From 731cfa02e7fd56d791d32382f218bae74a5335cc Mon Sep 17 00:00:00 2001 From: MSalopek Date: Wed, 13 Mar 2024 14:47:52 +0100 Subject: [PATCH 01/35] test: update confusing e2e democracy setup (#1701) (#1704) * tests: update confusing e2e democracy setup * test: refactor after review --- tests/e2e/main.go | 4 +- tests/e2e/steps.go | 13 +- tests/e2e/steps_democracy.go | 13 +- tests/e2e/steps_reward_denom.go | 308 ------------------------------- tests/e2e/trace_handlers_test.go | 8 +- 5 files changed, 22 insertions(+), 324 deletions(-) delete mode 100644 tests/e2e/steps_reward_denom.go diff --git a/tests/e2e/main.go b/tests/e2e/main.go index 8245b601b6..a14610def5 100644 --- a/tests/e2e/main.go +++ b/tests/e2e/main.go @@ -110,13 +110,13 @@ var stepChoices = map[string]StepChoice{ }, "democracy-reward": { name: "democracy-reward", - steps: democracyRewardsSteps, + steps: democracyRegisteredDenomSteps, description: "democracy tests allowing rewards", testConfig: DemocracyRewardTestCfg, }, "democracy": { name: "democracy", - steps: democracySteps, + steps: democracyUnregisteredDenomSteps, description: "democracy tests", testConfig: DemocracyTestCfg, }, diff --git a/tests/e2e/steps.go b/tests/e2e/steps.go index 6c85d925c9..4a6f40333e 100644 --- a/tests/e2e/steps.go +++ b/tests/e2e/steps.go @@ -73,20 +73,25 @@ var slashThrottleSteps = concatSteps( stepsStopChain("consu", 2), ) -var democracyRewardsSteps = concatSteps( +// these tests start with transfer SendEnabled set to false +// one of the steps will set SendEnabled to true +var democracyUnregisteredDenomSteps = concatSteps( // democracySteps requires a transfer channel stepsStartChains([]string{"democ"}, true), // delegation needs to happen so the first VSC packet can be delivered stepsDelegate("democ"), - stepsDemocracy("democ"), + // the denom is not registered on the provider chain so it will not be distributed as rewards + stepsDemocracy("democ", false), ) -var democracySteps = concatSteps( +// these tests start with transfer SendEnabled set to true +var democracyRegisteredDenomSteps = concatSteps( // democracySteps requires a transfer channel stepsStartChains([]string{"democ"}, true), // delegation needs to happen so the first VSC packet can be delivered stepsDelegate("democ"), - stepsRewardDenomConsumer("democ"), + // the denom is registered on the provider chain so it will be distributed as rewards + stepsDemocracy("democ", true), ) var multipleConsumers = concatSteps( diff --git a/tests/e2e/steps_democracy.go b/tests/e2e/steps_democracy.go index 506b33453c..30288e7ba9 100644 --- a/tests/e2e/steps_democracy.go +++ b/tests/e2e/steps_democracy.go @@ -2,7 +2,7 @@ package main const consumerRewardDenom = "ibc/3C3D7B3BE4ECC85A0E5B52A3AEC3B7DFC2AA9CA47C37821E57020D6807043BE9" -func stepsDemocracy(consumerName string) []Step { +func stepsDemocracy(consumerName string, expectRegisteredRewardDistribution bool) []Step { return []Step{ { Action: RegisterRepresentativeAction{ @@ -62,7 +62,7 @@ func stepsDemocracy(consumerName string) []Step { }, }, { - // whitelisted legacy proposal can only handle ibctransfer.SendEnabled/ReceiveEnabled + // this proposal will allow ibc transfer by setting SendEnabled to true Action: SubmitParamChangeLegacyProposalAction{ Chain: ChainID(consumerName), From: ValidatorID("alice"), @@ -181,12 +181,13 @@ func stepsDemocracy(consumerName string) []Step { }, State: State{ ChainID("provi"): ChainState{ - // Check that tokens are minted and sent to provider chain and distributed to validators and their delegators on provider chain + // Check that ARE NOT minted and sent to provider chain and distributed to validators and their delegators on provider chain + // the tokens are not sent because the test configuration does not allow sending tokens Rewards: &Rewards{ IsRewarded: map[ValidatorID]bool{ - ValidatorID("alice"): true, - ValidatorID("bob"): true, - ValidatorID("carol"): true, + ValidatorID("alice"): expectRegisteredRewardDistribution, + ValidatorID("bob"): expectRegisteredRewardDistribution, + ValidatorID("carol"): expectRegisteredRewardDistribution, }, IsIncrementalReward: false, IsNativeDenom: false, diff --git a/tests/e2e/steps_reward_denom.go b/tests/e2e/steps_reward_denom.go deleted file mode 100644 index 657508cd1b..0000000000 --- a/tests/e2e/steps_reward_denom.go +++ /dev/null @@ -1,308 +0,0 @@ -package main - -func stepsRewardDenomConsumer(consumerName string) []Step { - return []Step{ - { - Action: RegisterRepresentativeAction{ - Chain: ChainID(consumerName), - Representatives: []ValidatorID{ValidatorID("alice"), ValidatorID("bob")}, - Stakes: []uint{100000000, 40000000}, - }, - State: State{ - ChainID(consumerName): ChainState{ - StakedTokens: &map[ValidatorID]uint{ - ValidatorID("alice"): 100000000, - ValidatorID("bob"): 40000000, - }, - Rewards: &Rewards{ - IsRewarded: map[ValidatorID]bool{ - ValidatorID("alice"): true, - ValidatorID("bob"): true, - ValidatorID("carol"): false, - }, - IsIncrementalReward: true, - IsNativeDenom: true, - }, - }, - }, - }, - { - Action: DelegateTokensAction{ - Chain: ChainID(consumerName), - From: ValidatorID("carol"), - To: ValidatorID("alice"), - Amount: 500000, - }, - State: State{ - ChainID(consumerName): ChainState{ - // Check that delegators on gov-consumer chain can change representative powers - StakedTokens: &map[ValidatorID]uint{ - ValidatorID("alice"): 100500000, - ValidatorID("bob"): 40000000, - }, - // Check that delegating on gov-consumer does not change validator powers - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 511, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - // Check that tokens are minted and distributed to representatives and their delegators - Rewards: &Rewards{ - IsRewarded: map[ValidatorID]bool{ - ValidatorID("alice"): true, - ValidatorID("bob"): true, - ValidatorID("carol"): true, - }, - IsIncrementalReward: true, - IsNativeDenom: true, - }, - }, - }, - }, - { - // whitelisted legacy proposal can only handle ibctransfer.SendEnabled/ReceiveEnabled - Action: SubmitParamChangeLegacyProposalAction{ - Chain: ChainID(consumerName), - From: ValidatorID("alice"), - Deposit: 10000001, - Subspace: "transfer", - Key: "SendEnabled", - Value: true, - }, - State: State{ - ChainID(consumerName): ChainState{ - ValBalances: &map[ValidatorID]uint{ - ValidatorID("alice"): 9889999998, - ValidatorID("bob"): 9960000001, - }, - // Check that the "SendEnabled" transfer parameter is set to false - Params: &([]Param{{Subspace: "transfer", Key: "SendEnabled", Value: "false"}}), - Proposals: &map[uint]Proposal{ - 1: ParamsProposal{ - Deposit: 10000001, - Status: "PROPOSAL_STATUS_VOTING_PERIOD", - Subspace: "transfer", - Key: "SendEnabled", - Value: "true", - }, - }, - }, - }, - }, - { - // Have accounts vote on something on the gov-consumer chain - Action: VoteGovProposalAction{ - Chain: ChainID(consumerName), - From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob")}, - Vote: []string{"yes", "no"}, - PropNumber: 1, - }, - State: State{ - ChainID(consumerName): ChainState{ - // Check that alice gets the prop deposit refunded - ValBalances: &map[ValidatorID]uint{ - ValidatorID("alice"): 9899999999, - ValidatorID("bob"): 9960000001, - }, - // Check that the prop passed - Proposals: &map[uint]Proposal{ - 1: ParamsProposal{ - Deposit: 10000001, - Status: "PROPOSAL_STATUS_PASSED", - Subspace: "transfer", - Key: "SendEnabled", - Value: "true", - }, - }, - // Check that the parameter is changed on gov-consumer chain - Params: &([]Param{{Subspace: "transfer", Key: "SendEnabled", Value: "true"}}), - }, - }, - }, - { - Action: RelayRewardPacketsToProviderAction{ - ConsumerChain: ChainID(consumerName), - ProviderChain: ChainID("provi"), - Port: "transfer", - Channel: 1, - }, - State: State{ - ChainID("provi"): ChainState{ - // Check that tokens are not distributed before the denom has been registered - Rewards: &Rewards{ - IsRewarded: map[ValidatorID]bool{ - ValidatorID("alice"): false, - ValidatorID("bob"): false, - ValidatorID("carol"): false, - }, - IsIncrementalReward: false, - IsNativeDenom: false, - }, - // Check that the denom is not registered on provider chain - RegisteredConsumerRewardDenoms: &[]string{}, - }, - }, - }, - { - Action: SubmitChangeRewardDenomsProposalAction{ - Denom: "ibc/3C3D7B3BE4ECC85A0E5B52A3AEC3B7DFC2AA9CA47C37821E57020D6807043BE9", - Deposit: 10000001, - From: ValidatorID("bob"), - }, - State: State{ - ChainID("provi"): ChainState{ - // Denom not yet registered, gov prop needs to pass first - RegisteredConsumerRewardDenoms: &[]string{}, - }, - }, - }, - { - Action: VoteGovProposalAction{ - Chain: ChainID("provi"), - From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob"), ValidatorID("carol")}, - Vote: []string{"yes", "yes", "yes"}, - PropNumber: 2, - }, - State: State{ - ChainID("provi"): ChainState{ - // Check that the denom is registered on provider chain - RegisteredConsumerRewardDenoms: &[]string{"ibc/3C3D7B3BE4ECC85A0E5B52A3AEC3B7DFC2AA9CA47C37821E57020D6807043BE9"}, - }, - }, - }, - { - Action: RelayRewardPacketsToProviderAction{ - ConsumerChain: ChainID(consumerName), - ProviderChain: ChainID("provi"), - Port: "transfer", - Channel: 1, - }, - State: State{ - ChainID("provi"): ChainState{ - // Check that tokens are not minted and sent to provider chain and distributed to validators and their delegators on provider chain - Rewards: &Rewards{ - IsRewarded: map[ValidatorID]bool{ - ValidatorID("alice"): false, - ValidatorID("bob"): false, - ValidatorID("carol"): false, - }, - IsIncrementalReward: false, - IsNativeDenom: false, - }, - }, - }, - }, - { - Action: DowntimeSlashAction{ - Chain: ChainID(consumerName), - Validator: ValidatorID("bob"), - }, - State: State{ - // validator should be slashed on consumer, powers not affected on either chain yet - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 511, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 511, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - }, - }, - }, - { - Action: RelayPacketsAction{ - ChainA: ChainID("provi"), - ChainB: ChainID(consumerName), - Port: "provider", - Channel: 0, - }, - State: State{ - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 511, - // Downtime jailing and corresponding voting power change are processed by provider - ValidatorID("bob"): 0, - ValidatorID("carol"): 500, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 511, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - }, - }, - }, - // A block is incremented each Action, hence why VSC is committed on provider, - // and can now be relayed as packet to consumer - { - Action: RelayPacketsAction{ - ChainA: ChainID("provi"), - ChainB: ChainID(consumerName), - Port: "provider", - Channel: 0, - }, - State: State{ - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 511, - // VSC now seen on consumer - ValidatorID("bob"): 0, - ValidatorID("carol"): 500, - }, - }, - }, - }, - { - Action: UnjailValidatorAction{ - Provider: ChainID("provi"), - Validator: ValidatorID("bob"), - }, - State: State{ - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 511, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 511, - ValidatorID("bob"): 0, - ValidatorID("carol"): 500, - }, - }, - }, - }, - { - Action: RelayPacketsAction{ - ChainA: ChainID("provi"), - ChainB: ChainID(consumerName), - Port: "provider", - Channel: 0, - }, - State: State{ - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 511, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - // Check that slashing on the gov-consumer chain does not result in slashing for the representatives or their delegators - StakedTokens: &map[ValidatorID]uint{ - ValidatorID("alice"): 100500000, - ValidatorID("bob"): 40000000, - }, - }, - }, - }, - } -} diff --git a/tests/e2e/trace_handlers_test.go b/tests/e2e/trace_handlers_test.go index 4352c2a1b3..9b83d1c774 100644 --- a/tests/e2e/trace_handlers_test.go +++ b/tests/e2e/trace_handlers_test.go @@ -45,11 +45,11 @@ func TestWriterThenParser(t *testing.T) { "proposalInState": {proposalInStateSteps}, "start_provider_chain": {stepStartProviderChain()}, "happyPath": {happyPathSteps}, - "democracy": {democracySteps}, + "democracy": {democracyUnregisteredDenomSteps}, "slashThrottle": {slashThrottleSteps}, "multipleConsumers": {multipleConsumers}, "shorthappy": {shortHappyPathSteps}, - "democracyRewardsSteps": {democracyRewardsSteps}, + "democracyRewardsSteps": {democracyRegisteredDenomSteps}, "changeover": {changeoverSteps}, } @@ -76,11 +76,11 @@ func TestWriteExamples(t *testing.T) { trace []Step }{ "happyPath": {happyPathSteps}, - "democracy": {democracySteps}, + "democracy": {democracyUnregisteredDenomSteps}, "slashThrottle": {slashThrottleSteps}, "multipleConsumers": {multipleConsumers}, "shorthappy": {shortHappyPathSteps}, - "democracyRewardsSteps": {democracyRewardsSteps}, + "democracyRewardsSteps": {democracyRegisteredDenomSteps}, "changeover": {changeoverSteps}, "consumer-misbehaviour": {consumerMisbehaviourSteps}, "consumer-double-sign": {consumerDoubleSignSteps}, From 67f5fa9c736945708d638b4ff369989a06e707bf Mon Sep 17 00:00:00 2001 From: MSalopek Date: Thu, 14 Mar 2024 17:05:23 +0100 Subject: [PATCH 02/35] feat!: use cosmos-sdk v50 and IBC v8.1 (#1698) * proto: update proto files and deps * proto: run buf mode update * deps!: use cosmos-sdk/v0.50 and ibc-go/v8 * s&r: replace ibc-go imports * s&r: replace cosmos-sdk imports * cosmos-sdk: rm legacy upgrade prop handlers * cosmos-sdk: get cosmossdk.io modules * docs: add upgrade reference doc WIP * s&r: replace sdk math with math and legacydec * s&r: replace capability * deps: update modfile after merging main * interface changes: update expected_keepers.go * interface changes: update provider modules, legacy prop handlers * provider: update types directory * provider: update consumer equivocation * provider: update keeper.go * provider: update distribution.go * provider: update hooks (staking, governance) * provider: update params, add legacy params accessors * provider: update add/remove proposal handling; mv legacy to separate file * provider: add missing Tx types, update Msg server * provider: throttle, throttle_legacy, gov proposal handler (router) * provider: minor update to handler_test * provider: add cons version v4 migration - possibly broken * provider: client handling - legacy_proposals * provider: update key assignment * provider, testutil: partially fix tests * consumer: migrate consumer module * democracy: update module overrides * testutil: upgrade simibc files * testutil: upgrade ibc_testing setups * testutil: upgrade ibc_testing setups * testutil: update consumerkeeper mocks * tests: update provider consumer_equivocation tests * tests: fix most provider UTs * provider: fix key assignment and tests * provider: fix throttle and relay tests * provider: update app * provider: update app wiring and cmd * consumer: update consumer app * democracy: update democracy app * sovereign: update sovereign app * integration test: update integration tests * mbt: update mbt tests setup * sovereign: add readme file * tests: update test setup; refactor key_assignment addr parser * e2e: make initial e2e migration to v50 * provider: update wiring to enable e2e * provider: allow nil govkeeper in tests * provider: fix app wiring * tests: update unittest helpers * e2e tests: fix errors in provider relay * sovereign: fix root.go * consumer: add prefix registration to consumer main.go * democracy: update democracy app and root init * apps: refactor apps wiring * democ: refactor root.go wiring * democ: correctly override staking InitGenesis * democracy: update democracy distribution AllocateTokens * democracy: update staking and gov * democracy: update gov proposal whitelist (add legacy test props) * democracy: update staking interface overrides * e2e: refactor democracy tests and related actions * docs: v50 update reference * conclude merging release/v5 * e2e democ: fix democracy consumer IBC transfer tests; update whitelists * proto: update evidence messages submitters * tests: update deprecated tests * review: address comments * chore: use interchain-security/v5 module name * e2e: update e2e; use v5 --- Dockerfile | 2 +- Makefile | 2 +- app/consumer-democracy/abci.go | 84 + .../ante/forbidden_proposals_ante_test.go | 46 +- app/consumer-democracy/ante_handler.go | 10 +- app/consumer-democracy/app.go | 390 +-- app/consumer-democracy/export.go | 8 +- .../proposals_whitelisting.go | 26 +- .../proposals_whitelisting_test.go | 26 - app/consumer/abci.go | 84 + .../ante/disabled_modules_ante_test.go | 8 +- app/consumer/ante/msg_filter_ante_test.go | 6 +- app/consumer/ante_handler.go | 8 +- app/consumer/app.go | 308 +- app/consumer/export.go | 8 +- app/consumer/genesis.go | 4 +- app/consumer/genesis_test.go | 6 +- app/encoding/encoding.go | 16 +- app/provider/abci.go | 84 + app/provider/ante_handler.go | 4 +- app/provider/app.go | 493 +-- app/provider/export.go | 72 +- app/sovereign/Readme.md | 3 + app/sovereign/abci.go | 84 + app/sovereign/ante_handler.go | 4 +- app/sovereign/app.go | 226 +- app/sovereign/export.go | 75 +- cmd/interchain-security-cd/cmd/root.go | 67 +- cmd/interchain-security-cd/main.go | 21 +- cmd/interchain-security-cdd/cmd/root.go | 91 +- cmd/interchain-security-cdd/main.go | 21 +- cmd/interchain-security-pd/cmd/root.go | 232 +- cmd/interchain-security-pd/main.go | 17 +- cmd/interchain-security-sd/cmd/root.go | 86 +- cmd/interchain-security-sd/main.go | 18 +- docs/build_deploy.sh | 12 + docs/upgrades_reference/app_provider.md | 104 + docs/upgrades_reference/consumer.md | 17 + docs/upgrades_reference/democracy.md | 77 + docs/upgrades_reference/imports_only.md | 56 + docs/upgrades_reference/logic_changes.md | 306 ++ go.mod | 135 +- go.sum | 338 ++- proto/buf.lock | 12 +- proto/buf.yaml | 9 +- .../ccv/consumer/v1/consumer.proto | 2 +- .../ccv/consumer/v1/genesis.proto | 2 +- .../ccv/consumer/v1/query.proto | 2 +- .../ccv/provider/v1/genesis.proto | 2 +- .../ccv/provider/v1/provider.proto | 14 +- .../ccv/provider/v1/query.proto | 2 +- .../ccv/provider/v1/tx.proto | 159 +- .../ccv/v1/shared_consumer.proto | 2 +- proto/interchain_security/ccv/v1/wire.proto | 2 +- scripts/protocgen.sh | 2 +- tests/e2e/action_rapid_test.go | 15 +- tests/e2e/actions.go | 155 +- tests/e2e/config.go | 5 + tests/e2e/json_marshal_test.go | 14 +- tests/e2e/json_utils.go | 8 +- tests/e2e/main.go | 4 +- tests/e2e/state.go | 140 +- tests/e2e/state_rapid_test.go | 45 +- tests/e2e/steps_compatibility.go | 7 +- tests/e2e/steps_consumer_misbehaviour.go | 7 +- tests/e2e/steps_democracy.go | 53 +- tests/e2e/steps_sovereign_changeover.go | 15 +- tests/e2e/steps_start_chains.go | 9 +- tests/e2e/steps_stop_chain.go | 15 +- tests/e2e/test_driver.go | 4 +- ...StateMarshalling-20240314151749-32478.fail | 10 + ...eadAndWriteTrace-20240314151749-32478.fail | 18 + tests/e2e/testnet-scripts/start-chain.sh | 4 +- tests/e2e/testnet-scripts/start-changeover.sh | 2 +- tests/e2e/testnet-scripts/start-sovereign.sh | 2 +- tests/e2e/trace_handlers_test.go | 22 +- .../e2e/tracehandler_testdata/changeover.json | 42 +- .../consumer-double-sign.json | 30 +- .../consumer-misbehaviour.json | 28 +- .../e2e/tracehandler_testdata/democracy.json | 110 +- .../democracyRewardsSteps.json | 110 +- .../e2e/tracehandler_testdata/happyPath.json | 126 +- .../multipleConsumers.json | 202 +- .../e2e/tracehandler_testdata/shorthappy.json | 92 +- .../tracehandler_testdata/slashThrottle.json | 64 +- tests/integration/changeover.go | 4 +- tests/integration/common.go | 86 +- tests/integration/democracy.go | 104 +- tests/integration/distribution.go | 50 +- tests/integration/double_vote.go | 54 +- tests/integration/expired_client.go | 26 +- tests/integration/instance_test.go | 10 +- tests/integration/key_assignment.go | 12 +- tests/integration/misbehaviour.go | 18 +- tests/integration/normal_operations.go | 4 +- tests/integration/setup.go | 75 +- tests/integration/slashing.go | 81 +- tests/integration/soft_opt_out.go | 75 +- tests/integration/stop_consumer.go | 15 +- tests/integration/throttle.go | 124 +- tests/integration/throttle_retry.go | 30 +- tests/integration/unbonding.go | 46 +- tests/integration/valset_update.go | 8 +- tests/mbt/driver/common.go | 3 +- tests/mbt/driver/core.go | 60 +- tests/mbt/driver/mbt_test.go | 18 +- tests/mbt/driver/setup.go | 67 +- testutil/crypto/crypto.go | 12 +- testutil/crypto/evidence.go | 33 +- testutil/ibc_testing/generic_setup.go | 45 +- testutil/ibc_testing/specific_setup.go | 24 +- testutil/integration/debug_test.go | 10 +- testutil/integration/interfaces.go | 112 +- testutil/keeper/expectations.go | 38 +- testutil/keeper/mocks.go | 367 ++- testutil/keeper/unit_test_helpers.go | 44 +- testutil/simibc/chain_util.go | 73 +- testutil/simibc/ordered_outbox.go | 2 +- testutil/simibc/relay_util.go | 43 +- testutil/simibc/relayed_path.go | 6 +- x/ccv/consumer/client/cli/query.go | 2 +- x/ccv/consumer/ibc_module.go | 18 +- x/ccv/consumer/ibc_module_test.go | 18 +- x/ccv/consumer/keeper/changeover.go | 7 +- x/ccv/consumer/keeper/changeover_test.go | 6 +- x/ccv/consumer/keeper/distribution.go | 15 +- x/ccv/consumer/keeper/distribution_test.go | 11 +- x/ccv/consumer/keeper/genesis.go | 4 +- x/ccv/consumer/keeper/genesis_test.go | 16 +- x/ccv/consumer/keeper/grpc_query.go | 4 +- x/ccv/consumer/keeper/hooks.go | 6 +- x/ccv/consumer/keeper/keeper.go | 111 +- x/ccv/consumer/keeper/keeper_test.go | 15 +- x/ccv/consumer/keeper/legacy_params.go | 118 + x/ccv/consumer/keeper/migrations.go | 8 +- x/ccv/consumer/keeper/params.go | 115 +- x/ccv/consumer/keeper/params_test.go | 4 +- x/ccv/consumer/keeper/provider_info.go | 6 +- x/ccv/consumer/keeper/relay.go | 11 +- x/ccv/consumer/keeper/relay_test.go | 18 +- x/ccv/consumer/keeper/soft_opt_out.go | 30 +- x/ccv/consumer/keeper/soft_opt_out_test.go | 6 +- x/ccv/consumer/keeper/throttle_retry.go | 2 +- x/ccv/consumer/keeper/throttle_retry_test.go | 6 +- x/ccv/consumer/keeper/validators.go | 95 +- x/ccv/consumer/keeper/validators_test.go | 44 +- x/ccv/consumer/migrations/v2/migration.go | 6 +- .../consumer/migrations/v2/migration_test.go | 10 +- x/ccv/consumer/migrations/v3/migration.go | 22 + x/ccv/consumer/module.go | 47 +- x/ccv/consumer/types/consumer.pb.go | 50 +- x/ccv/consumer/types/genesis.go | 4 +- x/ccv/consumer/types/genesis.pb.go | 60 +- x/ccv/consumer/types/genesis_test.go | 12 +- x/ccv/consumer/types/keys.go | 10 +- x/ccv/consumer/types/keys_test.go | 1 + x/ccv/consumer/types/params_test.go | 2 +- x/ccv/consumer/types/query.pb.go | 6 +- x/ccv/democracy/distribution/module.go | 59 +- x/ccv/democracy/governance/module.go | 30 +- x/ccv/democracy/staking/module.go | 16 +- x/ccv/provider/client/cli/query.go | 2 +- x/ccv/provider/client/cli/tx.go | 7 +- .../client/legacy_proposal_handler.go | 215 ++ x/ccv/provider/client/legacy_proposals.go | 156 + x/ccv/provider/client/proposal_handler.go | 442 --- x/ccv/provider/handler.go | 13 +- x/ccv/provider/handler_test.go | 28 +- x/ccv/provider/ibc_module.go | 16 +- x/ccv/provider/ibc_module_test.go | 22 +- .../provider/keeper/consumer_equivocation.go | 70 +- .../keeper/consumer_equivocation_test.go | 106 +- x/ccv/provider/keeper/distribution.go | 6 +- x/ccv/provider/keeper/genesis.go | 4 +- x/ccv/provider/keeper/genesis_test.go | 19 +- x/ccv/provider/keeper/grpc_query.go | 12 +- x/ccv/provider/keeper/grpc_query_test.go | 8 +- x/ccv/provider/keeper/hooks.go | 61 +- x/ccv/provider/keeper/hooks_test.go | 290 +- x/ccv/provider/keeper/keeper.go | 173 +- x/ccv/provider/keeper/keeper_test.go | 10 +- x/ccv/provider/keeper/key_assignment.go | 33 +- x/ccv/provider/keeper/key_assignment_test.go | 68 +- x/ccv/provider/keeper/legacy_params.go | 86 + x/ccv/provider/keeper/legacy_proposal.go | 85 + x/ccv/provider/keeper/legacy_proposal_test.go | 256 ++ x/ccv/provider/keeper/msg_server.go | 69 +- x/ccv/provider/keeper/params.go | 72 +- x/ccv/provider/keeper/params_test.go | 13 +- x/ccv/provider/keeper/proposal.go | 145 +- x/ccv/provider/keeper/proposal_test.go | 253 +- x/ccv/provider/keeper/relay.go | 47 +- x/ccv/provider/keeper/relay_test.go | 35 +- x/ccv/provider/keeper/throttle.go | 36 +- x/ccv/provider/keeper/throttle_legacy.go | 9 +- x/ccv/provider/keeper/throttle_test.go | 154 +- x/ccv/provider/migrations/migrator.go | 9 +- .../provider/migrations/v3/migration_test.go | 2 +- x/ccv/provider/migrations/v3/migrations.go | 2 +- x/ccv/provider/migrations/v4/migrations.go | 22 + x/ccv/provider/module.go | 76 +- x/ccv/provider/module_test.go | 24 +- x/ccv/provider/proposal_handler.go | 10 +- x/ccv/provider/proposal_handler_test.go | 11 +- x/ccv/provider/types/codec.go | 11 +- x/ccv/provider/types/consumer.go | 2 +- x/ccv/provider/types/errors.go | 4 + x/ccv/provider/types/genesis.go | 4 +- x/ccv/provider/types/genesis.pb.go | 70 +- x/ccv/provider/types/genesis_test.go | 39 +- x/ccv/provider/types/key_assignment.go | 2 +- x/ccv/provider/types/keys.go | 10 +- x/ccv/provider/types/keys_test.go | 5 +- .../types/{proposal.go => legacy_proposal.go} | 11 +- ...oposal_test.go => legacy_proposal_test.go} | 6 +- x/ccv/provider/types/msg.go | 139 +- x/ccv/provider/types/params.go | 14 +- x/ccv/provider/types/params_test.go | 33 +- x/ccv/provider/types/provider.pb.go | 234 +- x/ccv/provider/types/query.pb.go | 126 +- x/ccv/provider/types/tx.pb.go | 2642 +++++++++++++++-- x/ccv/types/expected_keepers.go | 104 +- x/ccv/types/genesis.go | 2 +- x/ccv/types/params.go | 7 +- x/ccv/types/shared_consumer.pb.go | 100 +- x/ccv/types/shared_params.go | 9 +- x/ccv/types/utils.go | 6 +- x/ccv/types/utils_test.go | 4 +- x/ccv/types/wire.pb.go | 108 +- x/ccv/types/wire_test.go | 4 +- 230 files changed, 9895 insertions(+), 5041 deletions(-) create mode 100644 app/consumer-democracy/abci.go delete mode 100644 app/consumer-democracy/proposals_whitelisting_test.go create mode 100644 app/consumer/abci.go create mode 100644 app/provider/abci.go create mode 100644 app/sovereign/Readme.md create mode 100644 app/sovereign/abci.go create mode 100755 docs/build_deploy.sh create mode 100644 docs/upgrades_reference/app_provider.md create mode 100644 docs/upgrades_reference/consumer.md create mode 100644 docs/upgrades_reference/democracy.md create mode 100644 docs/upgrades_reference/imports_only.md create mode 100644 docs/upgrades_reference/logic_changes.md create mode 100644 tests/e2e/testdata/rapid/TestChainStateMarshalling/TestChainStateMarshalling-20240314151749-32478.fail create mode 100644 tests/e2e/testdata/rapid/TestReadAndWriteTrace/TestReadAndWriteTrace-20240314151749-32478.fail create mode 100644 x/ccv/consumer/keeper/legacy_params.go create mode 100644 x/ccv/consumer/migrations/v3/migration.go create mode 100644 x/ccv/provider/client/legacy_proposal_handler.go create mode 100644 x/ccv/provider/client/legacy_proposals.go delete mode 100644 x/ccv/provider/client/proposal_handler.go create mode 100644 x/ccv/provider/keeper/legacy_params.go create mode 100644 x/ccv/provider/keeper/legacy_proposal.go create mode 100644 x/ccv/provider/keeper/legacy_proposal_test.go create mode 100644 x/ccv/provider/migrations/v4/migrations.go rename x/ccv/provider/types/{proposal.go => legacy_proposal.go} (97%) rename x/ccv/provider/types/{proposal_test.go => legacy_proposal_test.go} (97%) diff --git a/Dockerfile b/Dockerfile index 830b101b2f..c32b2b5787 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,7 +32,7 @@ RUN make install FROM --platform=linux/amd64 ghcr.io/informalsystems/hermes:v1.8.0 AS hermes-builder # Get CometMock -FROM ghcr.io/informalsystems/cometmock:v0.37.x as cometmock-builder +FROM ghcr.io/informalsystems/cometmock:v0.38.x as cometmock-builder # Get GoRelayer FROM ghcr.io/informalsystems/relayer-no-gas-sim:v2.3.0-rc4-no-gas-sim AS gorelayer-builder diff --git a/Makefile b/Makefile index 71866d8b24..8a0d77ea03 100644 --- a/Makefile +++ b/Makefile @@ -186,7 +186,7 @@ $(BUILDDIR)/: DOCKER := $(shell which docker) HTTPS_GIT := https://github.com/cosmos/interchain-security.git -containerProtoVer=0.13.0 +containerProtoVer=0.14.0 containerProtoImage=ghcr.io/cosmos/proto-builder:$(containerProtoVer) protoImage=$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace $(containerProtoImage) diff --git a/app/consumer-democracy/abci.go b/app/consumer-democracy/abci.go new file mode 100644 index 0000000000..94b34cc3bb --- /dev/null +++ b/app/consumer-democracy/abci.go @@ -0,0 +1,84 @@ +package app + +import ( + "bytes" + "crypto/rand" + "encoding/json" + "fmt" + + abci "github.com/cometbft/cometbft/abci/types" + + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type ( + // VoteExtensionHandler defines a dummy vote extension handler for SimApp. + // + // NOTE: This implementation is solely used for testing purposes. DO NOT use + // in a production application! + VoteExtensionHandler struct{} + + // VoteExtension defines the structure used to create a dummy vote extension. + VoteExtension struct { + Hash []byte + Height int64 + Data []byte + } +) + +func NewVoteExtensionHandler() *VoteExtensionHandler { + return &VoteExtensionHandler{} +} + +func (h *VoteExtensionHandler) SetHandlers(bApp *baseapp.BaseApp) { + bApp.SetExtendVoteHandler(h.ExtendVote()) + bApp.SetVerifyVoteExtensionHandler(h.VerifyVoteExtension()) +} + +func (h *VoteExtensionHandler) ExtendVote() sdk.ExtendVoteHandler { + return func(_ sdk.Context, req *abci.RequestExtendVote) (*abci.ResponseExtendVote, error) { + buf := make([]byte, 1024) + + _, err := rand.Read(buf) + if err != nil { + return nil, fmt.Errorf("failed to generate random vote extension data: %w", err) + } + + ve := VoteExtension{ + Hash: req.Hash, + Height: req.Height, + Data: buf, + } + + bz, err := json.Marshal(ve) + if err != nil { + return nil, fmt.Errorf("failed to encode vote extension: %w", err) + } + + return &abci.ResponseExtendVote{VoteExtension: bz}, nil + } +} + +func (h *VoteExtensionHandler) VerifyVoteExtension() sdk.VerifyVoteExtensionHandler { + return func(ctx sdk.Context, req *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) { + var ve VoteExtension + + if err := json.Unmarshal(req.VoteExtension, &ve); err != nil { + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + } + + switch { + case req.Height != ve.Height: + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + + case !bytes.Equal(req.Hash, ve.Hash): + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + + case len(ve.Data) != 1024: + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + } + + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_ACCEPT}, nil + } +} diff --git a/app/consumer-democracy/ante/forbidden_proposals_ante_test.go b/app/consumer-democracy/ante/forbidden_proposals_ante_test.go index 8fd7fe3824..e1e1fda79b 100644 --- a/app/consumer-democracy/ante/forbidden_proposals_ante_test.go +++ b/app/consumer-democracy/ante/forbidden_proposals_ante_test.go @@ -3,19 +3,18 @@ package ante_test import ( "testing" - ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" "github.com/cosmos/cosmos-sdk/x/params/types/proposal" - app "github.com/cosmos/interchain-security/v4/app/consumer-democracy" - "github.com/cosmos/interchain-security/v4/app/consumer-democracy/ante" + app "github.com/cosmos/interchain-security/v5/app/consumer-democracy" + "github.com/cosmos/interchain-security/v5/app/consumer-democracy/ante" ) // in SDKv47 parameter updates full params object is required @@ -98,8 +97,9 @@ func TestForbiddenProposalsDecorator(t *testing.T) { } } -// Only ibctransfertypes.SendEnabled/ReceiveEnabled support legacy proposals for changing params -// Note: see LegacyWhitelistedParams in proposals_whitelisting.go +// Legacy parameter proposals are not supported in cosmos-sdk v0.50 +// since modules parameters were moved to their respective modules +// this test is to ensure that legacy parameter proposals are not allowed func TestForbiddenLegacyProposalsDecorator(t *testing.T) { txCfg := app.MakeTestEncodingConfig().TxConfig @@ -109,17 +109,6 @@ func TestForbiddenLegacyProposalsDecorator(t *testing.T) { msgs []sdk.Msg expectErr bool }{ - { - name: "Allowed legacy param change -- only for ibctransfertypes.SendEnabled/ReceiveEnabled", - ctx: sdk.Context{}, - msgs: []sdk.Msg{ - newLegacyParamChangeProposalMsg([]proposal.ParamChange{ - // only subspace and key are relevant for testing - {Subspace: ibctransfertypes.ModuleName, Key: "SendEnabled", Value: "true"}, - }), - }, - expectErr: false, - }, { name: "Forbidden param change", ctx: sdk.Context{}, @@ -131,33 +120,16 @@ func TestForbiddenLegacyProposalsDecorator(t *testing.T) { expectErr: true, }, { - name: "Allowed and forbidden param changes in the same msg", + name: "Multiple forbidden param changes in the same msg", ctx: sdk.Context{}, msgs: []sdk.Msg{ newLegacyParamChangeProposalMsg([]proposal.ParamChange{ - // allowed {Subspace: ibctransfertypes.ModuleName, Key: "SendEnabled", Value: "true"}, - // disallowed {Subspace: authtypes.ModuleName, Key: "MaxMemoCharacters", Value: ""}, }), }, expectErr: true, }, - { - name: "Allowed and forbidden param changes in different msg", - ctx: sdk.Context{}, - msgs: []sdk.Msg{ - newLegacyParamChangeProposalMsg([]proposal.ParamChange{ - // disallowed - {Subspace: banktypes.ModuleName, Key: "SendEnabled", Value: ""}, - }), - newLegacyParamChangeProposalMsg([]proposal.ParamChange{ - // allowed - {Subspace: ibctransfertypes.ModuleName, Key: "SendEnabled", Value: "true"}, - }), - }, - expectErr: true, - }, } for _, tc := range testCases { @@ -187,11 +159,11 @@ func newLegacyParamChangeProposalMsg(changes []proposal.ParamChange) *govv1.MsgS if err != nil { return nil } - msg, _ := govv1.NewMsgSubmitProposal([]sdk.Msg{msgContent}, sdk.NewCoins(), sdk.AccAddress{}.String(), "", "", "") + msg, _ := govv1.NewMsgSubmitProposal([]sdk.Msg{msgContent}, sdk.NewCoins(), sdk.AccAddress{}.String(), "", "", "", false) return msg } func newParamChangeProposalMsg(msgs []sdk.Msg) *govv1.MsgSubmitProposal { - msg, _ := govv1.NewMsgSubmitProposal(msgs, sdk.NewCoins(), sdk.AccAddress{}.String(), "", "", "") + msg, _ := govv1.NewMsgSubmitProposal(msgs, sdk.NewCoins(), sdk.AccAddress{}.String(), "", "", "", false) return msg } diff --git a/app/consumer-democracy/ante_handler.go b/app/consumer-democracy/ante_handler.go index 7e652ebb0c..a8efdfffb3 100644 --- a/app/consumer-democracy/ante_handler.go +++ b/app/consumer-democracy/ante_handler.go @@ -1,8 +1,8 @@ package app import ( - ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante" - ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" + ibcante "github.com/cosmos/ibc-go/v8/modules/core/ante" + ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" errorsmod "cosmossdk.io/errors" @@ -10,9 +10,9 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/ante" - democracyante "github.com/cosmos/interchain-security/v4/app/consumer-democracy/ante" - consumerante "github.com/cosmos/interchain-security/v4/app/consumer/ante" - ibcconsumerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" + democracyante "github.com/cosmos/interchain-security/v5/app/consumer-democracy/ante" + consumerante "github.com/cosmos/interchain-security/v5/app/consumer/ante" + ibcconsumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" ) // HandlerOptions extend the SDK's AnteHandler options by requiring the IBC diff --git a/app/consumer-democracy/app.go b/app/consumer-democracy/app.go index e90d35760e..b7506eb0c7 100644 --- a/app/consumer-democracy/app.go +++ b/app/consumer-democracy/app.go @@ -1,33 +1,44 @@ package app import ( + "context" "fmt" "io" stdlog "log" "os" "path/filepath" - "github.com/cosmos/ibc-go/v7/modules/apps/transfer" - ibctransferkeeper "github.com/cosmos/ibc-go/v7/modules/apps/transfer/keeper" - ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - ibc "github.com/cosmos/ibc-go/v7/modules/core" - ibcconnectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" - porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" - ibchost "github.com/cosmos/ibc-go/v7/modules/core/exported" - ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctesting "github.com/cosmos/ibc-go/v7/testing" - ibctestingtypes "github.com/cosmos/ibc-go/v7/testing/types" + "github.com/cosmos/gogoproto/proto" + "github.com/cosmos/ibc-go/v8/modules/apps/transfer" + ibctransferkeeper "github.com/cosmos/ibc-go/v8/modules/apps/transfer/keeper" + ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + ibc "github.com/cosmos/ibc-go/v8/modules/core" + ibcconnectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" + ibchost "github.com/cosmos/ibc-go/v8/modules/core/exported" + ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" + ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v8/testing" + ibctestingtypes "github.com/cosmos/ibc-go/v8/testing/types" "github.com/spf13/cast" autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" - + "cosmossdk.io/client/v2/autocli" + "cosmossdk.io/core/appmodule" + + storetypes "cosmossdk.io/store/types" + "cosmossdk.io/x/evidence" + evidencekeeper "cosmossdk.io/x/evidence/keeper" + evidencetypes "cosmossdk.io/x/evidence/types" + "cosmossdk.io/x/feegrant" + feegrantkeeper "cosmossdk.io/x/feegrant/keeper" + feegrantmodule "cosmossdk.io/x/feegrant/module" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" - "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/runtime" @@ -37,14 +48,14 @@ import ( "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/std" - storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/types/msgservice" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/ante" + authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" - authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/auth/vesting" @@ -55,9 +66,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/bank" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/cosmos-sdk/x/capability" - capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" "github.com/cosmos/cosmos-sdk/x/consensus" consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" @@ -66,12 +74,6 @@ import ( crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - "github.com/cosmos/cosmos-sdk/x/evidence" - evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" - "github.com/cosmos/cosmos-sdk/x/feegrant" - feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper" - feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" gov "github.com/cosmos/cosmos-sdk/x/gov" @@ -79,6 +81,14 @@ import ( govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + "github.com/cosmos/ibc-go/modules/capability" + capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" + + // add mint + "cosmossdk.io/x/upgrade" + upgradekeeper "cosmossdk.io/x/upgrade/keeper" + upgradetypes "cosmossdk.io/x/upgrade/types" mint "github.com/cosmos/cosmos-sdk/x/mint" mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" @@ -92,33 +102,39 @@ import ( slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/cosmos/cosmos-sdk/x/upgrade" - upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" - upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - dbm "github.com/cometbft/cometbft-db" + "cosmossdk.io/log" abci "github.com/cometbft/cometbft/abci/types" tmjson "github.com/cometbft/cometbft/libs/json" - "github.com/cometbft/cometbft/libs/log" tmos "github.com/cometbft/cometbft/libs/os" - - appencoding "github.com/cosmos/interchain-security/v4/app/encoding" - testutil "github.com/cosmos/interchain-security/v4/testutil/integration" - consumer "github.com/cosmos/interchain-security/v4/x/ccv/consumer" - consumerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccvdistr "github.com/cosmos/interchain-security/v4/x/ccv/democracy/distribution" - ccvgov "github.com/cosmos/interchain-security/v4/x/ccv/democracy/governance" - ccvstaking "github.com/cosmos/interchain-security/v4/x/ccv/democracy/staking" + dbm "github.com/cosmos/cosmos-db" + + appencoding "github.com/cosmos/interchain-security/v5/app/encoding" + testutil "github.com/cosmos/interchain-security/v5/testutil/integration" + consumer "github.com/cosmos/interchain-security/v5/x/ccv/consumer" + consumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvdistr "github.com/cosmos/interchain-security/v5/x/ccv/democracy/distribution" + ccvgov "github.com/cosmos/interchain-security/v5/x/ccv/democracy/governance" + ccvstaking "github.com/cosmos/interchain-security/v5/x/ccv/democracy/staking" ) const ( - AppName = "interchain-security-cd" - upgradeName = "sovereign-changeover" // arbitrary name, define your own appropriately named upgrade - AccountAddressPrefix = "consumer" + AppName = "interchain-security-cd" + upgradeName = "sovereign-changeover" // arbitrary name, define your own appropriately named upgrade + + Bech32MainPrefix = "consumer" ) +func init() { + userHomeDir, err := os.UserHomeDir() + if err != nil { + stdlog.Println("Failed to get home dir %2", err) + } + + DefaultNodeHome = filepath.Join(userHomeDir, "."+AppName) +} + var ( // DefaultNodeHome default home directories for the application daemon DefaultNodeHome string @@ -138,8 +154,6 @@ var ( // TODO: eventually remove upgrade proposal handler and cancel proposal handler []govclient.ProposalHandler{ paramsclient.ProposalHandler, - upgradeclient.LegacyProposalHandler, - upgradeclient.LegacyCancelProposalHandler, }, ), params.AppModuleBasic{}, @@ -152,8 +166,7 @@ var ( evidence.AppModuleBasic{}, transfer.AppModuleBasic{}, vesting.AppModuleBasic{}, - tendermint.AppModuleBasic{}, - // router.AppModuleBasic{}, + ibctm.AppModuleBasic{}, consumer.AppModuleBasic{}, consensus.AppModuleBasic{}, ) @@ -226,15 +239,6 @@ type App struct { // nolint: golint configurator module.Configurator } -func init() { - userHomeDir, err := os.UserHomeDir() - if err != nil { - stdlog.Println("Failed to get home dir %2", err) - } - - DefaultNodeHome = filepath.Join(userHomeDir, "."+AppName) -} - // New returns a reference to an initialized App. func New( logger log.Logger, @@ -244,19 +248,26 @@ func New( appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp), ) *App { - encodingConfig := makeEncodingConfig() + encodingConfig := MakeTestEncodingConfig() appCodec := encodingConfig.Codec legacyAmino := encodingConfig.Amino interfaceRegistry := encodingConfig.InterfaceRegistry txConfig := encodingConfig.TxConfig + // ABCI++, v50 + voteExtOp := func(bApp *baseapp.BaseApp) { + voteExtHandler := NewVoteExtensionHandler() + voteExtHandler.SetHandlers(bApp) + } + baseAppOptions = append(baseAppOptions, voteExtOp) + bApp := baseapp.NewBaseApp(AppName, logger, db, encodingConfig.TxConfig.TxDecoder(), baseAppOptions...) bApp.SetCommitMultiStoreTracer(traceStore) bApp.SetVersion(version.Version) bApp.SetInterfaceRegistry(interfaceRegistry) - keys := sdk.NewKVStoreKeys( + keys := storetypes.NewKVStoreKeys( authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, crisistypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, @@ -264,8 +275,8 @@ func New( capabilitytypes.StoreKey, authzkeeper.StoreKey, consensusparamtypes.StoreKey, consumertypes.StoreKey, ) - tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) - memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) + tkeys := storetypes.NewTransientStoreKeys(paramstypes.TStoreKey) + memKeys := storetypes.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) app := &App{ BaseApp: bApp, @@ -286,8 +297,8 @@ func New( ) // set the BaseApp's parameter store - app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, keys[upgradetypes.StoreKey], authtypes.NewModuleAddress(govtypes.ModuleName).String()) - bApp.SetParamStore(&app.ConsensusParamsKeeper) + app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[consensusparamtypes.StoreKey]), authtypes.NewModuleAddress(govtypes.ModuleName).String(), runtime.EventService{}) + bApp.SetParamStore(&app.ConsensusParamsKeeper.ParamsStore) // add capability keeper and ScopeToModule for ibc module app.CapabilityKeeper = capabilitykeeper.NewKeeper( @@ -303,10 +314,11 @@ func New( // add keepers app.AccountKeeper = authkeeper.NewAccountKeeper( appCodec, - keys[authtypes.StoreKey], + runtime.NewKVStoreService(keys[authtypes.StoreKey]), authtypes.ProtoBaseAccount, maccPerms, - AccountAddressPrefix, + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), + sdk.GetConfig().GetBech32AccountAddrPrefix(), authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) @@ -319,34 +331,37 @@ func New( app.BankKeeper = bankkeeper.NewBaseKeeper( appCodec, - keys[banktypes.StoreKey], + runtime.NewKVStoreService(keys[banktypes.StoreKey]), app.AccountKeeper, bankBlockedAddrs, authtypes.NewModuleAddress(govtypes.ModuleName).String(), + logger, ) app.AuthzKeeper = authzkeeper.NewKeeper( - keys[authzkeeper.StoreKey], + runtime.NewKVStoreService(keys[authzkeeper.StoreKey]), appCodec, - app.BaseApp.MsgServiceRouter(), + app.MsgServiceRouter(), app.AccountKeeper, ) app.FeeGrantKeeper = feegrantkeeper.NewKeeper( appCodec, - keys[feegrant.StoreKey], + runtime.NewKVStoreService(keys[feegrant.StoreKey]), app.AccountKeeper, ) app.StakingKeeper = stakingkeeper.NewKeeper( appCodec, - keys[stakingtypes.StoreKey], + runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), ) app.MintKeeper = mintkeeper.NewKeeper( appCodec, - keys[minttypes.StoreKey], + runtime.NewKVStoreService(keys[minttypes.StoreKey]), app.StakingKeeper, app.AccountKeeper, app.BankKeeper, @@ -357,13 +372,13 @@ func New( app.SlashingKeeper = slashingkeeper.NewKeeper( appCodec, legacyAmino, - keys[slashingtypes.StoreKey], - &app.ConsumerKeeper, + runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), + app.StakingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) app.DistrKeeper = distrkeeper.NewKeeper( appCodec, - keys[distrtypes.StoreKey], + runtime.NewKVStoreService(keys[distrtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, app.StakingKeeper, @@ -374,13 +389,13 @@ func New( invCheckPeriod := cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)) app.CrisisKeeper = *crisiskeeper.NewKeeper( appCodec, - keys[crisistypes.StoreKey], + runtime.NewKVStoreService(keys[crisistypes.StoreKey]), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String(), + app.AccountKeeper.AddressCodec(), ) - // get skipUpgradeHeights from the app options skipUpgradeHeights := map[int64]bool{} for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) { @@ -390,7 +405,7 @@ func New( // set the governance module account as the authority for conducting upgrades app.UpgradeKeeper = *upgradekeeper.NewKeeper( skipUpgradeHeights, - keys[upgradetypes.StoreKey], + runtime.NewKVStoreService(keys[upgradetypes.StoreKey]), appCodec, homePath, app.BaseApp, @@ -407,14 +422,11 @@ func New( // register the proposal types ccvgovRouter := govv1beta1.NewRouter() ccvgovRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler). - AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). - // TODO: remove upgrade handler from gov once admin module or decision for only signaling proposal is made. - AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(&app.UpgradeKeeper)) - + AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)) govConfig := govtypes.DefaultConfig() govKeeper := govkeeper.NewKeeper( - appCodec, keys[govtypes.StoreKey], app.AccountKeeper, app.BankKeeper, - app.StakingKeeper, app.MsgServiceRouter(), govConfig, authtypes.NewModuleAddress(govtypes.ModuleName).String(), + appCodec, runtime.NewKVStoreService(keys[govtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, + app.StakingKeeper, app.DistrKeeper, app.MsgServiceRouter(), govConfig, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) govKeeper.SetLegacyRouter(ccvgovRouter) @@ -438,6 +450,7 @@ func New( app.ConsumerKeeper, app.UpgradeKeeper, scopedIBCKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) app.IBCKeeper = ibckeeper.NewKeeper( @@ -447,6 +460,7 @@ func New( &app.ConsumerKeeper, app.UpgradeKeeper, scopedIBCKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) // Create CCV consumer and modules @@ -456,7 +470,7 @@ func New( app.GetSubspace(consumertypes.ModuleName), scopedIBCConsumerKeeper, app.IBCKeeper.ChannelKeeper, - &app.IBCKeeper.PortKeeper, + app.IBCKeeper.PortKeeper, app.IBCKeeper.ConnectionKeeper, app.IBCKeeper.ClientKeeper, app.SlashingKeeper, @@ -465,6 +479,9 @@ func New( &app.TransferKeeper, app.IBCKeeper, authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), ) // Setting the standalone staking keeper is only needed for standalone to consumer changeover chains @@ -475,7 +492,7 @@ func New( app.SlashingKeeper = slashingkeeper.NewKeeper( appCodec, legacyAmino, - keys[slashingtypes.StoreKey], + runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), &app.ConsumerKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) @@ -490,10 +507,11 @@ func New( app.GetSubspace(ibctransfertypes.ModuleName), app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper, - &app.IBCKeeper.PortKeeper, + app.IBCKeeper.PortKeeper, app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) transferModule := transfer.NewAppModule(app.TransferKeeper) ibcmodule := transfer.NewIBCModule(app.TransferKeeper) @@ -507,9 +525,11 @@ func New( // create evidence keeper with router evidenceKeeper := evidencekeeper.NewKeeper( appCodec, - keys[evidencetypes.StoreKey], + runtime.NewKVStoreService(keys[evidencetypes.StoreKey]), &app.ConsumerKeeper, app.SlashingKeeper, + app.AccountKeeper.AddressCodec(), + runtime.ProvideCometInfoService(), ) app.EvidenceKeeper = *evidenceKeeper @@ -521,8 +541,8 @@ func New( app.MM = module.NewManager( genutil.NewAppModule( app.AccountKeeper, - app.ConsumerKeeper, - app.BaseApp.DeliverTx, + &app.ConsumerKeeper, + app, encodingConfig.TxConfig, ), auth.NewAppModule(appCodec, app.AccountKeeper, nil, app.GetSubspace(authtypes.ModuleName)), @@ -533,19 +553,30 @@ func New( feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), ccvgov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper, IsProposalWhitelisted, app.GetSubspace(govtypes.ModuleName), IsModuleWhiteList), mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)), - slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.ConsumerKeeper, app.GetSubspace(slashingtypes.ModuleName)), + slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.ConsumerKeeper, app.GetSubspace(slashingtypes.ModuleName), app.interfaceRegistry), ccvdistr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, *app.StakingKeeper, authtypes.FeeCollectorName, app.GetSubspace(distrtypes.ModuleName)), - ccvstaking.NewAppModule(appCodec, *app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), - upgrade.NewAppModule(&app.UpgradeKeeper), + ccvstaking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), + upgrade.NewAppModule(&app.UpgradeKeeper, app.AccountKeeper.AddressCodec()), evidence.NewAppModule(app.EvidenceKeeper), params.NewAppModule(app.ParamsKeeper), authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), ibc.NewAppModule(app.IBCKeeper), + ibctm.NewAppModule(), transferModule, consumerModule, consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper), ) + ModuleBasics = module.NewBasicManagerFromManager( + app.MM, + map[string]module.AppModuleBasic{ + genutiltypes.ModuleName: genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator), + }) + + app.MM.SetOrderPreBlockers( + upgradetypes.ModuleName, + ) + // During begin block slashing happens after distr.BeginBlocker so that // there is nothing left over in the validator fee pool, so as to keep the // CanWithdrawInvariant invariant. @@ -553,8 +584,6 @@ func New( // NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC) // NOTE: the soft opt-out requires that the consumer module's beginblocker comes after the slashing module's beginblocker app.MM.SetOrderBeginBlockers( - // upgrades should be run first - upgradetypes.ModuleName, capabilitytypes.ModuleName, minttypes.ModuleName, distrtypes.ModuleName, @@ -613,7 +642,6 @@ func New( slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, - crisistypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, feegrant.ModuleName, @@ -625,67 +653,23 @@ func New( ibchost.ModuleName, ibctransfertypes.ModuleName, consumertypes.ModuleName, + crisistypes.ModuleName, ) app.MM.RegisterInvariants(&app.CrisisKeeper) app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) - app.MM.RegisterServices(app.configurator) - - // create the simulation manager and define the order of the modules for deterministic simulations - // - // NOTE: this is not required apps that don't use the simulator for fuzz testing - // transactions - app.sm = module.NewSimulationManager( - auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)), - bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName)), - capability.NewAppModule(appCodec, *app.CapabilityKeeper, false), - feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), - ccvgov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper, IsProposalWhitelisted, app.GetSubspace(govtypes.ModuleName), IsModuleWhiteList), - mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)), - ccvstaking.NewAppModule(appCodec, *app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), - ccvdistr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, *app.StakingKeeper, authtypes.FeeCollectorName, app.GetSubspace(distrtypes.ModuleName)), - slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, *app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName)), - params.NewAppModule(app.ParamsKeeper), - evidence.NewAppModule(app.EvidenceKeeper), ibc.NewAppModule(app.IBCKeeper), - authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), - transferModule, - ) - - app.sm.RegisterStoreDecoders() - - // initialize stores - app.MountKVStores(keys) - app.MountTransientStores(tkeys) - app.MountMemoryStores(memKeys) - - anteHandler, err := NewAnteHandler( - HandlerOptions{ - HandlerOptions: ante.HandlerOptions{ - AccountKeeper: app.AccountKeeper, - BankKeeper: app.BankKeeper, - FeegrantKeeper: app.FeeGrantKeeper, - SignModeHandler: encodingConfig.TxConfig.SignModeHandler(), - SigGasConsumer: ante.DefaultSigVerificationGasConsumer, - }, - IBCKeeper: app.IBCKeeper, - ConsumerKeeper: app.ConsumerKeeper, - }, - ) + err := app.MM.RegisterServices(app.configurator) if err != nil { - panic(fmt.Errorf("failed to create AnteHandler: %s", err)) + panic(err) } - app.SetAnteHandler(anteHandler) - - app.SetInitChainer(app.InitChainer) - app.SetBeginBlocker(app.BeginBlocker) - app.SetEndBlocker(app.EndBlocker) // Note this upgrade handler is just an example and may not be exactly what you need to implement. // See https://docs.cosmos.network/v0.45/building-modules/upgrade.html app.UpgradeKeeper.SetUpgradeHandler( upgradeName, - func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { - app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) + func(ctx context.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + app.IBCKeeper.ConnectionKeeper.SetParams(sdkCtx, ibcconnectiontypes.DefaultParams()) fromVM := make(map[string]uint64) @@ -715,9 +699,9 @@ func New( appCodec.MustUnmarshalJSON(appState[consumertypes.ModuleName], &consumerGenesis) consumerGenesis.PreCCV = true - app.ConsumerKeeper.InitGenesis(ctx, &consumerGenesis) + app.ConsumerKeeper.InitGenesis(sdkCtx, &consumerGenesis) - ctx.Logger().Info("start to run module migrations...") + app.Logger().Info("start to run module migrations...") // Note: consumer ccv module is added to app.MM.Modules constructor above, // meaning the consumer ccv module will have an entry in fromVM. @@ -744,23 +728,64 @@ func New( app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) } + autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.MM.Modules)) + + reflectionSvc, err := runtimeservices.NewReflectionService() + if err != nil { + panic(err) + } + reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc) + + // initialize stores + app.MountKVStores(keys) + app.MountTransientStores(tkeys) + app.MountMemoryStores(memKeys) + + anteHandler, err := NewAnteHandler( + HandlerOptions{ + HandlerOptions: ante.HandlerOptions{ + AccountKeeper: app.AccountKeeper, + BankKeeper: app.BankKeeper, + FeegrantKeeper: app.FeeGrantKeeper, + SignModeHandler: encodingConfig.TxConfig.SignModeHandler(), + SigGasConsumer: ante.DefaultSigVerificationGasConsumer, + }, + IBCKeeper: app.IBCKeeper, + ConsumerKeeper: app.ConsumerKeeper, + }, + ) + if err != nil { + panic(fmt.Errorf("failed to create AnteHandler: %s", err)) + } + app.SetAnteHandler(anteHandler) + + app.SetInitChainer(app.InitChainer) + app.SetPreBlocker(app.PreBlocker) + app.SetBeginBlocker(app.BeginBlocker) + app.SetEndBlocker(app.EndBlocker) + if loadLatest { if err := app.LoadLatestVersion(); err != nil { tmos.Exit(fmt.Sprintf("failed to load latest version: %s", err)) } } - app.ScopedIBCKeeper = scopedIBCKeeper - app.ScopedTransferKeeper = scopedTransferKeeper - app.ScopedIBCConsumerKeeper = scopedIBCConsumerKeeper - - autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.MM.Modules)) - - reflectionSvc, err := runtimeservices.NewReflectionService() + // At startup, after all modules have been registered, check that all prot + // annotations are correct. + protoFiles, err := proto.MergedRegistry() if err != nil { panic(err) } - reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc) + err = msgservice.ValidateProtoAnnotations(protoFiles) + if err != nil { + // Once we switch to using protoreflect-based antehandlers, we might + // want to panic here instead of logging a warning. + fmt.Fprintln(os.Stderr, err.Error()) + } + + app.ScopedIBCKeeper = scopedIBCKeeper + app.ScopedTransferKeeper = scopedTransferKeeper + app.ScopedIBCConsumerKeeper = scopedIBCConsumerKeeper return app } @@ -768,18 +793,22 @@ func New( // Name returns the name of the App func (app *App) Name() string { return app.BaseApp.Name() } +func (app *App) PreBlocker(ctx sdk.Context, _ *abci.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error) { + return app.MM.PreBlock(ctx) +} + // BeginBlocker application updates every begin block -func (app *App) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { - return app.MM.BeginBlock(ctx, req) +func (app *App) BeginBlocker(ctx sdk.Context) (sdk.BeginBlock, error) { + return app.MM.BeginBlock(ctx) } // EndBlocker application updates every end block -func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { - return app.MM.EndBlock(ctx, req) +func (app *App) EndBlocker(ctx sdk.Context) (sdk.EndBlock, error) { + return app.MM.EndBlock(ctx) } // InitChainer application update at chain initialization -func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { +func (app *App) InitChainer(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) { var genesisState GenesisState if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil { panic(err) @@ -882,7 +911,7 @@ func (app *App) GetTestSlashingKeeper() testutil.TestSlashingKeeper { } // GetTestEvidenceKeeper implements the ConsumerApp interface. -func (app *App) GetTestEvidenceKeeper() testutil.TestEvidenceKeeper { +func (app *App) GetTestEvidenceKeeper() evidencekeeper.Keeper { return app.EvidenceKeeper } @@ -897,12 +926,12 @@ func (app *App) GetTestDistributionKeeper() testutil.TestDistributionKeeper { } // GetTestMintKeeper implements the ConsumerApp interface. -func (app *App) GetTestMintKeeper() testutil.TestMintKeeper { +func (app *App) GetTestMintKeeper() mintkeeper.Keeper { return app.MintKeeper } // GetTestGovKeeper implements the ConsumerApp interface. -func (app *App) GetTestGovKeeper() testutil.TestGovKeeper { +func (app *App) GetTestGovKeeper() govkeeper.Keeper { return app.GovKeeper } @@ -930,7 +959,7 @@ func (app *App) GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper { // GetTxConfig implements the TestingApp interface. func (app *App) GetTxConfig() client.TxConfig { - return MakeTestEncodingConfig().TxConfig + return app.txConfig } // TxConfig returns SimApp's TxConfig @@ -938,6 +967,26 @@ func (app *App) TxConfig() client.TxConfig { return app.txConfig } +// AutoCliOpts returns the autocli options for the app. +func (app *App) AutoCliOpts() autocli.AppOptions { + modules := make(map[string]appmodule.AppModule, 0) + for _, m := range app.MM.Modules { + if moduleWithName, ok := m.(module.HasName); ok { + moduleName := moduleWithName.Name() + if appModule, ok := moduleWithName.(appmodule.AppModule); ok { + modules[moduleName] = appModule + } + } + } + + return autocli.AppOptions{ + Modules: modules, + AddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), + ValidatorAddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + ConsensusAddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), + } +} + // RegisterAPIRoutes registers all application module routes with the provided // API server. func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { @@ -945,7 +994,7 @@ func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig // Register new tx routes from grpc-gateway. authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) // Register new tendermint queries routes from grpc-gateway. - tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + cmtservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) // Register node gRPC service for grpc-gateway. nodeservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) @@ -964,13 +1013,13 @@ func (app *App) RegisterTxService(clientCtx client.Context) { authtx.RegisterTxService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.BaseApp.Simulate, app.interfaceRegistry) } -func (app *App) RegisterNodeService(clientCtx client.Context) { - nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter()) +func (app *App) RegisterNodeService(clientCtx client.Context, cfg config.Config) { + nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter(), cfg) } // RegisterTendermintService implements the Application.RegisterTendermintService method. func (app *App) RegisterTendermintService(clientCtx client.Context) { - tmservice.RegisterTendermintService(clientCtx, app.BaseApp.GRPCQueryRouter(), app.interfaceRegistry, app.Query) + cmtservice.RegisterTendermintService(clientCtx, app.BaseApp.GRPCQueryRouter(), app.interfaceRegistry, app.Query) } // GetMaccPerms returns a copy of the module account permissions @@ -1013,12 +1062,3 @@ func MakeTestEncodingConfig() appencoding.EncodingConfig { ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) return encodingConfig } - -func makeEncodingConfig() appencoding.EncodingConfig { - encodingConfig := appencoding.MakeTestEncodingConfig() - std.RegisterLegacyAminoCodec(encodingConfig.Amino) - std.RegisterInterfaces(encodingConfig.InterfaceRegistry) - ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) - ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) - return encodingConfig -} diff --git a/app/consumer-democracy/export.go b/app/consumer-democracy/export.go index bb710da1c4..9f73ae654d 100644 --- a/app/consumer-democracy/export.go +++ b/app/consumer-democracy/export.go @@ -8,7 +8,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" - tmproto "github.com/cometbft/cometbft/proto/tendermint/types" tmtypes "github.com/cometbft/cometbft/types" ) @@ -18,7 +17,7 @@ func (app *App) ExportAppStateAndValidators( forZeroHeight bool, jailAllowedAddrs, modulesToExport []string, ) (servertypes.ExportedApp, error) { // as if they could withdraw from the start of the next block - ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + ctx := app.NewContext(true) // We export at last height + 1, because that's the height at which // Tendermint will start InitChain. @@ -28,7 +27,10 @@ func (app *App) ExportAppStateAndValidators( app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs) } - genState := app.MM.ExportGenesis(ctx, app.appCodec) + genState, err := app.MM.ExportGenesis(ctx, app.appCodec) + if err != nil { + return servertypes.ExportedApp{}, err + } appState, err := json.MarshalIndent(genState, "", " ") if err != nil { return servertypes.ExportedApp{}, err diff --git a/app/consumer-democracy/proposals_whitelisting.go b/app/consumer-democracy/proposals_whitelisting.go index 1e9141895c..383d297505 100644 --- a/app/consumer-democracy/proposals_whitelisting.go +++ b/app/consumer-democracy/proposals_whitelisting.go @@ -1,8 +1,7 @@ package app import ( - ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" "github.com/cosmos/cosmos-sdk/x/params/types/proposal" ) @@ -11,7 +10,6 @@ func IsProposalWhitelisted(content v1beta1.Content) bool { switch c := content.(type) { case *proposal.ParameterChangeProposal: return isLegacyParamChangeWhitelisted(c.Changes) - default: return false } @@ -31,19 +29,23 @@ type legacyParamChangeKey struct { Subspace, Key string } +// these parameters don't exist in the consumer app -- keeping them as an var LegacyWhitelistedParams = map[legacyParamChangeKey]struct{}{ - // ibc transfer - {Subspace: ibctransfertypes.ModuleName, Key: "SendEnabled"}: {}, - {Subspace: ibctransfertypes.ModuleName, Key: "ReceiveEnabled"}: {}, - // add interchain account params(HostEnabled, AllowedMessages) once the module is added to the consumer app + // add whitlisted legacy parameters here [cosmos-sdk <= 0.47] + // commented parameters are just an example - most params have been moved to their respecitve modules + // and they cannot be changed through legacy governance proposals + {Subspace: banktypes.ModuleName, Key: "SendEnabled"}: {}, } +// add whitelisted module param update messages [cosmos-sdk >= 0.47] var WhiteListModule = map[string]struct{}{ - "/cosmos.gov.v1.MsgUpdateParams": {}, - "/cosmos.bank.v1beta1.MsgUpdateParams": {}, - "/cosmos.staking.v1beta1.MsgUpdateParams": {}, - "/cosmos.distribution.v1beta1.MsgUpdateParams": {}, - "/cosmos.mint.v1beta1.MsgUpdateParams": {}, + "/cosmos.gov.v1.MsgUpdateParams": {}, + "/cosmos.bank.v1beta1.MsgUpdateParams": {}, + "/cosmos.staking.v1beta1.MsgUpdateParams": {}, + "/cosmos.distribution.v1beta1.MsgUpdateParams": {}, + "/cosmos.mint.v1beta1.MsgUpdateParams": {}, + "/cosmos.gov.v1beta1.TextProposal": {}, + "/ibc.applications.transfer.v1.MsgUpdateParams": {}, } func IsModuleWhiteList(typeUrl string) bool { diff --git a/app/consumer-democracy/proposals_whitelisting_test.go b/app/consumer-democracy/proposals_whitelisting_test.go deleted file mode 100644 index cf1db2d10b..0000000000 --- a/app/consumer-democracy/proposals_whitelisting_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package app_test - -import ( - "testing" - - ibctesting "github.com/cosmos/ibc-go/v7/testing" - "github.com/stretchr/testify/require" - - appConsumer "github.com/cosmos/interchain-security/v4/app/consumer-democracy" - icstestingutils "github.com/cosmos/interchain-security/v4/testutil/ibc_testing" - testutil "github.com/cosmos/interchain-security/v4/testutil/integration" -) - -func TestDemocracyGovernanceWhitelistingKeys(t *testing.T) { - _, valUpdates, _, err := testutil.CreateValidators(4) - require.NoError(t, err) - ibctesting.DefaultTestingAppInit = icstestingutils.DemocracyConsumerAppIniter(valUpdates) - chain := ibctesting.NewTestChain(t, ibctesting.NewCoordinator(t, 0), "test") - paramKeeper := chain.App.(*appConsumer.App).ParamsKeeper - for paramKey := range appConsumer.LegacyWhitelistedParams { - ss, ok := paramKeeper.GetSubspace(paramKey.Subspace) - require.True(t, ok, "Unknown subspace %s", paramKey.Subspace) - hasKey := ss.Has(chain.GetContext(), []byte(paramKey.Key)) - require.True(t, hasKey, "Invalid key %s for subspace %s", paramKey.Key, paramKey.Subspace) - } -} diff --git a/app/consumer/abci.go b/app/consumer/abci.go new file mode 100644 index 0000000000..94b34cc3bb --- /dev/null +++ b/app/consumer/abci.go @@ -0,0 +1,84 @@ +package app + +import ( + "bytes" + "crypto/rand" + "encoding/json" + "fmt" + + abci "github.com/cometbft/cometbft/abci/types" + + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type ( + // VoteExtensionHandler defines a dummy vote extension handler for SimApp. + // + // NOTE: This implementation is solely used for testing purposes. DO NOT use + // in a production application! + VoteExtensionHandler struct{} + + // VoteExtension defines the structure used to create a dummy vote extension. + VoteExtension struct { + Hash []byte + Height int64 + Data []byte + } +) + +func NewVoteExtensionHandler() *VoteExtensionHandler { + return &VoteExtensionHandler{} +} + +func (h *VoteExtensionHandler) SetHandlers(bApp *baseapp.BaseApp) { + bApp.SetExtendVoteHandler(h.ExtendVote()) + bApp.SetVerifyVoteExtensionHandler(h.VerifyVoteExtension()) +} + +func (h *VoteExtensionHandler) ExtendVote() sdk.ExtendVoteHandler { + return func(_ sdk.Context, req *abci.RequestExtendVote) (*abci.ResponseExtendVote, error) { + buf := make([]byte, 1024) + + _, err := rand.Read(buf) + if err != nil { + return nil, fmt.Errorf("failed to generate random vote extension data: %w", err) + } + + ve := VoteExtension{ + Hash: req.Hash, + Height: req.Height, + Data: buf, + } + + bz, err := json.Marshal(ve) + if err != nil { + return nil, fmt.Errorf("failed to encode vote extension: %w", err) + } + + return &abci.ResponseExtendVote{VoteExtension: bz}, nil + } +} + +func (h *VoteExtensionHandler) VerifyVoteExtension() sdk.VerifyVoteExtensionHandler { + return func(ctx sdk.Context, req *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) { + var ve VoteExtension + + if err := json.Unmarshal(req.VoteExtension, &ve); err != nil { + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + } + + switch { + case req.Height != ve.Height: + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + + case !bytes.Equal(req.Hash, ve.Hash): + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + + case len(ve.Data) != 1024: + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + } + + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_ACCEPT}, nil + } +} diff --git a/app/consumer/ante/disabled_modules_ante_test.go b/app/consumer/ante/disabled_modules_ante_test.go index 7fa95f37c6..187d8bc956 100644 --- a/app/consumer/ante/disabled_modules_ante_test.go +++ b/app/consumer/ante/disabled_modules_ante_test.go @@ -3,17 +3,17 @@ package ante_test import ( "testing" - ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibcclienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/stretchr/testify/require" + evidencetypes "cosmossdk.io/x/evidence/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/authz" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" - "github.com/cosmos/interchain-security/v4/app/consumer/ante" - appencoding "github.com/cosmos/interchain-security/v4/app/encoding" + "github.com/cosmos/interchain-security/v5/app/consumer/ante" + appencoding "github.com/cosmos/interchain-security/v5/app/encoding" ) func TestDisabledModulesDecorator(t *testing.T) { diff --git a/app/consumer/ante/msg_filter_ante_test.go b/app/consumer/ante/msg_filter_ante_test.go index bfc1bb0a50..9080844c03 100644 --- a/app/consumer/ante/msg_filter_ante_test.go +++ b/app/consumer/ante/msg_filter_ante_test.go @@ -3,14 +3,14 @@ package ante_test import ( "testing" - ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + ibcclienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/interchain-security/v4/app/consumer/ante" - appencoding "github.com/cosmos/interchain-security/v4/app/encoding" + "github.com/cosmos/interchain-security/v5/app/consumer/ante" + appencoding "github.com/cosmos/interchain-security/v5/app/encoding" ) type consumerKeeper struct { diff --git a/app/consumer/ante_handler.go b/app/consumer/ante_handler.go index fa28a52caf..24dcfea0e9 100644 --- a/app/consumer/ante_handler.go +++ b/app/consumer/ante_handler.go @@ -1,8 +1,8 @@ package app import ( - ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante" - ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" + ibcante "github.com/cosmos/ibc-go/v8/modules/core/ante" + ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" errorsmod "cosmossdk.io/errors" @@ -10,8 +10,8 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/auth/ante" - consumerante "github.com/cosmos/interchain-security/v4/app/consumer/ante" - ibcconsumerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" + consumerante "github.com/cosmos/interchain-security/v5/app/consumer/ante" + ibcconsumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" ) // HandlerOptions extend the SDK's AnteHandler options by requiring the IBC diff --git a/app/consumer/app.go b/app/consumer/app.go index 9853145117..3bf468b22f 100644 --- a/app/consumer/app.go +++ b/app/consumer/app.go @@ -1,33 +1,48 @@ package app import ( + "context" "fmt" "io" stdlog "log" "os" "path/filepath" - "github.com/cosmos/ibc-go/v7/modules/apps/transfer" - ibctransferkeeper "github.com/cosmos/ibc-go/v7/modules/apps/transfer/keeper" - ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - ibc "github.com/cosmos/ibc-go/v7/modules/core" - ibcconnectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" - porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" - ibchost "github.com/cosmos/ibc-go/v7/modules/core/exported" - ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctesting "github.com/cosmos/ibc-go/v7/testing" - ibctestingtypes "github.com/cosmos/ibc-go/v7/testing/types" - "github.com/spf13/cast" - autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" + "cosmossdk.io/client/v2/autocli" + "cosmossdk.io/core/appmodule" + "github.com/cosmos/cosmos-sdk/testutil/testdata/testpb" + + "github.com/cosmos/ibc-go/v8/modules/apps/transfer" + ibctransferkeeper "github.com/cosmos/ibc-go/v8/modules/apps/transfer/keeper" + ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + ibc "github.com/cosmos/ibc-go/v8/modules/core" + ibcconnectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" + ibchost "github.com/cosmos/ibc-go/v8/modules/core/exported" + ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" + ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v8/testing" + ibctestingtypes "github.com/cosmos/ibc-go/v8/testing/types" + "github.com/spf13/cast" + storetypes "cosmossdk.io/store/types" + "cosmossdk.io/x/evidence" + evidencekeeper "cosmossdk.io/x/evidence/keeper" + evidencetypes "cosmossdk.io/x/evidence/types" + "cosmossdk.io/x/feegrant" + feegrantkeeper "cosmossdk.io/x/feegrant/keeper" + feegrantmodule "cosmossdk.io/x/feegrant/module" + "cosmossdk.io/x/upgrade" + upgradekeeper "cosmossdk.io/x/upgrade/keeper" + upgradetypes "cosmossdk.io/x/upgrade/types" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" - "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/runtime" @@ -37,14 +52,13 @@ import ( "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/std" - storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/ante" + authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" - authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/auth/vesting" @@ -55,19 +69,11 @@ import ( "github.com/cosmos/cosmos-sdk/x/bank" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/cosmos-sdk/x/capability" - capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" + consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" "github.com/cosmos/cosmos-sdk/x/crisis" crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper" crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" - "github.com/cosmos/cosmos-sdk/x/evidence" - evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" - "github.com/cosmos/cosmos-sdk/x/feegrant" - feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper" - feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" @@ -77,29 +83,39 @@ import ( "github.com/cosmos/cosmos-sdk/x/slashing" slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" - "github.com/cosmos/cosmos-sdk/x/upgrade" - upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + "github.com/cosmos/ibc-go/modules/capability" + capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" - dbm "github.com/cometbft/cometbft-db" + "cosmossdk.io/log" abci "github.com/cometbft/cometbft/abci/types" tmjson "github.com/cometbft/cometbft/libs/json" - "github.com/cometbft/cometbft/libs/log" tmos "github.com/cometbft/cometbft/libs/os" + dbm "github.com/cosmos/cosmos-db" - appencoding "github.com/cosmos/interchain-security/v4/app/encoding" - testutil "github.com/cosmos/interchain-security/v4/testutil/integration" - ibcconsumer "github.com/cosmos/interchain-security/v4/x/ccv/consumer" - ibcconsumerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" - ibcconsumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" + appencoding "github.com/cosmos/interchain-security/v5/app/encoding" + testutil "github.com/cosmos/interchain-security/v5/testutil/integration" + ibcconsumer "github.com/cosmos/interchain-security/v5/x/ccv/consumer" + ibcconsumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" + ibcconsumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" ) const ( - AppName = "interchain-security-c" - upgradeName = "ics-v1-to-v2" - AccountAddressPrefix = "consumer" + AppName = "interchain-security-c" + upgradeName = "ics-v1-to-v2" + + Bech32MainPrefix = "consumer" ) +func init() { + userHomeDir, err := os.UserHomeDir() + if err != nil { + stdlog.Println("Failed to get home dir %2", err) + } + + DefaultNodeHome = filepath.Join(userHomeDir, "."+AppName) +} + var ( // DefaultNodeHome default home directories for the application daemon DefaultNodeHome string @@ -122,7 +138,7 @@ var ( evidence.AppModuleBasic{}, transfer.AppModuleBasic{}, vesting.AppModuleBasic{}, - tendermint.AppModuleBasic{}, + ibctm.AppModuleBasic{}, // router.AppModuleBasic{}, ibcconsumer.AppModuleBasic{}, ) @@ -149,12 +165,13 @@ type App struct { // nolint: golint *baseapp.BaseApp legacyAmino *codec.LegacyAmino appCodec codec.Codec - txConfig client.TxConfig interfaceRegistry types.InterfaceRegistry + txConfig client.TxConfig // keys to access the substores - keys map[string]*storetypes.KVStoreKey - tkeys map[string]*storetypes.TransientStoreKey + keys map[string]*storetypes.KVStoreKey + tkeys map[string]*storetypes.TransientStoreKey + memKeys map[string]*storetypes.MemoryStoreKey // keepers @@ -163,10 +180,6 @@ type App struct { // nolint: golint CapabilityKeeper *capabilitykeeper.Keeper SlashingKeeper slashingkeeper.Keeper - // NOTE the distribution keeper should either be removed - // from consumer chain or set to use an independent - // different fee-pool from the consumer chain ConsumerKeeper - CrisisKeeper crisiskeeper.Keeper UpgradeKeeper upgradekeeper.Keeper ParamsKeeper paramskeeper.Keeper @@ -191,15 +204,6 @@ type App struct { // nolint: golint configurator module.Configurator } -func init() { - userHomeDir, err := os.UserHomeDir() - if err != nil { - stdlog.Println("Failed to get home dir %2", err) - } - - DefaultNodeHome = filepath.Join(userHomeDir, "."+AppName) -} - // New returns a reference to an initialized App. func New( logger log.Logger, @@ -216,20 +220,28 @@ func New( interfaceRegistry := encodingConfig.InterfaceRegistry txConfig := encodingConfig.TxConfig + // ABCI++, v50 + voteExtOp := func(bApp *baseapp.BaseApp) { + voteExtHandler := NewVoteExtensionHandler() + voteExtHandler.SetHandlers(bApp) + } + baseAppOptions = append(baseAppOptions, voteExtOp) + bApp := baseapp.NewBaseApp(AppName, logger, db, encodingConfig.TxConfig.TxDecoder(), baseAppOptions...) bApp.SetCommitMultiStoreTracer(traceStore) bApp.SetVersion(version.Version) bApp.SetInterfaceRegistry(interfaceRegistry) - keys := sdk.NewKVStoreKeys( + keys := storetypes.NewKVStoreKeys( authtypes.StoreKey, banktypes.StoreKey, slashingtypes.StoreKey, crisistypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, feegrant.StoreKey, authzkeeper.StoreKey, + consensusparamtypes.StoreKey, ibcconsumertypes.StoreKey, ) - tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) - memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) + tkeys := storetypes.NewTransientStoreKeys(paramstypes.TStoreKey) + memKeys := storetypes.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) app := &App{ BaseApp: bApp, @@ -250,8 +262,8 @@ func New( ) // set the BaseApp's parameter store - app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, keys[upgradetypes.StoreKey], authtypes.NewModuleAddress(govtypes.ModuleName).String()) - bApp.SetParamStore(&app.ConsensusParamsKeeper) + app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[consensusparamtypes.StoreKey]), authtypes.NewModuleAddress(govtypes.ModuleName).String(), runtime.EventService{}) + bApp.SetParamStore(&app.ConsensusParamsKeeper.ParamsStore) // add capability keeper and ScopeToModule for ibc module app.CapabilityKeeper = capabilitykeeper.NewKeeper( @@ -267,10 +279,11 @@ func New( // add keepers app.AccountKeeper = authkeeper.NewAccountKeeper( appCodec, - keys[authtypes.StoreKey], + runtime.NewKVStoreService(keys[authtypes.StoreKey]), authtypes.ProtoBaseAccount, maccPerms, - AccountAddressPrefix, + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), + sdk.GetConfig().GetBech32AccountAddrPrefix(), authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) @@ -283,20 +296,22 @@ func New( app.BankKeeper = bankkeeper.NewBaseKeeper( appCodec, - keys[banktypes.StoreKey], + runtime.NewKVStoreService(keys[banktypes.StoreKey]), app.AccountKeeper, bankBlockedAddrs, authtypes.NewModuleAddress(govtypes.ModuleName).String(), + logger, ) app.AuthzKeeper = authzkeeper.NewKeeper( - keys[authzkeeper.StoreKey], + runtime.NewKVStoreService(keys[authzkeeper.StoreKey]), appCodec, - app.BaseApp.MsgServiceRouter(), + app.MsgServiceRouter(), app.AccountKeeper, ) + app.FeeGrantKeeper = feegrantkeeper.NewKeeper( appCodec, - keys[feegrant.StoreKey], + runtime.NewKVStoreService(keys[feegrant.StoreKey]), app.AccountKeeper, ) @@ -305,7 +320,7 @@ func New( app.SlashingKeeper = slashingkeeper.NewKeeper( appCodec, legacyAmino, - keys[slashingtypes.StoreKey], + runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), &app.ConsumerKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) @@ -313,11 +328,12 @@ func New( invCheckPeriod := cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)) app.CrisisKeeper = *crisiskeeper.NewKeeper( appCodec, - keys[crisistypes.StoreKey], + runtime.NewKVStoreService(keys[crisistypes.StoreKey]), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String(), + app.AccountKeeper.AddressCodec(), ) // get skipUpgradeHeights from the app options @@ -329,7 +345,7 @@ func New( // set the governance module account as the authority for conducting upgrades app.UpgradeKeeper = *upgradekeeper.NewKeeper( skipUpgradeHeights, - keys[upgradetypes.StoreKey], + runtime.NewKVStoreService(keys[upgradetypes.StoreKey]), appCodec, homePath, app.BaseApp, @@ -353,6 +369,7 @@ func New( app.ConsumerKeeper, app.UpgradeKeeper, scopedIBCKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) // initialize the actual consumer keeper @@ -362,7 +379,7 @@ func New( app.GetSubspace(ibcconsumertypes.ModuleName), scopedIBCConsumerKeeper, app.IBCKeeper.ChannelKeeper, - &app.IBCKeeper.PortKeeper, + app.IBCKeeper.PortKeeper, app.IBCKeeper.ConnectionKeeper, app.IBCKeeper.ClientKeeper, app.SlashingKeeper, @@ -371,6 +388,9 @@ func New( &app.TransferKeeper, app.IBCKeeper, authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), ) // register slashing module Slashing hooks to the consumer keeper @@ -383,10 +403,11 @@ func New( app.GetSubspace(ibctransfertypes.ModuleName), app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper, - &app.IBCKeeper.PortKeeper, + app.IBCKeeper.PortKeeper, app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) transferModule := transfer.NewAppModule(app.TransferKeeper) ibcmodule := transfer.NewIBCModule(app.TransferKeeper) @@ -400,9 +421,11 @@ func New( // create evidence keeper with router evidenceKeeper := evidencekeeper.NewKeeper( appCodec, - keys[evidencetypes.StoreKey], + runtime.NewKVStoreService(keys[evidencetypes.StoreKey]), &app.ConsumerKeeper, app.SlashingKeeper, + app.AccountKeeper.AddressCodec(), + runtime.ProvideCometInfoService(), ) app.EvidenceKeeper = *evidenceKeeper @@ -415,7 +438,7 @@ func New( genutil.NewAppModule( app.AccountKeeper, app.ConsumerKeeper, - app.BaseApp.DeliverTx, + app, encodingConfig.TxConfig, ), auth.NewAppModule(appCodec, app.AccountKeeper, nil, app.GetSubspace(authtypes.ModuleName)), @@ -423,17 +446,28 @@ func New( bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName)), capability.NewAppModule(appCodec, *app.CapabilityKeeper, false), crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)), - slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.ConsumerKeeper, app.GetSubspace(slashingtypes.ModuleName)), - upgrade.NewAppModule(&app.UpgradeKeeper), + slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.ConsumerKeeper, app.GetSubspace(slashingtypes.ModuleName), app.interfaceRegistry), + upgrade.NewAppModule(&app.UpgradeKeeper, app.AccountKeeper.AddressCodec()), evidence.NewAppModule(app.EvidenceKeeper), feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), ibc.NewAppModule(app.IBCKeeper), + ibctm.NewAppModule(), params.NewAppModule(app.ParamsKeeper), transferModule, consumerModule, ) + ModuleBasics = module.NewBasicManagerFromManager( + app.MM, + map[string]module.AppModuleBasic{ + genutiltypes.ModuleName: genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator), + }) + + app.MM.SetOrderPreBlockers( + upgradetypes.ModuleName, + ) + // During begin block slashing happens after distr.BeginBlocker so that // there is nothing left over in the validator fee pool, so as to keep the // CanWithdrawInvariant invariant. @@ -441,7 +475,6 @@ func New( // NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC) app.MM.SetOrderBeginBlockers( // upgrades should be run first - upgradetypes.ModuleName, capabilitytypes.ModuleName, crisistypes.ModuleName, ibctransfertypes.ModuleName, @@ -457,6 +490,8 @@ func New( vestingtypes.ModuleName, ibcconsumertypes.ModuleName, ) + app.SetPreBlocker(app.PreBlocker) + app.MM.SetOrderEndBlockers( crisistypes.ModuleName, ibctransfertypes.ModuleName, @@ -502,30 +537,32 @@ func New( app.MM.RegisterInvariants(&app.CrisisKeeper) app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) - app.MM.RegisterServices(app.configurator) - - // create the simulation manager and define the order of the modules for deterministic simulations - // - // NOTE: this is not required apps that don't use the simulator for fuzz testing - // transactions - app.sm = module.NewSimulationManager( - auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)), - bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName)), - capability.NewAppModule(appCodec, *app.CapabilityKeeper, false), - feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), - authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), - params.NewAppModule(app.ParamsKeeper), - evidence.NewAppModule(app.EvidenceKeeper), ibc.NewAppModule(app.IBCKeeper), - transferModule, - ) + err := app.MM.RegisterServices(app.configurator) + if err != nil { + panic(err) + } - app.sm.RegisterStoreDecoders() + autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.MM.Modules)) + + reflectionSvc, err := runtimeservices.NewReflectionService() + if err != nil { + panic(err) + } + reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc) + + // add test gRPC service for testing gRPC queries in isolation + testpb.RegisterQueryServer(app.GRPCQueryRouter(), testpb.QueryImpl{}) // initialize stores app.MountKVStores(keys) app.MountTransientStores(tkeys) app.MountMemoryStores(memKeys) + app.SetInitChainer(app.InitChainer) + app.SetPreBlocker(app.PreBlocker) + app.SetBeginBlocker(app.BeginBlocker) + app.SetEndBlocker(app.EndBlocker) + anteHandler, err := NewAnteHandler( HandlerOptions{ HandlerOptions: ante.HandlerOptions{ @@ -544,16 +581,13 @@ func New( } app.SetAnteHandler(anteHandler) - app.SetInitChainer(app.InitChainer) - app.SetBeginBlocker(app.BeginBlocker) - app.SetEndBlocker(app.EndBlocker) - // Note this upgrade handler is just an example and may not be exactly what you need to implement. // See https://docs.cosmos.network/v0.45/building-modules/upgrade.html app.UpgradeKeeper.SetUpgradeHandler( upgradeName, - func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { - app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) + func(ctx context.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + app.IBCKeeper.ConnectionKeeper.SetParams(sdkCtx, ibcconnectiontypes.DefaultParams()) fromVM := make(map[string]uint64) @@ -564,7 +598,7 @@ func New( } } - ctx.Logger().Info("start to run module migrations...") + app.Logger().Info("start to run module migrations...") return app.MM.RunMigrations(ctx, app.configurator, fromVM) }, @@ -592,32 +626,28 @@ func New( app.ScopedTransferKeeper = scopedTransferKeeper app.ScopedIBCConsumerKeeper = scopedIBCConsumerKeeper - autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.MM.Modules)) - - reflectionSvc, err := runtimeservices.NewReflectionService() - if err != nil { - panic(err) - } - reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc) - return app } // Name returns the name of the App func (app *App) Name() string { return app.BaseApp.Name() } +func (app *App) PreBlocker(ctx sdk.Context, _ *abci.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error) { + return app.MM.PreBlock(ctx) +} + // BeginBlocker application updates every begin block -func (app *App) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { - return app.MM.BeginBlock(ctx, req) +func (app *App) BeginBlocker(ctx sdk.Context) (sdk.BeginBlock, error) { + return app.MM.BeginBlock(ctx) } // EndBlocker application updates every end block -func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { - return app.MM.EndBlock(ctx, req) +func (app *App) EndBlocker(ctx sdk.Context) (sdk.EndBlock, error) { + return app.MM.EndBlock(ctx) } // InitChainer application update at chain initialization -func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { +func (app *App) InitChainer(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) { var genesisState GenesisState if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil { panic(err) @@ -720,7 +750,7 @@ func (app *App) GetTestSlashingKeeper() testutil.TestSlashingKeeper { } // GetTestEvidenceKeeper implements the ConsumerApp interface. -func (app *App) GetTestEvidenceKeeper() testutil.TestEvidenceKeeper { +func (app *App) GetTestEvidenceKeeper() evidencekeeper.Keeper { return app.EvidenceKeeper } @@ -756,6 +786,26 @@ func (app *App) TxConfig() client.TxConfig { return app.txConfig } +// AutoCliOpts returns the autocli options for the app. +func (app *App) AutoCliOpts() autocli.AppOptions { + modules := make(map[string]appmodule.AppModule, 0) + for _, m := range app.MM.Modules { + if moduleWithName, ok := m.(module.HasName); ok { + moduleName := moduleWithName.Name() + if appModule, ok := moduleWithName.(appmodule.AppModule); ok { + modules[moduleName] = appModule + } + } + } + + return autocli.AppOptions{ + Modules: modules, + AddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), + ValidatorAddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + ConsensusAddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), + } +} + // RegisterAPIRoutes registers all application module routes with the provided // API server. func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { @@ -764,7 +814,7 @@ func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig // Register new tx routes from grpc-gateway. authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) // Register new tendermint queries routes from grpc-gateway. - tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + cmtservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) // Register grpc query routes. ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) @@ -775,13 +825,13 @@ func (app *App) RegisterTxService(clientCtx client.Context) { authtx.RegisterTxService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.BaseApp.Simulate, app.interfaceRegistry) } -func (app *App) RegisterNodeService(clientCtx client.Context) { - nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter()) +func (app *App) RegisterNodeService(clientCtx client.Context, cfg config.Config) { + nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter(), cfg) } // RegisterTendermintService implements the Application.RegisterTendermintService method. func (app *App) RegisterTendermintService(clientCtx client.Context) { - tmservice.RegisterTendermintService(clientCtx, app.BaseApp.GRPCQueryRouter(), app.interfaceRegistry, app.Query) + cmtservice.RegisterTendermintService(clientCtx, app.BaseApp.GRPCQueryRouter(), app.interfaceRegistry, app.Query) } // GetMaccPerms returns a copy of the module account permissions @@ -808,28 +858,6 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino return paramsKeeper } -// MakeTestEncodingConfig creates an EncodingConfig for testing. This function -// should be used only in tests or when creating a new app instance (NewApp*()). -// App user shouldn't create new codecs - use the app.AppCodec instead. -// [DEPRECATED] -// func MakeTestEncodingConfig() appparams.EncodingConfig { -// encodingConfig := appparams.MakeTestEncodingConfig() -// std.RegisterLegacyAminoCodec(encodingConfig.Amino) -// std.RegisterInterfaces(encodingConfig.InterfaceRegistry) -// ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) -// ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) -// return encodingConfig -// } - -// func makeEncodingConfig() simappparams.EncodingConfig { -// encodingConfig := simappparams.MakeTestEncodingConfig() -// std.RegisterLegacyAminoCodec(encodingConfig.Amino) -// std.RegisterInterfaces(encodingConfig.InterfaceRegistry) -// ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) -// ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) -// return encodingConfig -// } - func MakeTestEncodingConfig() appencoding.EncodingConfig { encodingConfig := appencoding.MakeTestEncodingConfig() std.RegisterLegacyAminoCodec(encodingConfig.Amino) diff --git a/app/consumer/export.go b/app/consumer/export.go index 4260efda92..c8fd545f05 100644 --- a/app/consumer/export.go +++ b/app/consumer/export.go @@ -8,7 +8,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" - tmproto "github.com/cometbft/cometbft/proto/tendermint/types" tmtypes "github.com/cometbft/cometbft/types" ) @@ -18,7 +17,7 @@ func (app *App) ExportAppStateAndValidators( forZeroHeight bool, jailAllowedAddrs, modulesToExport []string, ) (servertypes.ExportedApp, error) { // as if they could withdraw from the start of the next block - ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + ctx := app.NewContext(true) // We export at last height + 1, because that's the height at which // Tendermint will start InitChain. @@ -28,7 +27,10 @@ func (app *App) ExportAppStateAndValidators( app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs) } - genState := app.MM.ExportGenesis(ctx, app.appCodec) + genState, err := app.MM.ExportGenesis(ctx, app.appCodec) + if err != nil { + return servertypes.ExportedApp{}, err + } appState, err := json.MarshalIndent(genState, "", " ") if err != nil { return servertypes.ExportedApp{}, err diff --git a/app/consumer/genesis.go b/app/consumer/genesis.go index bf7ba81c95..9f19463d87 100644 --- a/app/consumer/genesis.go +++ b/app/consumer/genesis.go @@ -15,8 +15,8 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" - consumerTypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - "github.com/cosmos/interchain-security/v4/x/ccv/types" + consumerTypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // The genesis state of the blockchain is represented here as a map of raw json diff --git a/app/consumer/genesis_test.go b/app/consumer/genesis_test.go index f5aa3208b1..acfcae1746 100644 --- a/app/consumer/genesis_test.go +++ b/app/consumer/genesis_test.go @@ -16,9 +16,9 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/x/auth/types" - app "github.com/cosmos/interchain-security/v4/app/consumer" - consumerTypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + app "github.com/cosmos/interchain-security/v5/app/consumer" + consumerTypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // Testdata mapping consumer genesis exports to a provider module version as diff --git a/app/encoding/encoding.go b/app/encoding/encoding.go index 6897e53634..216adac79c 100644 --- a/app/encoding/encoding.go +++ b/app/encoding/encoding.go @@ -1,10 +1,14 @@ package encoding import ( + "cosmossdk.io/x/tx/signing" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/address" "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/tx" + "github.com/cosmos/gogoproto/proto" ) // EncodingConfig specifies the concrete encoding types to use for a given app. @@ -19,7 +23,17 @@ type EncodingConfig struct { // MakeTestEncodingConfig creates an EncodingConfig for an amino based test configuration. func MakeTestEncodingConfig() EncodingConfig { amino := codec.NewLegacyAmino() - interfaceRegistry := types.NewInterfaceRegistry() + interfaceRegistry, _ := types.NewInterfaceRegistryWithOptions(types.InterfaceRegistryOptions{ + ProtoFiles: proto.HybridResolver, + SigningOptions: signing.Options{ + AddressCodec: address.Bech32Codec{ + Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix(), + }, + ValidatorAddressCodec: address.Bech32Codec{ + Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix(), + }, + }, + }) chainCodec := codec.NewProtoCodec(interfaceRegistry) txCfg := tx.NewTxConfig(chainCodec, tx.DefaultSignModes) diff --git a/app/provider/abci.go b/app/provider/abci.go new file mode 100644 index 0000000000..94b34cc3bb --- /dev/null +++ b/app/provider/abci.go @@ -0,0 +1,84 @@ +package app + +import ( + "bytes" + "crypto/rand" + "encoding/json" + "fmt" + + abci "github.com/cometbft/cometbft/abci/types" + + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type ( + // VoteExtensionHandler defines a dummy vote extension handler for SimApp. + // + // NOTE: This implementation is solely used for testing purposes. DO NOT use + // in a production application! + VoteExtensionHandler struct{} + + // VoteExtension defines the structure used to create a dummy vote extension. + VoteExtension struct { + Hash []byte + Height int64 + Data []byte + } +) + +func NewVoteExtensionHandler() *VoteExtensionHandler { + return &VoteExtensionHandler{} +} + +func (h *VoteExtensionHandler) SetHandlers(bApp *baseapp.BaseApp) { + bApp.SetExtendVoteHandler(h.ExtendVote()) + bApp.SetVerifyVoteExtensionHandler(h.VerifyVoteExtension()) +} + +func (h *VoteExtensionHandler) ExtendVote() sdk.ExtendVoteHandler { + return func(_ sdk.Context, req *abci.RequestExtendVote) (*abci.ResponseExtendVote, error) { + buf := make([]byte, 1024) + + _, err := rand.Read(buf) + if err != nil { + return nil, fmt.Errorf("failed to generate random vote extension data: %w", err) + } + + ve := VoteExtension{ + Hash: req.Hash, + Height: req.Height, + Data: buf, + } + + bz, err := json.Marshal(ve) + if err != nil { + return nil, fmt.Errorf("failed to encode vote extension: %w", err) + } + + return &abci.ResponseExtendVote{VoteExtension: bz}, nil + } +} + +func (h *VoteExtensionHandler) VerifyVoteExtension() sdk.VerifyVoteExtensionHandler { + return func(ctx sdk.Context, req *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) { + var ve VoteExtension + + if err := json.Unmarshal(req.VoteExtension, &ve); err != nil { + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + } + + switch { + case req.Height != ve.Height: + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + + case !bytes.Equal(req.Hash, ve.Hash): + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + + case len(ve.Data) != 1024: + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + } + + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_ACCEPT}, nil + } +} diff --git a/app/provider/ante_handler.go b/app/provider/ante_handler.go index 9ba33d3264..564f96284d 100644 --- a/app/provider/ante_handler.go +++ b/app/provider/ante_handler.go @@ -1,8 +1,8 @@ package app import ( - ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante" - ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" + ibcante "github.com/cosmos/ibc-go/v8/modules/core/ante" + ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" errorsmod "cosmossdk.io/errors" diff --git a/app/provider/app.go b/app/provider/app.go index 7527756d45..ef60ccc53b 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -1,37 +1,47 @@ package app import ( + "context" "fmt" "io" stdlog "log" "os" "path/filepath" - "github.com/cosmos/ibc-go/v7/modules/apps/transfer" - ibctransferkeeper "github.com/cosmos/ibc-go/v7/modules/apps/transfer/keeper" - ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - ibc "github.com/cosmos/ibc-go/v7/modules/core" - ibcclient "github.com/cosmos/ibc-go/v7/modules/core/02-client" - ibcclientclient "github.com/cosmos/ibc-go/v7/modules/core/02-client/client" - ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - ibcconnectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" - porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" - ibchost "github.com/cosmos/ibc-go/v7/modules/core/exported" - ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctesting "github.com/cosmos/ibc-go/v7/testing" - ibctestingtypes "github.com/cosmos/ibc-go/v7/testing/types" + "github.com/cosmos/gogoproto/proto" + "github.com/cosmos/ibc-go/v8/modules/apps/transfer" + ibctransferkeeper "github.com/cosmos/ibc-go/v8/modules/apps/transfer/keeper" + ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + ibc "github.com/cosmos/ibc-go/v8/modules/core" + ibcconnectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" + ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" + ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" + ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v8/testing" + ibctestingtypes "github.com/cosmos/ibc-go/v8/testing/types" "github.com/spf13/cast" autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" - + "cosmossdk.io/client/v2/autocli" + "cosmossdk.io/core/appmodule" + + storetypes "cosmossdk.io/store/types" + "cosmossdk.io/x/evidence" + evidencekeeper "cosmossdk.io/x/evidence/keeper" + evidencetypes "cosmossdk.io/x/evidence/types" + "cosmossdk.io/x/tx/signing" + "cosmossdk.io/x/upgrade" + upgradekeeper "cosmossdk.io/x/upgrade/keeper" + upgradetypes "cosmossdk.io/x/upgrade/types" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" - "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/address" "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/runtime" runtimeservices "github.com/cosmos/cosmos-sdk/runtime/services" @@ -40,14 +50,15 @@ import ( "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/std" - storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/types/msgservice" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/ante" + authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" - authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" + "github.com/cosmos/cosmos-sdk/x/auth/posthandler" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/auth/vesting" @@ -55,19 +66,15 @@ import ( "github.com/cosmos/cosmos-sdk/x/bank" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/cosmos-sdk/x/capability" - capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + "github.com/cosmos/cosmos-sdk/x/consensus" consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" + consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" "github.com/cosmos/cosmos-sdk/x/crisis" crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper" crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" distr "github.com/cosmos/cosmos-sdk/x/distribution" distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - "github.com/cosmos/cosmos-sdk/x/evidence" - evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/cosmos/cosmos-sdk/x/gov" @@ -89,29 +96,31 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/cosmos/cosmos-sdk/x/upgrade" - upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" - upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + "github.com/cosmos/ibc-go/modules/capability" + capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" - dbm "github.com/cometbft/cometbft-db" + "cosmossdk.io/log" abci "github.com/cometbft/cometbft/abci/types" tmjson "github.com/cometbft/cometbft/libs/json" - "github.com/cometbft/cometbft/libs/log" tmos "github.com/cometbft/cometbft/libs/os" - - appencoding "github.com/cosmos/interchain-security/v4/app/encoding" - testutil "github.com/cosmos/interchain-security/v4/testutil/integration" - ibcprovider "github.com/cosmos/interchain-security/v4/x/ccv/provider" - ibcproviderclient "github.com/cosmos/interchain-security/v4/x/ccv/provider/client" - ibcproviderkeeper "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + dbm "github.com/cosmos/cosmos-db" + + appencoding "github.com/cosmos/interchain-security/v5/app/encoding" + testutil "github.com/cosmos/interchain-security/v5/testutil/integration" + ibcprovider "github.com/cosmos/interchain-security/v5/x/ccv/provider" + ibcproviderclient "github.com/cosmos/interchain-security/v5/x/ccv/provider/client" + ibcproviderkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + + "github.com/cosmos/cosmos-sdk/testutil/testdata/testpb" + sigtypes "github.com/cosmos/cosmos-sdk/types/tx/signing" + txmodule "github.com/cosmos/cosmos-sdk/x/auth/tx/config" ) const ( - AppName = "interchain-security-p" - upgradeName = "ics-v1-to-v2" - AccountAddressPrefix = "cosmos" + AppName = "interchain-security-p" + upgradeName = "ics-v1-to-v2" ) // this line is used by starport scaffolding # stargate/wasm/app/enabledProposals @@ -124,35 +133,32 @@ var ( // non-dependant module elements, such as codec registration // and genesis verification. ModuleBasics = module.NewBasicManager( - auth.AppModuleBasic{}, genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator), + auth.AppModuleBasic{}, + vesting.AppModuleBasic{}, bank.AppModuleBasic{}, capability.AppModuleBasic{}, - staking.AppModuleBasic{}, - mint.AppModuleBasic{}, - distr.AppModuleBasic{}, + consensus.AppModuleBasic{}, + crisis.AppModuleBasic{}, gov.NewAppModuleBasic( []govclient.ProposalHandler{ paramsclient.ProposalHandler, - upgradeclient.LegacyProposalHandler, - upgradeclient.LegacyCancelProposalHandler, - ibcclientclient.UpdateClientProposalHandler, - ibcclientclient.UpgradeProposalHandler, ibcproviderclient.ConsumerAdditionProposalHandler, ibcproviderclient.ConsumerRemovalProposalHandler, ibcproviderclient.ChangeRewardDenomsProposalHandler, }, ), - params.AppModuleBasic{}, - crisis.AppModuleBasic{}, + mint.AppModuleBasic{}, slashing.AppModuleBasic{}, - ibc.AppModuleBasic{}, + distr.AppModuleBasic{}, + staking.AppModuleBasic{}, upgrade.AppModuleBasic{}, evidence.AppModuleBasic{}, + + ibc.AppModuleBasic{}, + ibctm.AppModuleBasic{}, + params.AppModuleBasic{}, transfer.AppModuleBasic{}, - vesting.AppModuleBasic{}, - tendermint.AppModuleBasic{}, - // router.AppModuleBasic{}, ibcprovider.AppModuleBasic{}, ) @@ -244,27 +250,52 @@ func New( appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp), ) *App { - encodingConfig := makeEncodingConfig() - - appCodec := encodingConfig.Codec - legacyAmino := encodingConfig.Amino - interfaceRegistry := encodingConfig.InterfaceRegistry + interfaceRegistry, _ := types.NewInterfaceRegistryWithOptions(types.InterfaceRegistryOptions{ + ProtoFiles: proto.HybridResolver, + SigningOptions: signing.Options{ + AddressCodec: address.Bech32Codec{ + Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix(), + }, + ValidatorAddressCodec: address.Bech32Codec{ + Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix(), + }, + }, + }) + appCodec := codec.NewProtoCodec(interfaceRegistry) + legacyAmino := codec.NewLegacyAmino() + txConfig := authtx.NewTxConfig(appCodec, authtx.DefaultSignModes) + + std.RegisterLegacyAminoCodec(legacyAmino) + std.RegisterInterfaces(interfaceRegistry) + // ABCI++, v50 + voteExtOp := func(bApp *baseapp.BaseApp) { + voteExtHandler := NewVoteExtensionHandler() + voteExtHandler.SetHandlers(bApp) + } + baseAppOptions = append(baseAppOptions, voteExtOp) - bApp := baseapp.NewBaseApp(AppName, logger, db, encodingConfig.TxConfig.TxDecoder(), baseAppOptions...) + bApp := baseapp.NewBaseApp(AppName, logger, db, txConfig.TxDecoder(), baseAppOptions...) bApp.SetCommitMultiStoreTracer(traceStore) bApp.SetVersion(version.Version) bApp.SetInterfaceRegistry(interfaceRegistry) - keys := sdk.NewKVStoreKeys( + keys := storetypes.NewKVStoreKeys( authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, crisistypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, - govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, + govtypes.StoreKey, paramstypes.StoreKey, ibcexported.StoreKey, upgradetypes.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, providertypes.StoreKey, + consensusparamtypes.StoreKey, ) - tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) - memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) + + // register streaming services + if err := bApp.RegisterStreamingServices(appOpts, keys); err != nil { + panic(err) + } + + tkeys := storetypes.NewTransientStoreKeys(paramstypes.TStoreKey) + memKeys := storetypes.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) app := &App{ BaseApp: bApp, @@ -274,7 +305,7 @@ func New( keys: keys, tkeys: tkeys, memKeys: memKeys, - txConfig: encodingConfig.TxConfig, + txConfig: txConfig, } app.ParamsKeeper = initParamsKeeper( @@ -286,8 +317,14 @@ func New( // set the BaseApp's parameter store // upgradetypes.StoreKey -> maybe consensusparamtypes.StoreKey (package consensusparamtypes ("github.com/cosmos/cosmos-sdk/x/consensus/types") - app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, keys[upgradetypes.StoreKey], authtypes.NewModuleAddress(govtypes.ModuleName).String()) - bApp.SetParamStore(&app.ConsensusParamsKeeper) + app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[consensusparamtypes.StoreKey]), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + runtime.EventService{}, + ) + + bApp.SetParamStore(&app.ConsensusParamsKeeper.ParamsStore) // add capability keeper and ScopeToModule for ibc module app.CapabilityKeeper = capabilitykeeper.NewKeeper( @@ -295,7 +332,7 @@ func New( keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey], ) - scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName) + scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibcexported.ModuleName) scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) scopedIBCProviderKeeper := app.CapabilityKeeper.ScopeToModule(providertypes.ModuleName) app.CapabilityKeeper.Seal() @@ -303,10 +340,11 @@ func New( // add keepers app.AccountKeeper = authkeeper.NewAccountKeeper( appCodec, - keys[authtypes.StoreKey], + runtime.NewKVStoreService(keys[authtypes.StoreKey]), authtypes.ProtoBaseAccount, maccPerms, - AccountAddressPrefix, + authcodec.NewBech32Codec(sdk.Bech32MainPrefix), + sdk.Bech32MainPrefix, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) @@ -319,22 +357,25 @@ func New( app.BankKeeper = bankkeeper.NewBaseKeeper( appCodec, - keys[banktypes.StoreKey], + runtime.NewKVStoreService(keys[banktypes.StoreKey]), app.AccountKeeper, bankBlockedAddrs, authtypes.NewModuleAddress(govtypes.ModuleName).String(), + logger, ) app.StakingKeeper = stakingkeeper.NewKeeper( appCodec, - keys[stakingtypes.StoreKey], + runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), + authcodec.NewBech32Codec(sdk.Bech32PrefixValAddr), + authcodec.NewBech32Codec(sdk.Bech32PrefixConsAddr), ) app.MintKeeper = mintkeeper.NewKeeper( appCodec, - keys[minttypes.StoreKey], + runtime.NewKVStoreService(keys[minttypes.StoreKey]), app.StakingKeeper, app.AccountKeeper, app.BankKeeper, @@ -343,7 +384,7 @@ func New( ) app.DistrKeeper = distrkeeper.NewKeeper( appCodec, - keys[distrtypes.StoreKey], + runtime.NewKVStoreService(keys[distrtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, app.StakingKeeper, @@ -353,7 +394,7 @@ func New( app.SlashingKeeper = slashingkeeper.NewKeeper( appCodec, legacyAmino, - keys[slashingtypes.StoreKey], + runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), app.StakingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) @@ -361,11 +402,12 @@ func New( invCheckPeriod := cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)) app.CrisisKeeper = *crisiskeeper.NewKeeper( appCodec, - keys[crisistypes.StoreKey], + runtime.NewKVStoreService(keys[crisistypes.StoreKey]), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String(), + app.AccountKeeper.AddressCodec(), ) // get skipUpgradeHeights from the app options @@ -377,7 +419,7 @@ func New( // set the governance module account as the authority for conducting upgrades app.UpgradeKeeper = *upgradekeeper.NewKeeper( skipUpgradeHeights, - keys[upgradetypes.StoreKey], + runtime.NewKVStoreService(keys[upgradetypes.StoreKey]), appCodec, homePath, app.BaseApp, @@ -396,29 +438,34 @@ func New( app.IBCKeeper = ibckeeper.NewKeeper( appCodec, - keys[ibchost.StoreKey], - app.GetSubspace(ibchost.ModuleName), + keys[ibcexported.StoreKey], + app.GetSubspace(ibcexported.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) // create evidence keeper with router app.EvidenceKeeper = *evidencekeeper.NewKeeper( appCodec, - keys[evidencetypes.StoreKey], + runtime.NewKVStoreService(keys[evidencetypes.StoreKey]), app.StakingKeeper, app.SlashingKeeper, + app.AccountKeeper.AddressCodec(), + runtime.ProvideCometInfoService(), ) + govConfig := govtypes.DefaultConfig() app.GovKeeper = govkeeper.NewKeeper( appCodec, - keys[govtypes.StoreKey], + runtime.NewKVStoreService(keys[govtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, app.StakingKeeper, + app.DistrKeeper, app.MsgServiceRouter(), - govtypes.DefaultConfig(), + govConfig, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) @@ -428,7 +475,7 @@ func New( app.GetSubspace(providertypes.ModuleName), scopedIBCProviderKeeper, app.IBCKeeper.ChannelKeeper, - &app.IBCKeeper.PortKeeper, + app.IBCKeeper.PortKeeper, app.IBCKeeper.ConnectionKeeper, app.IBCKeeper.ClientKeeper, app.StakingKeeper, @@ -436,22 +483,20 @@ func New( app.AccountKeeper, app.DistrKeeper, app.BankKeeper, - app.GovKeeper, + *app.GovKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + authcodec.NewBech32Codec(sdk.Bech32PrefixValAddr), + authcodec.NewBech32Codec(sdk.Bech32PrefixConsAddr), authtypes.FeeCollectorName, ) - providerModule := ibcprovider.NewAppModule(&app.ProviderKeeper, app.GetSubspace(providertypes.ModuleName)) - - // register the proposal types + // gov router must be set after the provider keeper is created + // otherwise the provider keeper will not be able to handle proposals (will be nil) govRouter := govv1beta1.NewRouter() govRouter. AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler). AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). - AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(&app.UpgradeKeeper)). - AddRoute(ibchost.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)). - AddRoute(providertypes.RouterKey, ibcprovider.NewProviderProposalHandler(app.ProviderKeeper)). - AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)) - + AddRoute(providertypes.RouterKey, ibcprovider.NewProviderProposalHandler(app.ProviderKeeper)) // Set legacy router for backwards compatibility with gov v1beta1 app.GovKeeper.SetLegacyRouter(govRouter) @@ -459,17 +504,21 @@ func New( govtypes.NewMultiGovHooks(app.ProviderKeeper.Hooks()), ) + providerModule := ibcprovider.NewAppModule(&app.ProviderKeeper, app.GetSubspace(providertypes.ModuleName)) + app.TransferKeeper = ibctransferkeeper.NewKeeper( appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName), app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper, - &app.IBCKeeper.PortKeeper, + app.IBCKeeper.PortKeeper, app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) + transferModule := transfer.NewAppModule(app.TransferKeeper) ibcmodule := transfer.NewIBCModule(app.TransferKeeper) @@ -479,16 +528,6 @@ func New( ibcRouter.AddRoute(providertypes.ModuleName, providerModule) app.IBCKeeper.SetRouter(ibcRouter) - // create evidence keeper with router - evidenceKeeper := evidencekeeper.NewKeeper( - appCodec, - keys[evidencetypes.StoreKey], - app.StakingKeeper, - app.SlashingKeeper, - ) - - app.EvidenceKeeper = *evidenceKeeper - skipGenesisInvariants := cast.ToBool(appOpts.Get(crisis.FlagSkipGenesisInvariants)) // NOTE: Any module instantiated in the module manager that is later modified @@ -497,41 +536,79 @@ func New( genutil.NewAppModule( app.AccountKeeper, app.StakingKeeper, - app.BaseApp.DeliverTx, - encodingConfig.TxConfig, + app, + txConfig, ), auth.NewAppModule(appCodec, app.AccountKeeper, nil, app.GetSubspace(authtypes.ModuleName)), vesting.NewAppModule(app.AccountKeeper, app.BankKeeper), bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName)), + consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper), capability.NewAppModule(appCodec, *app.CapabilityKeeper, false), crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)), gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(govtypes.ModuleName)), mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)), - slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName)), + slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName), app.interfaceRegistry), distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), - upgrade.NewAppModule(&app.UpgradeKeeper), + upgrade.NewAppModule(&app.UpgradeKeeper, app.AccountKeeper.AddressCodec()), evidence.NewAppModule(app.EvidenceKeeper), + ibc.NewAppModule(app.IBCKeeper), + ibctm.NewAppModule(), params.NewAppModule(app.ParamsKeeper), transferModule, providerModule, ) + // NOTE: @Msalopek -> ModuleBasic override is happening because Tx commands don't work without it + // TODO: double-check + ModuleBasics = module.NewBasicManagerFromManager( + app.MM, + map[string]module.AppModuleBasic{ + genutiltypes.ModuleName: genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator), + govtypes.ModuleName: gov.NewAppModuleBasic( + []govclient.ProposalHandler{ + paramsclient.ProposalHandler, + ibcproviderclient.ConsumerAdditionProposalHandler, + ibcproviderclient.ConsumerRemovalProposalHandler, + ibcproviderclient.ChangeRewardDenomsProposalHandler, + }, + ), + }) + ModuleBasics.RegisterLegacyAminoCodec(app.legacyAmino) + ModuleBasics.RegisterInterfaces(app.interfaceRegistry) + + enabledSignModes := append(authtx.DefaultSignModes, + sigtypes.SignMode_SIGN_MODE_TEXTUAL) + txConfigOpts := authtx.ConfigOptions{ + EnabledSignModes: enabledSignModes, + TextualCoinMetadataQueryFn: txmodule.NewBankKeeperCoinMetadataQueryFn(app.BankKeeper), + } + txConfig, err := authtx.NewTxConfigWithOptions( + appCodec, + txConfigOpts, + ) + if err != nil { + panic(err) + } + app.txConfig = txConfig + + app.MM.SetOrderPreBlockers( + upgradetypes.ModuleName, + ) + // During begin block slashing happens after distr.BeginBlocker so that // there is nothing left over in the validator fee pool, so as to keep the // CanWithdrawInvariant invariant. // NOTE: staking module is required if HistoricalEntries param > 0 // NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC) app.MM.SetOrderBeginBlockers( - // upgrades should be run first - upgradetypes.ModuleName, capabilitytypes.ModuleName, crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName, ibctransfertypes.ModuleName, - ibchost.ModuleName, + ibcexported.ModuleName, authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName, @@ -549,7 +626,7 @@ func New( govtypes.ModuleName, stakingtypes.ModuleName, ibctransfertypes.ModuleName, - ibchost.ModuleName, + ibcexported.ModuleName, capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, @@ -580,7 +657,7 @@ func New( govtypes.ModuleName, minttypes.ModuleName, crisistypes.ModuleName, - ibchost.ModuleName, + ibcexported.ModuleName, evidencetypes.ModuleName, ibctransfertypes.ModuleName, genutiltypes.ModuleName, @@ -588,64 +665,25 @@ func New( upgradetypes.ModuleName, vestingtypes.ModuleName, providertypes.ModuleName, + consensusparamtypes.ModuleName, ) app.MM.RegisterInvariants(&app.CrisisKeeper) app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) - app.MM.RegisterServices(app.configurator) - - // create the simulation manager and define the order of the modules for deterministic simulations - // - // NOTE: this is not required apps that don't use the simulator for fuzz testing - // transactions - app.sm = module.NewSimulationManager( - auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)), - bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName)), - capability.NewAppModule(appCodec, *app.CapabilityKeeper, false), - gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(govtypes.ModuleName)), - mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)), - staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), - distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), - slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName)), - params.NewAppModule(app.ParamsKeeper), - evidence.NewAppModule(app.EvidenceKeeper), - ibc.NewAppModule(app.IBCKeeper), - transferModule, - ) - - app.sm.RegisterStoreDecoders() - - // initialize stores - app.MountKVStores(keys) - app.MountTransientStores(tkeys) - app.MountMemoryStores(memKeys) - - anteHandler, err := NewAnteHandler( - HandlerOptions{ - HandlerOptions: ante.HandlerOptions{ - AccountKeeper: app.AccountKeeper, - BankKeeper: app.BankKeeper, - SignModeHandler: encodingConfig.TxConfig.SignModeHandler(), - SigGasConsumer: ante.DefaultSigVerificationGasConsumer, - }, - IBCKeeper: app.IBCKeeper, - }, - ) + err = app.MM.RegisterServices(app.configurator) if err != nil { - panic(fmt.Errorf("failed to create AnteHandler: %s", err)) + panic(err) } - app.SetAnteHandler(anteHandler) - app.SetInitChainer(app.InitChainer) - app.SetBeginBlocker(app.BeginBlocker) - app.SetEndBlocker(app.EndBlocker) + // create the simulation manager and define the order of the modules for deterministic simulations // Note this upgrade handler is just an example and may not be exactly what you need to implement. // See https://docs.cosmos.network/v0.45/building-modules/upgrade.html app.UpgradeKeeper.SetUpgradeHandler( upgradeName, - func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { - app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) + func(ctx context.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + app.IBCKeeper.ConnectionKeeper.SetParams(sdkCtx, ibcconnectiontypes.DefaultParams()) fromVM := make(map[string]uint64) @@ -656,7 +694,7 @@ func New( } } - ctx.Logger().Info("start to run module migrations...") + app.Logger().Info("start to run module migrations...") return app.MM.RunMigrations(ctx, app.configurator, fromVM) }, @@ -674,6 +712,58 @@ func New( app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) } + autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.MM.Modules)) + + reflectionSvc, err := runtimeservices.NewReflectionService() + if err != nil { + panic(err) + } + reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc) + + // add test gRPC service for testing gRPC queries in isolation + testpb.RegisterQueryServer(app.GRPCQueryRouter(), testpb.QueryImpl{}) + + // initialize stores + app.MountKVStores(keys) + app.MountTransientStores(tkeys) + app.MountMemoryStores(memKeys) + + anteHandler, err := NewAnteHandler( + HandlerOptions{ + HandlerOptions: ante.HandlerOptions{ + AccountKeeper: app.AccountKeeper, + BankKeeper: app.BankKeeper, + SignModeHandler: txConfig.SignModeHandler(), + SigGasConsumer: ante.DefaultSigVerificationGasConsumer, + }, + IBCKeeper: app.IBCKeeper, + }, + ) + if err != nil { + panic(fmt.Errorf("failed to create AnteHandler: %s", err)) + } + + app.SetInitChainer(app.InitChainer) + app.SetPreBlocker(app.PreBlocker) + app.SetBeginBlocker(app.BeginBlocker) + app.SetEndBlocker(app.EndBlocker) + app.SetAnteHandler(anteHandler) + + app.setPostHandler() + + // At startup, after all modules have been registered, check that all prot + // annotations are correct. + protoFiles, err := proto.MergedRegistry() + if err != nil { + panic(err) + } + err = msgservice.ValidateProtoAnnotations(protoFiles) + if err != nil { + // Once we switch to using protoreflect-based antehandlers, we might + // want to panic here instead of logging a warning. + fmt.Fprintln(os.Stderr, err.Error()) + } + if loadLatest { if err := app.LoadLatestVersion(); err != nil { tmos.Exit(fmt.Sprintf("failed to load latest version: %s", err)) @@ -684,32 +774,44 @@ func New( app.ScopedTransferKeeper = scopedTransferKeeper app.ScopedIBCProviderKeeper = scopedIBCProviderKeeper - autocliv1.RegisterQueryServer(app.GRPCQueryRouter(), runtimeservices.NewAutoCLIQueryService(app.MM.Modules)) + return app +} - reflectionSvc, err := runtimeservices.NewReflectionService() +// Name returns the name of the App +func (app *App) Name() string { return app.BaseApp.Name() } + +// Configurator returns the configurator for the app +func (app *App) Configurator() module.Configurator { + return app.configurator +} + +func (app *App) setPostHandler() { + postHandler, err := posthandler.NewPostHandler( + posthandler.HandlerOptions{}, + ) if err != nil { panic(err) } - reflectionv1.RegisterReflectionServiceServer(app.GRPCQueryRouter(), reflectionSvc) - return app + app.SetPostHandler(postHandler) } -// Name returns the name of the App -func (app *App) Name() string { return app.BaseApp.Name() } +func (app *App) PreBlocker(ctx sdk.Context, _ *abci.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error) { + return app.MM.PreBlock(ctx) +} // BeginBlocker application updates every begin block -func (app *App) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { - return app.MM.BeginBlock(ctx, req) +func (app *App) BeginBlocker(ctx sdk.Context) (sdk.BeginBlock, error) { + return app.MM.BeginBlock(ctx) } // EndBlocker application updates every end block -func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { - return app.MM.EndBlock(ctx, req) +func (app *App) EndBlocker(ctx sdk.Context) (sdk.EndBlock, error) { + return app.MM.EndBlock(ctx) } // InitChainer application update at chain initialization -func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { +func (app *App) InitChainer(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) { var genesisState GenesisState if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil { panic(err) @@ -854,6 +956,27 @@ func (app *App) TxConfig() client.TxConfig { return app.txConfig } +// AutoCliOpts returns the autocli options for the app. +func (app *App) AutoCliOpts() autocli.AppOptions { + modules := make(map[string]appmodule.AppModule, 0) + for _, m := range app.MM.Modules { + if moduleWithName, ok := m.(module.HasName); ok { + moduleName := moduleWithName.Name() + if appModule, ok := moduleWithName.(appmodule.AppModule); ok { + modules[moduleName] = appModule + } + } + } + + return autocli.AppOptions{ + Modules: modules, + ModuleOptions: runtimeservices.ExtractAutoCLIOptions(app.MM.Modules), + AddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), + ValidatorAddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + ConsensusAddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), + } +} + // RegisterAPIRoutes registers all application module routes with the provided // API server. func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { @@ -861,7 +984,7 @@ func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig // Register new tx routes from grpc-gateway. authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) // Register new tendermint queries routes from grpc-gateway. - tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + cmtservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) // Register node gRPC service for grpc-gateway. nodeservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) @@ -880,13 +1003,14 @@ func (app *App) RegisterTxService(clientCtx client.Context) { authtx.RegisterTxService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.BaseApp.Simulate, app.interfaceRegistry) } -func (app *App) RegisterNodeService(clientCtx client.Context) { - nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter()) +func (app *App) RegisterNodeService(clientCtx client.Context, cfg config.Config) { + nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter(), cfg) } // RegisterTendermintService implements the Application.RegisterTendermintService method. func (app *App) RegisterTendermintService(clientCtx client.Context) { - tmservice.RegisterTendermintService(clientCtx, app.BaseApp.GRPCQueryRouter(), app.interfaceRegistry, app.Query) + cmtApp := server.NewCometABCIWrapper(app) + cmtservice.RegisterTendermintService(clientCtx, app.BaseApp.GRPCQueryRouter(), app.interfaceRegistry, cmtApp.Query) } // GetMaccPerms returns a copy of the module account permissions @@ -911,25 +1035,12 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(gov.ProvideKeyTable()) paramsKeeper.Subspace(crisistypes.ModuleName) paramsKeeper.Subspace(ibctransfertypes.ModuleName) - paramsKeeper.Subspace(ibchost.ModuleName) + paramsKeeper.Subspace(ibcexported.ModuleName) paramsKeeper.Subspace(providertypes.ModuleName) return paramsKeeper } -// MakeTestEncodingConfig creates an EncodingConfig for testing. This function -// should be used only in tests or when creating a new app instance (NewApp*()). -// App user shouldn't create new codecs - use the app.AppCodec instead. -// [DEPRECATED] -// func MakeTestEncodingConfig() appparams.EncodingConfig { -// encodingConfig := appparams.MakeTestEncodingConfig() -// std.RegisterLegacyAminoCodec(encodingConfig.Amino) -// std.RegisterInterfaces(encodingConfig.InterfaceRegistry) -// ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) -// ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) -// return encodingConfig -// } - func MakeTestEncodingConfig() appencoding.EncodingConfig { encodingConfig := appencoding.MakeTestEncodingConfig() std.RegisterLegacyAminoCodec(encodingConfig.Amino) @@ -941,9 +1052,7 @@ func MakeTestEncodingConfig() appencoding.EncodingConfig { func makeEncodingConfig() appencoding.EncodingConfig { encodingConfig := appencoding.MakeTestEncodingConfig() - std.RegisterLegacyAminoCodec(encodingConfig.Amino) - std.RegisterInterfaces(encodingConfig.InterfaceRegistry) - ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) - ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) + // std.RegisterLegacyAminoCodec(encodingConfig.Amino) + // std.RegisterInterfaces(encodingConfig.InterfaceRegistry) return encodingConfig } diff --git a/app/provider/export.go b/app/provider/export.go index 74faed0657..a99ef9e83c 100644 --- a/app/provider/export.go +++ b/app/provider/export.go @@ -4,13 +4,12 @@ import ( "encoding/json" "log" + storetypes "cosmossdk.io/store/types" servertypes "github.com/cosmos/cosmos-sdk/server/types" sdk "github.com/cosmos/cosmos-sdk/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" "github.com/cosmos/cosmos-sdk/x/staking" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - - tmproto "github.com/cometbft/cometbft/proto/tendermint/types" ) // ExportAppStateAndValidators exports the state of the application for a genesis @@ -19,7 +18,7 @@ func (app *App) ExportAppStateAndValidators( forZeroHeight bool, jailAllowedAddrs, modulesToExport []string, ) (servertypes.ExportedApp, error) { // as if they could withdraw from the start of the next block - ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + ctx := app.NewContext(true) // We export at last height + 1, because that's the height at which // Tendermint will start InitChain. @@ -29,7 +28,10 @@ func (app *App) ExportAppStateAndValidators( app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs) } - genState := app.MM.ExportGenesis(ctx, app.appCodec) + genState, err := app.MM.ExportGenesis(ctx, app.appCodec) + if err != nil { + return servertypes.ExportedApp{}, err + } appState, err := json.MarshalIndent(genState, "", " ") if err != nil { return servertypes.ExportedApp{}, err @@ -76,7 +78,12 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str // withdraw all validator commission app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { - _, err := app.DistrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator()) + valAddr, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator()) + if err != nil { + panic(err) + } + + _, err = app.DistrKeeper.WithdrawValidatorCommission(ctx, valAddr) if err != nil { panic(err) } @@ -84,9 +91,23 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str }) // withdraw all delegator rewards - dels := app.StakingKeeper.GetAllDelegations(ctx) + dels, err := app.StakingKeeper.GetAllDelegations(ctx) + if err != nil { + panic(err) + } for _, delegation := range dels { - _, err := app.DistrKeeper.WithdrawDelegationRewards(ctx, delegation.GetDelegatorAddr(), delegation.GetValidatorAddr()) + // NOTE: @MSalopek this may be wrong + // TODO: add tests to figure this out (it's low impact since this is just a test app) + delAddr, err := app.AccountKeeper.AddressCodec().StringToBytes(delegation.GetDelegatorAddr()) + if err != nil { + panic(err) + } + // NOTE: @MSalopek this may be wrong -> need validator addr codec + valAddr, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(delegation.GetValidatorAddr()) + if err != nil { + panic(err) + } + _, err = app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr) if err != nil { panic(err) } @@ -105,12 +126,23 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str // reinitialize all validators app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { // donate any unwithdrawn outstanding reward fraction tokens to the community pool - scraps := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator()) - feePool := app.DistrKeeper.GetFeePool(ctx) + valAddr, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator()) + if err != nil { + panic(err) + } + + scraps, err := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, valAddr) + if err != nil { + panic(err) + } + feePool, err := app.DistrKeeper.FeePool.Get(ctx) + if err != nil { + panic(err) + } feePool.CommunityPool = feePool.CommunityPool.Add(scraps...) - app.DistrKeeper.SetFeePool(ctx, feePool) + app.DistrKeeper.FeePool.Set(ctx, feePool) - err := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()) + err = app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, valAddr) if err != nil { panic(err) } @@ -119,11 +151,19 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str // reinitialize all delegations for _, del := range dels { - err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) + delAddr, err := app.AccountKeeper.AddressCodec().StringToBytes(del.GetDelegatorAddr()) + if err != nil { + panic(err) + } + valAddr, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(del.GetValidatorAddr()) if err != nil { panic(err) } - err = app.DistrKeeper.Hooks().AfterDelegationModified(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) + err = app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr) + if err != nil { + panic(err) + } + err = app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr) if err != nil { panic(err) } @@ -155,13 +195,13 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str // Iterate through validators by power descending, reset bond heights, and // update bond intra-tx counters. store := ctx.KVStore(app.keys[stakingtypes.StoreKey]) - iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey) + iter := storetypes.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey) counter := int16(0) for ; iter.Valid(); iter.Next() { addr := sdk.ValAddress(iter.Key()[1:]) - validator, found := app.StakingKeeper.GetValidator(ctx, addr) - if !found { + validator, err := app.StakingKeeper.GetValidator(ctx, addr) + if err != nil { panic("expected validator, not found") } diff --git a/app/sovereign/Readme.md b/app/sovereign/Readme.md new file mode 100644 index 0000000000..5c50725983 --- /dev/null +++ b/app/sovereign/Readme.md @@ -0,0 +1,3 @@ +# Sovereign/Standalone chain + +Standalone simapp is modeled after the `app/consumer/app.go`. It must support all features that `app/consumer/app.go` supports so we can use it in standalone to consumer changeover procedures in our test suites. diff --git a/app/sovereign/abci.go b/app/sovereign/abci.go new file mode 100644 index 0000000000..94b34cc3bb --- /dev/null +++ b/app/sovereign/abci.go @@ -0,0 +1,84 @@ +package app + +import ( + "bytes" + "crypto/rand" + "encoding/json" + "fmt" + + abci "github.com/cometbft/cometbft/abci/types" + + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type ( + // VoteExtensionHandler defines a dummy vote extension handler for SimApp. + // + // NOTE: This implementation is solely used for testing purposes. DO NOT use + // in a production application! + VoteExtensionHandler struct{} + + // VoteExtension defines the structure used to create a dummy vote extension. + VoteExtension struct { + Hash []byte + Height int64 + Data []byte + } +) + +func NewVoteExtensionHandler() *VoteExtensionHandler { + return &VoteExtensionHandler{} +} + +func (h *VoteExtensionHandler) SetHandlers(bApp *baseapp.BaseApp) { + bApp.SetExtendVoteHandler(h.ExtendVote()) + bApp.SetVerifyVoteExtensionHandler(h.VerifyVoteExtension()) +} + +func (h *VoteExtensionHandler) ExtendVote() sdk.ExtendVoteHandler { + return func(_ sdk.Context, req *abci.RequestExtendVote) (*abci.ResponseExtendVote, error) { + buf := make([]byte, 1024) + + _, err := rand.Read(buf) + if err != nil { + return nil, fmt.Errorf("failed to generate random vote extension data: %w", err) + } + + ve := VoteExtension{ + Hash: req.Hash, + Height: req.Height, + Data: buf, + } + + bz, err := json.Marshal(ve) + if err != nil { + return nil, fmt.Errorf("failed to encode vote extension: %w", err) + } + + return &abci.ResponseExtendVote{VoteExtension: bz}, nil + } +} + +func (h *VoteExtensionHandler) VerifyVoteExtension() sdk.VerifyVoteExtensionHandler { + return func(ctx sdk.Context, req *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) { + var ve VoteExtension + + if err := json.Unmarshal(req.VoteExtension, &ve); err != nil { + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + } + + switch { + case req.Height != ve.Height: + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + + case !bytes.Equal(req.Hash, ve.Hash): + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + + case len(ve.Data) != 1024: + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + } + + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_ACCEPT}, nil + } +} diff --git a/app/sovereign/ante_handler.go b/app/sovereign/ante_handler.go index 9ba33d3264..564f96284d 100644 --- a/app/sovereign/ante_handler.go +++ b/app/sovereign/ante_handler.go @@ -1,8 +1,8 @@ package app import ( - ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante" - ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" + ibcante "github.com/cosmos/ibc-go/v8/modules/core/ante" + ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" errorsmod "cosmossdk.io/errors" diff --git a/app/sovereign/app.go b/app/sovereign/app.go index 4017ca9d4f..ae5a2a82f6 100644 --- a/app/sovereign/app.go +++ b/app/sovereign/app.go @@ -1,33 +1,43 @@ package app import ( + "context" "fmt" "io" stdlog "log" "os" "path/filepath" - "github.com/cosmos/ibc-go/v7/modules/apps/transfer" - ibctransferkeeper "github.com/cosmos/ibc-go/v7/modules/apps/transfer/keeper" - ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - ibc "github.com/cosmos/ibc-go/v7/modules/core" - ibcconnectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" - porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" - ibchost "github.com/cosmos/ibc-go/v7/modules/core/exported" - ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper" - tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctesting "github.com/cosmos/ibc-go/v7/testing" - ibctestingtypes "github.com/cosmos/ibc-go/v7/testing/types" + "github.com/cosmos/ibc-go/v8/modules/apps/transfer" + ibctransferkeeper "github.com/cosmos/ibc-go/v8/modules/apps/transfer/keeper" + ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + ibc "github.com/cosmos/ibc-go/v8/modules/core" + ibcconnectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" + ibchost "github.com/cosmos/ibc-go/v8/modules/core/exported" + ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" + ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v8/testing" + ibctestingtypes "github.com/cosmos/ibc-go/v8/testing/types" "github.com/spf13/cast" autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" - + "cosmossdk.io/client/v2/autocli" + "cosmossdk.io/core/appmodule" + + storetypes "cosmossdk.io/store/types" + "cosmossdk.io/x/evidence" + evidencekeeper "cosmossdk.io/x/evidence/keeper" + evidencetypes "cosmossdk.io/x/evidence/types" + "cosmossdk.io/x/feegrant" + feegrantkeeper "cosmossdk.io/x/feegrant/keeper" + feegrantmodule "cosmossdk.io/x/feegrant/module" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" - "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/runtime" @@ -37,12 +47,12 @@ import ( "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/std" - storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/ante" + authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -54,9 +64,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/bank" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/cosmos/cosmos-sdk/x/capability" - capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" "github.com/cosmos/cosmos-sdk/x/consensus" consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" @@ -66,12 +73,6 @@ import ( sdkdistr "github.com/cosmos/cosmos-sdk/x/distribution" distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - "github.com/cosmos/cosmos-sdk/x/evidence" - evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" - "github.com/cosmos/cosmos-sdk/x/feegrant" - feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper" - feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" sdkgov "github.com/cosmos/cosmos-sdk/x/gov" @@ -79,8 +80,14 @@ import ( govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + "github.com/cosmos/ibc-go/modules/capability" + capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" // add mint + "cosmossdk.io/x/upgrade" + upgradekeeper "cosmossdk.io/x/upgrade/keeper" + upgradetypes "cosmossdk.io/x/upgrade/types" mint "github.com/cosmos/cosmos-sdk/x/mint" mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" @@ -95,25 +102,21 @@ import ( sdkstaking "github.com/cosmos/cosmos-sdk/x/staking" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/cosmos/cosmos-sdk/x/upgrade" - upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client" - upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" - upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - dbm "github.com/cometbft/cometbft-db" + "cosmossdk.io/log" abci "github.com/cometbft/cometbft/abci/types" tmjson "github.com/cometbft/cometbft/libs/json" - "github.com/cometbft/cometbft/libs/log" tmos "github.com/cometbft/cometbft/libs/os" + dbm "github.com/cosmos/cosmos-db" - appencoding "github.com/cosmos/interchain-security/v4/app/encoding" - testutil "github.com/cosmos/interchain-security/v4/testutil/integration" + appencoding "github.com/cosmos/interchain-security/v5/app/encoding" + testutil "github.com/cosmos/interchain-security/v5/testutil/integration" ) const ( AppName = "interchain-security-s" upgradeName = "v07-Theta" // arbitrary name, define your own appropriately named upgrade - AccountAddressPrefix = "consumer" + AccountAddressPrefix = "cosmos" ) var ( @@ -134,8 +137,6 @@ var ( sdkgov.NewAppModuleBasic( []govclient.ProposalHandler{ paramsclient.ProposalHandler, - upgradeclient.LegacyProposalHandler, - upgradeclient.LegacyCancelProposalHandler, }, ), params.AppModuleBasic{}, @@ -148,7 +149,7 @@ var ( evidence.AppModuleBasic{}, transfer.AppModuleBasic{}, vesting.AppModuleBasic{}, - tendermint.AppModuleBasic{}, + ibctm.AppModuleBasic{}, consensus.AppModuleBasic{}, ) @@ -241,21 +242,29 @@ func New( appCodec := encodingConfig.Codec legacyAmino := encodingConfig.Amino interfaceRegistry := encodingConfig.InterfaceRegistry + txConfig := encodingConfig.TxConfig + + // ABCI++, v50 + voteExtOp := func(bApp *baseapp.BaseApp) { + voteExtHandler := NewVoteExtensionHandler() + voteExtHandler.SetHandlers(bApp) + } + baseAppOptions = append(baseAppOptions, voteExtOp) bApp := baseapp.NewBaseApp(AppName, logger, db, encodingConfig.TxConfig.TxDecoder(), baseAppOptions...) bApp.SetCommitMultiStoreTracer(traceStore) bApp.SetVersion(version.Version) bApp.SetInterfaceRegistry(interfaceRegistry) - keys := sdk.NewKVStoreKeys( + keys := storetypes.NewKVStoreKeys( authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, crisistypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, authzkeeper.StoreKey, consensusparamtypes.StoreKey, ) - tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) - memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) + tkeys := storetypes.NewTransientStoreKeys(paramstypes.TStoreKey) + memKeys := storetypes.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) app := &App{ BaseApp: bApp, @@ -265,7 +274,7 @@ func New( keys: keys, tkeys: tkeys, memKeys: memKeys, - txConfig: encodingConfig.TxConfig, + txConfig: txConfig, } app.ParamsKeeper = initParamsKeeper( @@ -276,9 +285,8 @@ func New( ) // set the BaseApp's parameter store - // upgradetypes.StoreKey -> maybe consensusparamtypes.StoreKey (package consensusparamtypes ("github.com/cosmos/cosmos-sdk/x/consensus/types") - app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, keys[upgradetypes.StoreKey], authtypes.NewModuleAddress(govtypes.ModuleName).String()) - bApp.SetParamStore(&app.ConsensusParamsKeeper) + app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[consensusparamtypes.StoreKey]), authtypes.NewModuleAddress(govtypes.ModuleName).String(), runtime.EventService{}) + bApp.SetParamStore(&app.ConsensusParamsKeeper.ParamsStore) // add capability keeper and ScopeToModule for ibc module app.CapabilityKeeper = capabilitykeeper.NewKeeper( @@ -293,10 +301,11 @@ func New( // add keepers app.AccountKeeper = authkeeper.NewAccountKeeper( appCodec, - keys[authtypes.StoreKey], + runtime.NewKVStoreService(keys[authtypes.StoreKey]), authtypes.ProtoBaseAccount, maccPerms, - AccountAddressPrefix, + authcodec.NewBech32Codec(sdk.Bech32MainPrefix), + sdk.Bech32MainPrefix, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) @@ -304,34 +313,38 @@ func New( app.BankKeeper = bankkeeper.NewBaseKeeper( appCodec, - keys[banktypes.StoreKey], + runtime.NewKVStoreService(keys[banktypes.StoreKey]), app.AccountKeeper, bankBlockedAddrs, authtypes.NewModuleAddress(govtypes.ModuleName).String(), + logger, ) app.AuthzKeeper = authzkeeper.NewKeeper( - keys[authzkeeper.StoreKey], + runtime.NewKVStoreService(keys[authzkeeper.StoreKey]), appCodec, - app.BaseApp.MsgServiceRouter(), + app.MsgServiceRouter(), app.AccountKeeper, ) + app.FeeGrantKeeper = feegrantkeeper.NewKeeper( appCodec, - keys[feegrant.StoreKey], + runtime.NewKVStoreService(keys[feegrant.StoreKey]), app.AccountKeeper, ) app.StakingKeeper = *stakingkeeper.NewKeeper( appCodec, - keys[stakingtypes.StoreKey], + runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), + authcodec.NewBech32Codec(sdk.Bech32PrefixValAddr), + authcodec.NewBech32Codec(sdk.Bech32PrefixConsAddr), ) app.MintKeeper = mintkeeper.NewKeeper( appCodec, - keys[minttypes.StoreKey], + runtime.NewKVStoreService(keys[minttypes.StoreKey]), app.StakingKeeper, app.AccountKeeper, app.BankKeeper, @@ -342,14 +355,14 @@ func New( app.SlashingKeeper = slashingkeeper.NewKeeper( appCodec, legacyAmino, - keys[slashingtypes.StoreKey], + runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), app.StakingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) app.DistrKeeper = distrkeeper.NewKeeper( appCodec, - keys[distrtypes.StoreKey], + runtime.NewKVStoreService(keys[distrtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, app.StakingKeeper, @@ -360,11 +373,12 @@ func New( invCheckPeriod := cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)) app.CrisisKeeper = *crisiskeeper.NewKeeper( appCodec, - keys[crisistypes.StoreKey], + runtime.NewKVStoreService(keys[crisistypes.StoreKey]), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String(), + app.AccountKeeper.AddressCodec(), ) // get skipUpgradeHeights from the app options @@ -375,7 +389,7 @@ func New( homePath := cast.ToString(appOpts.Get(flags.FlagHome)) app.UpgradeKeeper = *upgradekeeper.NewKeeper( skipUpgradeHeights, - keys[upgradetypes.StoreKey], + runtime.NewKVStoreService(keys[upgradetypes.StoreKey]), appCodec, homePath, app.BaseApp, @@ -395,16 +409,16 @@ func New( sdkgovRouter := govv1beta1.NewRouter() sdkgovRouter. AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler). - AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). - AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(&app.UpgradeKeeper)) + AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)) govConfig := govtypes.DefaultConfig() app.GovKeeper = *govkeeper.NewKeeper( appCodec, - keys[govtypes.StoreKey], + runtime.NewKVStoreService(keys[govtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, app.StakingKeeper, + app.DistrKeeper, app.MsgServiceRouter(), govConfig, authtypes.NewModuleAddress(govtypes.ModuleName).String(), @@ -419,12 +433,13 @@ func New( &app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) app.SlashingKeeper = slashingkeeper.NewKeeper( appCodec, legacyAmino, - keys[slashingtypes.StoreKey], + runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), app.StakingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) @@ -435,10 +450,11 @@ func New( app.GetSubspace(ibctransfertypes.ModuleName), app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper, - &app.IBCKeeper.PortKeeper, + app.IBCKeeper.PortKeeper, app.AccountKeeper, app.BankKeeper, scopedTransferKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) transferModule := transfer.NewAppModule(app.TransferKeeper) ibcmodule := transfer.NewIBCModule(app.TransferKeeper) @@ -451,9 +467,11 @@ func New( // create evidence keeper with router evidenceKeeper := evidencekeeper.NewKeeper( appCodec, - keys[evidencetypes.StoreKey], + runtime.NewKVStoreService(keys[evidencetypes.StoreKey]), &app.StakingKeeper, app.SlashingKeeper, + app.AccountKeeper.AddressCodec(), + runtime.ProvideCometInfoService(), ) app.EvidenceKeeper = *evidenceKeeper @@ -466,7 +484,7 @@ func New( genutil.NewAppModule( app.AccountKeeper, app.StakingKeeper, - app.BaseApp.DeliverTx, + app, encodingConfig.TxConfig, ), auth.NewAppModule(appCodec, app.AccountKeeper, nil, app.GetSubspace(authtypes.ModuleName)), @@ -477,10 +495,10 @@ func New( feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry), sdkgov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(govtypes.ModuleName)), mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)), - slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName)), + slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName), app.interfaceRegistry), sdkdistr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), sdkstaking.NewAppModule(appCodec, &app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), - upgrade.NewAppModule(&app.UpgradeKeeper), + upgrade.NewAppModule(&app.UpgradeKeeper, app.AccountKeeper.AddressCodec()), evidence.NewAppModule(app.EvidenceKeeper), params.NewAppModule(app.ParamsKeeper), authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), @@ -589,9 +607,9 @@ func New( app.UpgradeKeeper.SetUpgradeHandler( upgradeName, - func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { - app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) - + func(ctx context.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + app.IBCKeeper.ConnectionKeeper.SetParams(sdkCtx, ibcconnectiontypes.DefaultParams()) fromVM := make(map[string]uint64) for moduleName := range app.MM.Modules { @@ -601,7 +619,7 @@ func New( } } - ctx.Logger().Info("start to run module migrations...") + app.Logger().Info("start to run module migrations...") return app.MM.RunMigrations(ctx, app.configurator, fromVM) }, @@ -640,18 +658,22 @@ func New( // Name returns the name of the App func (app *App) Name() string { return app.BaseApp.Name() } +func (app *App) PreBlocker(ctx sdk.Context, _ *abci.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error) { + return app.MM.PreBlock(ctx) +} + // BeginBlocker application updates every begin block -func (app *App) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { - return app.MM.BeginBlock(ctx, req) +func (app *App) BeginBlocker(ctx sdk.Context) (sdk.BeginBlock, error) { + return app.MM.BeginBlock(ctx) } // EndBlocker application updates every end block -func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { - return app.MM.EndBlock(ctx, req) +func (app *App) EndBlocker(ctx sdk.Context) (sdk.EndBlock, error) { + return app.MM.EndBlock(ctx) } // InitChainer application update at chain initialization -func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { +func (app *App) InitChainer(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) { var genesisState GenesisState if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil { panic(err) @@ -743,7 +765,7 @@ func (app *App) GetTestSlashingKeeper() testutil.TestSlashingKeeper { return app.SlashingKeeper } -func (app *App) GetTestEvidenceKeeper() testutil.TestEvidenceKeeper { +func (app *App) GetTestEvidenceKeeper() evidencekeeper.Keeper { return app.EvidenceKeeper } @@ -755,11 +777,11 @@ func (app *App) GetTestDistributionKeeper() testutil.TestDistributionKeeper { return app.DistrKeeper } -func (app *App) GetTestMintKeeper() testutil.TestMintKeeper { +func (app *App) GetTestMintKeeper() mintkeeper.Keeper { return app.MintKeeper } -func (app *App) GetTestGovKeeper() testutil.TestGovKeeper { +func (app *App) GetTestGovKeeper() govkeeper.Keeper { return app.GovKeeper } @@ -795,23 +817,51 @@ func (app *App) TxConfig() client.TxConfig { return app.txConfig } +// AutoCliOpts returns the autocli options for the app. +func (app *App) AutoCliOpts() autocli.AppOptions { + modules := make(map[string]appmodule.AppModule, 0) + for _, m := range app.MM.Modules { + if moduleWithName, ok := m.(module.HasName); ok { + moduleName := moduleWithName.Name() + if appModule, ok := moduleWithName.(appmodule.AppModule); ok { + modules[moduleName] = appModule + } + } + } + + return autocli.AppOptions{ + Modules: modules, + ModuleOptions: runtimeservices.ExtractAutoCLIOptions(app.MM.Modules), + AddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), + ValidatorAddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + ConsensusAddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), + } +} + // RegisterAPIRoutes registers all application module routes with the provided // API server. func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) { clientCtx := apiSvr.ClientCtx // Register new tx routes from grpc-gateway. authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) - // Register new tendermint queries routes from grpc-gateway. - tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + + // Register new CometBFT queries routes from grpc-gateway. + cmtservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + // Register node gRPC service for grpc-gateway. nodeservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) - // Register legacy and grpc-gateway routes for all modules. + // Register grpc-gateway routes for all modules. ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter) + + // register swagger API from root so that other applications can override easily + if err := server.RegisterSwaggerAPI(apiSvr.ClientCtx, apiSvr.Router, apiConfig.Swagger); err != nil { + panic(err) + } } -func (app *App) RegisterNodeService(clientCtx client.Context) { - nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter()) +func (app *App) RegisterNodeService(clientCtx client.Context, cfg config.Config) { + nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter(), cfg) } // RegisterTxService implements the Application.RegisterTxService method. @@ -821,7 +871,8 @@ func (app *App) RegisterTxService(clientCtx client.Context) { // RegisterTendermintService implements the Application.RegisterTendermintService method. func (app *App) RegisterTendermintService(clientCtx client.Context) { - tmservice.RegisterTendermintService(clientCtx, app.BaseApp.GRPCQueryRouter(), app.interfaceRegistry, app.Query) + cmtApp := server.NewCometABCIWrapper(app) + cmtservice.RegisterTendermintService(clientCtx, app.BaseApp.GRPCQueryRouter(), app.interfaceRegistry, cmtApp.Query) } // GetMaccPerms returns a copy of the module account permissions @@ -851,19 +902,6 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino return paramsKeeper } -// MakeTestEncodingConfig creates an EncodingConfig for testing. This function -// should be used only in tests or when creating a new app instance (NewApp*()). -// App user shouldn't create new codecs - use the app.AppCodec instead. -// [DEPRECATED] -// func MakeTestEncodingConfig() appparams.EncodingConfig { -// encodingConfig := appparams.MakeTestEncodingConfig() -// std.RegisterLegacyAminoCodec(encodingConfig.Amino) -// std.RegisterInterfaces(encodingConfig.InterfaceRegistry) -// ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) -// ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) -// return encodingConfig -// } - func MakeTestEncodingConfig() appencoding.EncodingConfig { encodingConfig := appencoding.MakeTestEncodingConfig() std.RegisterLegacyAminoCodec(encodingConfig.Amino) diff --git a/app/sovereign/export.go b/app/sovereign/export.go index 93d46bf973..53e9f6fee1 100644 --- a/app/sovereign/export.go +++ b/app/sovereign/export.go @@ -2,15 +2,16 @@ package app import ( "encoding/json" + "errors" "log" + storetypes "cosmossdk.io/store/types" servertypes "github.com/cosmos/cosmos-sdk/server/types" sdk "github.com/cosmos/cosmos-sdk/types" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" "github.com/cosmos/cosmos-sdk/x/staking" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - - tmproto "github.com/cometbft/cometbft/proto/tendermint/types" ) // ExportAppStateAndValidators exports the state of the application for a genesis @@ -19,7 +20,7 @@ func (app *App) ExportAppStateAndValidators( forZeroHeight bool, jailAllowedAddrs, modulesToExport []string, ) (servertypes.ExportedApp, error) { // as if they could withdraw from the start of the next block - ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + ctx := app.NewContext(true) // We export at last height + 1, because that's the height at which // Tendermint will start InitChain. @@ -29,7 +30,10 @@ func (app *App) ExportAppStateAndValidators( app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs) } - genState := app.MM.ExportGenesis(ctx, app.appCodec) + genState, err := app.MM.ExportGenesis(ctx, app.appCodec) + if err != nil { + return servertypes.ExportedApp{}, err + } appState, err := json.MarshalIndent(genState, "", " ") if err != nil { return servertypes.ExportedApp{}, err @@ -76,20 +80,31 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str // withdraw all validator commission app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { - _, err := app.DistrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator()) + valBz, err := app.StakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator()) + if err != nil { panic(err) } + _, _ = app.DistrKeeper.WithdrawValidatorCommission(ctx, valBz) return false }) // withdraw all delegator rewards - dels := app.StakingKeeper.GetAllDelegations(ctx) + dels, err := app.StakingKeeper.GetAllDelegations(ctx) + if err != nil { + panic(err) + } for _, delegation := range dels { - _, err := app.DistrKeeper.WithdrawDelegationRewards(ctx, delegation.GetDelegatorAddr(), delegation.GetValidatorAddr()) + valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress) if err != nil { panic(err) } + + delAddr, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress) + if err != nil { + panic(err) + } + _, _ = app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr) } // clear validator slash events @@ -103,27 +118,49 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str ctx = ctx.WithBlockHeight(0) // reinitialize all validators - app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { + err = app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) { + valBz, err := sdk.ValAddressFromBech32(val.GetOperator()) + if err != nil { + panic(err) + } // donate any unwithdrawn outstanding reward fraction tokens to the community pool - scraps := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator()) - feePool := app.DistrKeeper.GetFeePool(ctx) + scraps, err := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, valBz) + if err != nil { + panic(err) + } + feePool, err := app.DistrKeeper.FeePool.Get(ctx) + if err != nil { + panic(err) + } feePool.CommunityPool = feePool.CommunityPool.Add(scraps...) - app.DistrKeeper.SetFeePool(ctx, feePool) + if err := app.DistrKeeper.FeePool.Set(ctx, feePool); err != nil { + panic(err) + } - err := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()) - if err != nil { + if err := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, valBz); err != nil { panic(err) } return false }) + if err != nil { + panic(err) + } // reinitialize all delegations for _, del := range dels { - err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) + valAddr, err := sdk.ValAddressFromBech32(del.ValidatorAddress) + if err != nil { + panic(err) + } + delAddr, err := sdk.AccAddressFromBech32(del.DelegatorAddress) if err != nil { panic(err) } - err = app.DistrKeeper.Hooks().AfterDelegationModified(ctx, del.GetDelegatorAddr(), del.GetValidatorAddr()) + err = app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr) + if err != nil { + panic(err) + } + err = app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr) if err != nil { panic(err) } @@ -155,14 +192,14 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str // Iterate through validators by power descending, reset bond heights, and // update bond intra-tx counters. store := ctx.KVStore(app.keys[stakingtypes.StoreKey]) - iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey) + iter := storetypes.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey) counter := int16(0) for ; iter.Valid(); iter.Next() { addr := sdk.ValAddress(iter.Key()[1:]) - validator, found := app.StakingKeeper.GetValidator(ctx, addr) - if !found { - panic("expected validator, not found") + validator, err := app.StakingKeeper.GetValidator(ctx, addr) + if err != nil { + panic(errors.New("expected validator, not found")) } validator.UnbondingHeight = 0 diff --git a/cmd/interchain-security-cd/cmd/root.go b/cmd/interchain-security-cd/cmd/root.go index 215b45317a..0a980f3452 100644 --- a/cmd/interchain-security-cd/cmd/root.go +++ b/cmd/interchain-security-cd/cmd/root.go @@ -8,8 +8,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - rosettaCmd "cosmossdk.io/tools/rosetta/cmd" - + "cosmossdk.io/client/v2/autocli" + confixcmd "cosmossdk.io/tools/confix/cmd" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/config" "github.com/cosmos/cosmos-sdk/client/debug" @@ -17,6 +17,8 @@ import ( "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/client/pruning" "github.com/cosmos/cosmos-sdk/client/rpc" + addresscodec "github.com/cosmos/cosmos-sdk/codec/address" + "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/server" serverconfig "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" @@ -27,12 +29,12 @@ import ( "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" - dbm "github.com/cometbft/cometbft-db" + "cosmossdk.io/log" tmcfg "github.com/cometbft/cometbft/config" - "github.com/cometbft/cometbft/libs/log" + dbm "github.com/cosmos/cosmos-db" - consumer "github.com/cosmos/interchain-security/v4/app/consumer" - appencoding "github.com/cosmos/interchain-security/v4/app/encoding" + consumer "github.com/cosmos/interchain-security/v5/app/consumer" + appencoding "github.com/cosmos/interchain-security/v5/app/encoding" ) // NewRootCmd creates a new root command for simd. It is called once in the @@ -87,10 +89,38 @@ func NewRootCmd() *cobra.Command { } initRootCmd(rootCmd, encodingConfig) + autoCliOpts, err := enrichAutoCliOpts(tempApp.AutoCliOpts(), initClientCtx) + if err != nil { + panic(err) + } + + if err := autoCliOpts.EnhanceRootCommand(rootCmd); err != nil { + panic(err) + } return rootCmd } +func enrichAutoCliOpts(autoCliOpts autocli.AppOptions, clientCtx client.Context) (autocli.AppOptions, error) { + autoCliOpts.AddressCodec = addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()) + autoCliOpts.ValidatorAddressCodec = addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()) + autoCliOpts.ConsensusAddressCodec = addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()) + + var err error + clientCtx, err = config.ReadFromClientConfig(clientCtx) + if err != nil { + return autocli.AppOptions{}, err + } + + autoCliOpts.ClientCtx = clientCtx + autoCliOpts.Keyring, err = keyring.NewAutoCLIKeyring(clientCtx.Keyring) + if err != nil { + return autocli.AppOptions{}, err + } + + return autoCliOpts, nil +} + // initTendermintConfig helps to override default Tendermint Config values. // return tmcfg.DefaultConfig if no custom configuration is required for the application. func initTendermintConfig() *tmcfg.Config { @@ -121,11 +151,8 @@ func txCommand() *cobra.Command { authcmd.GetBroadcastCommand(), authcmd.GetEncodeCommand(), authcmd.GetDecodeCommand(), - authcmd.GetAuxToFeeCommand(), ) - consumer.ModuleBasics.AddTxCommands(cmd) - return cmd } @@ -187,29 +214,23 @@ lru_size = 0` } func initRootCmd(rootCmd *cobra.Command, encodingConfig appencoding.EncodingConfig) { - cfg := sdk.GetConfig() - cfg.Seal() - rootCmd.AddCommand( genutilcli.InitCmd(consumer.ModuleBasics, consumer.DefaultNodeHome), debug.Cmd(), - config.Cmd(), - pruning.PruningCmd(newApp), + pruning.Cmd(newApp, consumer.DefaultNodeHome), + confixcmd.ConfigCommand(), ) server.AddCommands(rootCmd, consumer.DefaultNodeHome, newApp, appExport, addModuleInitFlags) // add keybase, auxiliary RPC, query, genesis, and tx child commands rootCmd.AddCommand( - rpc.StatusCommand(), + server.StatusCommand(), genesisCommand(encodingConfig, consumer.GetConsumerGenesisTransformCmd()), queryCommand(), txCommand(), - keys.Commands(consumer.DefaultNodeHome), + keys.Commands(), ) - - // add rosetta - rootCmd.AddCommand(rosettaCmd.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Codec)) } // newApp is an appCreator @@ -296,16 +317,16 @@ func queryCommand() *cobra.Command { } cmd.AddCommand( - authcmd.GetAccountCmd(), rpc.ValidatorCommand(), - rpc.BlockCommand(), + server.QueryBlockCmd(), + server.QueryBlocksCmd(), + server.QueryBlockResultsCmd(), authcmd.QueryTxsByEventsCmd(), authcmd.QueryTxCmd(), authcmd.GetEncodeCommand(), authcmd.GetDecodeCommand(), + authcmd.GetSimulateCmd(), ) - consumer.ModuleBasics.AddQueryCommands(cmd) - return cmd } diff --git a/cmd/interchain-security-cd/main.go b/cmd/interchain-security-cd/main.go index a64a2a8645..6b36b93859 100644 --- a/cmd/interchain-security-cd/main.go +++ b/cmd/interchain-security-cd/main.go @@ -1,26 +1,23 @@ package main import ( + "fmt" "os" - "github.com/cosmos/cosmos-sdk/server" svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" - app "github.com/cosmos/interchain-security/v4/app/consumer" - appparams "github.com/cosmos/interchain-security/v4/app/params" - "github.com/cosmos/interchain-security/v4/cmd/interchain-security-cd/cmd" + app "github.com/cosmos/interchain-security/v5/app/consumer" + appparams "github.com/cosmos/interchain-security/v5/app/params" + "github.com/cosmos/interchain-security/v5/cmd/interchain-security-cd/cmd" ) func main() { - appparams.SetAddressPrefixes("consumer") + appparams.SetAddressPrefixes(app.Bech32MainPrefix) + rootCmd := cmd.NewRootCmd() - if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { - switch e := err.(type) { - case server.ErrorCode: - os.Exit(e.Code) - default: - os.Exit(1) - } + if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { + fmt.Fprintln(rootCmd.OutOrStderr(), err) + os.Exit(1) } } diff --git a/cmd/interchain-security-cdd/cmd/root.go b/cmd/interchain-security-cdd/cmd/root.go index 6b2e6cc726..b71e1422c1 100644 --- a/cmd/interchain-security-cdd/cmd/root.go +++ b/cmd/interchain-security-cdd/cmd/root.go @@ -8,8 +8,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - rosettaCmd "cosmossdk.io/tools/rosetta/cmd" - + "cosmossdk.io/client/v2/autocli" + confixcmd "cosmossdk.io/tools/confix/cmd" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/config" "github.com/cosmos/cosmos-sdk/client/debug" @@ -17,22 +17,28 @@ import ( "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/client/pruning" "github.com/cosmos/cosmos-sdk/client/rpc" + "github.com/cosmos/cosmos-sdk/codec" + addresscodec "github.com/cosmos/cosmos-sdk/codec/address" + "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/server" serverconfig "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + "github.com/cosmos/cosmos-sdk/x/auth/tx" + txmodule "github.com/cosmos/cosmos-sdk/x/auth/tx/config" "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" - dbm "github.com/cometbft/cometbft-db" + "cosmossdk.io/log" tmcfg "github.com/cometbft/cometbft/config" - "github.com/cometbft/cometbft/libs/log" + dbm "github.com/cosmos/cosmos-db" - cdd "github.com/cosmos/interchain-security/v4/app/consumer-democracy" - appencoding "github.com/cosmos/interchain-security/v4/app/encoding" + cdd "github.com/cosmos/interchain-security/v5/app/consumer-democracy" + appencoding "github.com/cosmos/interchain-security/v5/app/encoding" ) // NewRootCmd creates a new root command for simd. It is called once in the @@ -75,6 +81,24 @@ func NewRootCmd() *cobra.Command { return err } + // This needs to go after ReadFromClientConfig, as that function + // sets the RPC client needed for SIGN_MODE_TEXTUAL. This sign mode + // is only available if the client is online. + if !initClientCtx.Offline { + txConfigOpts := tx.ConfigOptions{ + EnabledSignModes: append(tx.DefaultSignModes, signing.SignMode_SIGN_MODE_TEXTUAL), + TextualCoinMetadataQueryFn: txmodule.NewGRPCCoinMetadataQueryFn(initClientCtx), + } + txConfigWithTextual, err := tx.NewTxConfigWithOptions( + codec.NewProtoCodec(encodingConfig.InterfaceRegistry), + txConfigOpts, + ) + if err != nil { + return err + } + initClientCtx = initClientCtx.WithTxConfig(txConfigWithTextual) + } + if err := client.SetCmdClientContextHandler(initClientCtx, cmd); err != nil { return err } @@ -87,10 +111,38 @@ func NewRootCmd() *cobra.Command { } initRootCmd(rootCmd, encodingConfig) + autoCliOpts, err := enrichAutoCliOpts(tempApp.AutoCliOpts(), initClientCtx) + if err != nil { + panic(err) + } + + if err := autoCliOpts.EnhanceRootCommand(rootCmd); err != nil { + panic(err) + } return rootCmd } +func enrichAutoCliOpts(autoCliOpts autocli.AppOptions, clientCtx client.Context) (autocli.AppOptions, error) { + autoCliOpts.AddressCodec = addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()) + autoCliOpts.ValidatorAddressCodec = addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()) + autoCliOpts.ConsensusAddressCodec = addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()) + + var err error + clientCtx, err = config.ReadFromClientConfig(clientCtx) + if err != nil { + return autocli.AppOptions{}, err + } + + autoCliOpts.ClientCtx = clientCtx + autoCliOpts.Keyring, err = keyring.NewAutoCLIKeyring(clientCtx.Keyring) + if err != nil { + return autocli.AppOptions{}, err + } + + return autoCliOpts, nil +} + // initTendermintConfig helps to override default Tendermint Config values. // return tmcfg.DefaultConfig if no custom configuration is required for the application. func initTendermintConfig() *tmcfg.Config { @@ -121,11 +173,8 @@ func txCommand() *cobra.Command { authcmd.GetBroadcastCommand(), authcmd.GetEncodeCommand(), authcmd.GetDecodeCommand(), - authcmd.GetAuxToFeeCommand(), ) - cdd.ModuleBasics.AddTxCommands(cmd) - return cmd } @@ -187,29 +236,23 @@ lru_size = 0` } func initRootCmd(rootCmd *cobra.Command, encodingConfig appencoding.EncodingConfig) { - cfg := sdk.GetConfig() - cfg.Seal() - rootCmd.AddCommand( genutilcli.InitCmd(cdd.ModuleBasics, cdd.DefaultNodeHome), debug.Cmd(), - config.Cmd(), - pruning.PruningCmd(newApp), + pruning.Cmd(newApp, cdd.DefaultNodeHome), + confixcmd.ConfigCommand(), ) server.AddCommands(rootCmd, cdd.DefaultNodeHome, newApp, appExport, addModuleInitFlags) // add keybase, auxiliary RPC, query, genesis, and tx child commands rootCmd.AddCommand( - rpc.StatusCommand(), + server.StatusCommand(), genesisCommand(encodingConfig), queryCommand(), txCommand(), - keys.Commands(cdd.DefaultNodeHome), + keys.Commands(), ) - - // add rosetta - rootCmd.AddCommand(rosettaCmd.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Codec)) } // newApp is an appCreator @@ -296,14 +339,16 @@ func queryCommand() *cobra.Command { } cmd.AddCommand( - authcmd.GetAccountCmd(), rpc.ValidatorCommand(), - rpc.BlockCommand(), + server.QueryBlockCmd(), + server.QueryBlocksCmd(), + server.QueryBlockResultsCmd(), authcmd.QueryTxsByEventsCmd(), authcmd.QueryTxCmd(), + authcmd.GetEncodeCommand(), + authcmd.GetDecodeCommand(), + authcmd.GetSimulateCmd(), ) - cdd.ModuleBasics.AddQueryCommands(cmd) - return cmd } diff --git a/cmd/interchain-security-cdd/main.go b/cmd/interchain-security-cdd/main.go index 9b6aacd759..d6a5d29d22 100644 --- a/cmd/interchain-security-cdd/main.go +++ b/cmd/interchain-security-cdd/main.go @@ -1,26 +1,23 @@ package main import ( + "fmt" "os" - "github.com/cosmos/cosmos-sdk/server" svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" - app "github.com/cosmos/interchain-security/v4/app/consumer-democracy" - appparams "github.com/cosmos/interchain-security/v4/app/params" - "github.com/cosmos/interchain-security/v4/cmd/interchain-security-cdd/cmd" + app "github.com/cosmos/interchain-security/v5/app/consumer-democracy" + appparams "github.com/cosmos/interchain-security/v5/app/params" + "github.com/cosmos/interchain-security/v5/cmd/interchain-security-cdd/cmd" ) func main() { - appparams.SetAddressPrefixes("consumer") + appparams.SetAddressPrefixes(app.Bech32MainPrefix) + rootCmd := cmd.NewRootCmd() - if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { - switch e := err.(type) { - case server.ErrorCode: - os.Exit(e.Code) - default: - os.Exit(1) - } + if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { + fmt.Fprintln(rootCmd.OutOrStderr(), err) + os.Exit(1) } } diff --git a/cmd/interchain-security-pd/cmd/root.go b/cmd/interchain-security-pd/cmd/root.go index 8a8f5fec32..da0d719981 100644 --- a/cmd/interchain-security-pd/cmd/root.go +++ b/cmd/interchain-security-pd/cmd/root.go @@ -8,8 +8,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - rosettaCmd "cosmossdk.io/tools/rosetta/cmd" - + "cosmossdk.io/client/v2/autocli" + confixcmd "cosmossdk.io/tools/confix/cmd" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/config" "github.com/cosmos/cosmos-sdk/client/debug" @@ -17,30 +17,36 @@ import ( "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/client/pruning" "github.com/cosmos/cosmos-sdk/client/rpc" + "github.com/cosmos/cosmos-sdk/codec" + addresscodec "github.com/cosmos/cosmos-sdk/codec/address" + "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/server" serverconfig "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + "github.com/cosmos/cosmos-sdk/x/auth/tx" + txmodule "github.com/cosmos/cosmos-sdk/x/auth/tx/config" "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" - dbm "github.com/cometbft/cometbft-db" - tmcfg "github.com/cometbft/cometbft/config" - "github.com/cometbft/cometbft/libs/log" + "cosmossdk.io/log" + cmtcfg "github.com/cometbft/cometbft/config" + dbm "github.com/cosmos/cosmos-db" - appencoding "github.com/cosmos/interchain-security/v4/app/encoding" - providerApp "github.com/cosmos/interchain-security/v4/app/provider" + appEncoding "github.com/cosmos/interchain-security/v5/app/encoding" + providerApp "github.com/cosmos/interchain-security/v5/app/provider" ) // NewRootCmd creates a new root command for simd. It is called once in the // main function. func NewRootCmd() *cobra.Command { // we "pre"-instantiate the application for getting the injected/configured encoding configuration - tempApp := providerApp.New(log.NewNopLogger(), dbm.NewMemDB(), nil, true, simtestutil.NewAppOptionsWithFlagHome(providerApp.DefaultNodeHome)) - encodingConfig := appencoding.EncodingConfig{ + tempApp := providerApp.New(log.NewNopLogger(), dbm.NewMemDB(), nil, true, simtestutil.NewAppOptionsWithFlagHome(tempDir())) + encodingConfig := appEncoding.EncodingConfig{ InterfaceRegistry: tempApp.InterfaceRegistry(), Codec: tempApp.AppCodec(), TxConfig: tempApp.TxConfig(), @@ -50,7 +56,6 @@ func NewRootCmd() *cobra.Command { initClientCtx := client.Context{}. WithCodec(encodingConfig.Codec). WithInterfaceRegistry(encodingConfig.InterfaceRegistry). - WithTxConfig(encodingConfig.TxConfig). WithLegacyAmino(encodingConfig.Amino). WithInput(os.Stdin). WithAccountRetriever(types.AccountRetriever{}). @@ -58,13 +63,15 @@ func NewRootCmd() *cobra.Command { WithViper("") // In simapp, we don't use any prefix for env variables. rootCmd := &cobra.Command{ - Use: "simd", - Short: "simulation app", + Use: "simd", + Short: "simulation app", + SilenceErrors: true, PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { // set the default command outputs cmd.SetOut(cmd.OutOrStdout()) cmd.SetErr(cmd.ErrOrStderr()) + initClientCtx = initClientCtx.WithCmdContext(cmd.Context()) initClientCtx, err := client.ReadPersistentCommandFlags(initClientCtx, cmd.Flags()) if err != nil { return err @@ -75,58 +82,78 @@ func NewRootCmd() *cobra.Command { return err } + // This needs to go after ReadFromClientConfig, as that function + // sets the RPC client needed for SIGN_MODE_TEXTUAL. This sign mode + // is only available if the client is online. + if !initClientCtx.Offline { + txConfigOpts := tx.ConfigOptions{ + EnabledSignModes: append(tx.DefaultSignModes, signing.SignMode_SIGN_MODE_TEXTUAL), + TextualCoinMetadataQueryFn: txmodule.NewGRPCCoinMetadataQueryFn(initClientCtx), + } + txConfigWithTextual, err := tx.NewTxConfigWithOptions( + codec.NewProtoCodec(encodingConfig.InterfaceRegistry), + txConfigOpts, + ) + if err != nil { + return err + } + initClientCtx = initClientCtx.WithTxConfig(txConfigWithTextual) + } + if err := client.SetCmdClientContextHandler(initClientCtx, cmd); err != nil { return err } customAppTemplate, customAppConfig := initAppConfig() - customTMConfig := initTendermintConfig() + customCMTConfig := initCometBFTConfig() - return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customTMConfig) + return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customCMTConfig) }, } initRootCmd(rootCmd, encodingConfig) + autoCliOpts, err := enrichAutoCliOpts(tempApp.AutoCliOpts(), initClientCtx) + if err != nil { + panic(err) + } + + if err := autoCliOpts.EnhanceRootCommand(rootCmd); err != nil { + panic(err) + } return rootCmd } -// initTendermintConfig helps to override default Tendermint Config values. -// return tmcfg.DefaultConfig if no custom configuration is required for the application. -func initTendermintConfig() *tmcfg.Config { - cfg := tmcfg.DefaultConfig() - - // these values put a higher strain on node memory - // cfg.P2P.MaxNumInboundPeers = 100 - // cfg.P2P.MaxNumOutboundPeers = 40 +func enrichAutoCliOpts(autoCliOpts autocli.AppOptions, clientCtx client.Context) (autocli.AppOptions, error) { + autoCliOpts.AddressCodec = addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()) + autoCliOpts.ValidatorAddressCodec = addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()) + autoCliOpts.ConsensusAddressCodec = addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()) - return cfg -} + var err error + clientCtx, err = config.ReadFromClientConfig(clientCtx) + if err != nil { + return autocli.AppOptions{}, err + } -func txCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "tx", - Short: "Transactions subcommands", - DisableFlagParsing: false, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, + autoCliOpts.ClientCtx = clientCtx + autoCliOpts.Keyring, err = keyring.NewAutoCLIKeyring(clientCtx.Keyring) + if err != nil { + return autocli.AppOptions{}, err } - cmd.AddCommand( - authcmd.GetSignCommand(), - authcmd.GetSignBatchCommand(), - authcmd.GetMultiSignCommand(), - authcmd.GetMultiSignBatchCmd(), - authcmd.GetValidateSignaturesCommand(), - authcmd.GetBroadcastCommand(), - authcmd.GetEncodeCommand(), - authcmd.GetDecodeCommand(), - authcmd.GetAuxToFeeCommand(), - ) + return autoCliOpts, nil +} - providerApp.ModuleBasics.AddTxCommands(cmd) +// initCometBFTConfig helps to override default CometBFT Config values. +// return cmtcfg.DefaultConfig if no custom configuration is required for the application. +func initCometBFTConfig() *cmtcfg.Config { + cfg := cmtcfg.DefaultConfig() - return cmd + // these values put a higher strain on node memory + // cfg.P2P.MaxNumInboundPeers = 100 + // cfg.P2P.MaxNumOutboundPeers = 40 + + return cfg } // initAppConfig helps to override default appConfig template and configs. @@ -186,30 +213,91 @@ lru_size = 0` return customAppTemplate, customAppConfig } -func initRootCmd(rootCmd *cobra.Command, encodingConfig appencoding.EncodingConfig) { +func initRootCmd(rootCmd *cobra.Command, encodingConfig appEncoding.EncodingConfig) { cfg := sdk.GetConfig() cfg.Seal() rootCmd.AddCommand( genutilcli.InitCmd(providerApp.ModuleBasics, providerApp.DefaultNodeHome), debug.Cmd(), - config.Cmd(), - pruning.PruningCmd(newApp), + pruning.Cmd(newApp, providerApp.DefaultNodeHome), + confixcmd.ConfigCommand(), + server.QueryBlockResultsCmd(), ) server.AddCommands(rootCmd, providerApp.DefaultNodeHome, newApp, appExport, addModuleInitFlags) // add keybase, auxiliary RPC, query, genesis, and tx child commands rootCmd.AddCommand( - rpc.StatusCommand(), + server.StatusCommand(), genesisCommand(encodingConfig), - queryCommand(), txCommand(), - keys.Commands(providerApp.DefaultNodeHome), + queryCommand(), + keys.Commands(), ) +} - // add rosetta - rootCmd.AddCommand(rosettaCmd.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Codec)) +func addModuleInitFlags(startCmd *cobra.Command) { + crisis.AddModuleInitFlags(startCmd) +} + +func queryCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "query", + Aliases: []string{"q"}, + Short: "Querying subcommands", + DisableFlagParsing: false, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + rpc.ValidatorCommand(), + server.QueryBlockCmd(), + authcmd.QueryTxsByEventsCmd(), + server.QueryBlocksCmd(), + authcmd.QueryTxCmd(), + authcmd.GetSimulateCmd(), + ) + + return cmd +} + +func txCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "tx", + Short: "Transactions subcommands", + DisableFlagParsing: false, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + authcmd.GetSignCommand(), + authcmd.GetSignBatchCommand(), + authcmd.GetMultiSignCommand(), + authcmd.GetMultiSignBatchCmd(), + authcmd.GetValidateSignaturesCommand(), + authcmd.GetBroadcastCommand(), + authcmd.GetEncodeCommand(), + authcmd.GetDecodeCommand(), + authcmd.GetSimulateCmd(), + ) + + // NOTE: this must be registered for now so that submit-legacy-proposal + // message can be routed to the provider handler and processed correctly. + providerApp.ModuleBasics.AddTxCommands(cmd) + + return cmd +} + +// genesisCommand builds genesis-related `simd genesis` command. Users may provide application specific commands as a parameter +func genesisCommand(encodingConfig appEncoding.EncodingConfig, cmds ...*cobra.Command) *cobra.Command { + cmd := genutilcli.GenesisCoreCommand(encodingConfig.TxConfig, providerApp.ModuleBasics, providerApp.DefaultNodeHome) + for _, sub_cmd := range cmds { + cmd.AddCommand(sub_cmd) + } + return cmd } // newApp is an appCreator @@ -271,40 +359,12 @@ func appExport( return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport) } -func addModuleInitFlags(startCmd *cobra.Command) { - crisis.AddModuleInitFlags(startCmd) -} - -// genesisCommand builds genesis-related `simd genesis` command. Users may provide application specific commands as a parameter -func genesisCommand(encodingConfig appencoding.EncodingConfig, cmds ...*cobra.Command) *cobra.Command { - cmd := genutilcli.GenesisCoreCommand(encodingConfig.TxConfig, providerApp.ModuleBasics, providerApp.DefaultNodeHome) - for _, sub_cmd := range cmds { - cmd.AddCommand(sub_cmd) +var tempDir = func() string { + dir, err := os.MkdirTemp("", "."+providerApp.AppName) + if err != nil { + dir = providerApp.DefaultNodeHome } - return cmd -} + defer os.RemoveAll(dir) -func queryCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "query", - Aliases: []string{"q"}, - Short: "Querying subcommands", - DisableFlagParsing: false, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - - cmd.AddCommand( - authcmd.GetAccountCmd(), - rpc.ValidatorCommand(), - rpc.BlockCommand(), - authcmd.QueryTxsByEventsCmd(), - authcmd.QueryTxCmd(), - authcmd.GetEncodeCommand(), - authcmd.GetDecodeCommand(), - ) - - providerApp.ModuleBasics.AddQueryCommands(cmd) - - return cmd + return dir } diff --git a/cmd/interchain-security-pd/main.go b/cmd/interchain-security-pd/main.go index 7788f06bff..daf68d27d5 100644 --- a/cmd/interchain-security-pd/main.go +++ b/cmd/interchain-security-pd/main.go @@ -1,26 +1,21 @@ package main import ( + "fmt" "os" - "github.com/cosmos/cosmos-sdk/server" svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" - appparams "github.com/cosmos/interchain-security/v4/app/params" - app "github.com/cosmos/interchain-security/v4/app/provider" - "github.com/cosmos/interchain-security/v4/cmd/interchain-security-pd/cmd" + appparams "github.com/cosmos/interchain-security/v5/app/params" + app "github.com/cosmos/interchain-security/v5/app/provider" + "github.com/cosmos/interchain-security/v5/cmd/interchain-security-pd/cmd" ) func main() { appparams.SetAddressPrefixes("cosmos") rootCmd := cmd.NewRootCmd() if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { - switch e := err.(type) { - case server.ErrorCode: - os.Exit(e.Code) - - default: - os.Exit(1) - } + fmt.Fprintln(rootCmd.OutOrStderr(), err) + os.Exit(1) } } diff --git a/cmd/interchain-security-sd/cmd/root.go b/cmd/interchain-security-sd/cmd/root.go index 28520ef1a4..5e65e536fb 100644 --- a/cmd/interchain-security-sd/cmd/root.go +++ b/cmd/interchain-security-sd/cmd/root.go @@ -8,8 +8,8 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - rosettaCmd "cosmossdk.io/tools/rosetta/cmd" - + "cosmossdk.io/client/v2/autocli" + confixcmd "cosmossdk.io/tools/confix/cmd" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/config" "github.com/cosmos/cosmos-sdk/client/debug" @@ -17,22 +17,28 @@ import ( "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/client/pruning" "github.com/cosmos/cosmos-sdk/client/rpc" + "github.com/cosmos/cosmos-sdk/codec" + addresscodec "github.com/cosmos/cosmos-sdk/codec/address" + "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/server" serverconfig "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + "github.com/cosmos/cosmos-sdk/x/auth/tx" + txmodule "github.com/cosmos/cosmos-sdk/x/auth/tx/config" "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" - dbm "github.com/cometbft/cometbft-db" + "cosmossdk.io/log" tmcfg "github.com/cometbft/cometbft/config" - "github.com/cometbft/cometbft/libs/log" + dbm "github.com/cosmos/cosmos-db" - appencoding "github.com/cosmos/interchain-security/v4/app/encoding" - sovereignApp "github.com/cosmos/interchain-security/v4/app/sovereign" + appencoding "github.com/cosmos/interchain-security/v5/app/encoding" + sovereignApp "github.com/cosmos/interchain-security/v5/app/sovereign" ) // NewRootCmd creates a new root command for simd. It is called once in the @@ -75,6 +81,24 @@ func NewRootCmd() *cobra.Command { return err } + // This needs to go after ReadFromClientConfig, as that function + // sets the RPC client needed for SIGN_MODE_TEXTUAL. This sign mode + // is only available if the client is online. + if !initClientCtx.Offline { + txConfigOpts := tx.ConfigOptions{ + EnabledSignModes: append(tx.DefaultSignModes, signing.SignMode_SIGN_MODE_TEXTUAL), + TextualCoinMetadataQueryFn: txmodule.NewGRPCCoinMetadataQueryFn(initClientCtx), + } + txConfigWithTextual, err := tx.NewTxConfigWithOptions( + codec.NewProtoCodec(encodingConfig.InterfaceRegistry), + txConfigOpts, + ) + if err != nil { + return err + } + initClientCtx = initClientCtx.WithTxConfig(txConfigWithTextual) + } + if err := client.SetCmdClientContextHandler(initClientCtx, cmd); err != nil { return err } @@ -87,10 +111,38 @@ func NewRootCmd() *cobra.Command { } initRootCmd(rootCmd, encodingConfig) + autoCliOpts, err := enrichAutoCliOpts(tempApp.AutoCliOpts(), initClientCtx) + if err != nil { + panic(err) + } + + if err := autoCliOpts.EnhanceRootCommand(rootCmd); err != nil { + panic(err) + } return rootCmd } +func enrichAutoCliOpts(autoCliOpts autocli.AppOptions, clientCtx client.Context) (autocli.AppOptions, error) { + autoCliOpts.AddressCodec = addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()) + autoCliOpts.ValidatorAddressCodec = addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()) + autoCliOpts.ConsensusAddressCodec = addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()) + + var err error + clientCtx, err = config.ReadFromClientConfig(clientCtx) + if err != nil { + return autocli.AppOptions{}, err + } + + autoCliOpts.ClientCtx = clientCtx + autoCliOpts.Keyring, err = keyring.NewAutoCLIKeyring(clientCtx.Keyring) + if err != nil { + return autocli.AppOptions{}, err + } + + return autoCliOpts, nil +} + // initTendermintConfig helps to override default Tendermint Config values. // return tmcfg.DefaultConfig if no custom configuration is required for the application. func initTendermintConfig() *tmcfg.Config { @@ -121,11 +173,8 @@ func txCommand() *cobra.Command { authcmd.GetBroadcastCommand(), authcmd.GetEncodeCommand(), authcmd.GetDecodeCommand(), - authcmd.GetAuxToFeeCommand(), ) - sovereignApp.ModuleBasics.AddTxCommands(cmd) - return cmd } @@ -193,23 +242,20 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig appencoding.EncodingConf rootCmd.AddCommand( genutilcli.InitCmd(sovereignApp.ModuleBasics, sovereignApp.DefaultNodeHome), debug.Cmd(), - config.Cmd(), - pruning.PruningCmd(newApp), + pruning.Cmd(newApp, sovereignApp.DefaultNodeHome), + confixcmd.ConfigCommand(), ) server.AddCommands(rootCmd, sovereignApp.DefaultNodeHome, newApp, appExport, addModuleInitFlags) // add keybase, auxiliary RPC, query, genesis, and tx child commands rootCmd.AddCommand( - rpc.StatusCommand(), + server.StatusCommand(), genesisCommand(encodingConfig), queryCommand(), txCommand(), - keys.Commands(sovereignApp.DefaultNodeHome), + keys.Commands(), ) - - // add rosetta - rootCmd.AddCommand(rosettaCmd.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Codec)) } // newApp is an appCreator @@ -295,16 +341,16 @@ func queryCommand() *cobra.Command { } cmd.AddCommand( - authcmd.GetAccountCmd(), rpc.ValidatorCommand(), - rpc.BlockCommand(), + server.QueryBlockCmd(), + server.QueryBlocksCmd(), + server.QueryBlockResultsCmd(), authcmd.QueryTxsByEventsCmd(), authcmd.QueryTxCmd(), authcmd.GetEncodeCommand(), authcmd.GetDecodeCommand(), + authcmd.GetSimulateCmd(), ) - sovereignApp.ModuleBasics.AddQueryCommands(cmd) - return cmd } diff --git a/cmd/interchain-security-sd/main.go b/cmd/interchain-security-sd/main.go index 2265afad90..99f6b9b371 100644 --- a/cmd/interchain-security-sd/main.go +++ b/cmd/interchain-security-sd/main.go @@ -1,26 +1,20 @@ package main import ( + "fmt" "os" - "github.com/cosmos/cosmos-sdk/server" svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" - appparams "github.com/cosmos/interchain-security/v4/app/params" - app "github.com/cosmos/interchain-security/v4/app/sovereign" - "github.com/cosmos/interchain-security/v4/cmd/interchain-security-sd/cmd" + app "github.com/cosmos/interchain-security/v5/app/sovereign" + "github.com/cosmos/interchain-security/v5/cmd/interchain-security-sd/cmd" ) func main() { - appparams.SetAddressPrefixes("consumer") rootCmd := cmd.NewRootCmd() - if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { - switch e := err.(type) { - case server.ErrorCode: - os.Exit(e.Code) - default: - os.Exit(1) - } + if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { + fmt.Fprintln(rootCmd.OutOrStderr(), err) + os.Exit(1) } } diff --git a/docs/build_deploy.sh b/docs/build_deploy.sh new file mode 100755 index 0000000000..2e948cb55d --- /dev/null +++ b/docs/build_deploy.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +echo "######### BUILD DOCS #########" + +# pull in the versions from versions.json +source ./sync_versions.sh + +echo "building docusaurus main docs" +npm ci && npm run build +cp -r ./legacy ./build/ +mv build ~/output +echo "done building docusaurus main docs" diff --git a/docs/upgrades_reference/app_provider.md b/docs/upgrades_reference/app_provider.md new file mode 100644 index 0000000000..ced15f1478 --- /dev/null +++ b/docs/upgrades_reference/app_provider.md @@ -0,0 +1,104 @@ +# provider/app.go +* use ibc-go/modules/capability +* interfaces registration +```go +interfaceRegistry, _ := types.NewInterfaceRegistryWithOptions(types.InterfaceRegistryOptions{ + ProtoFiles: proto.HybridResolver, + SigningOptions: signing.Options{ + AddressCodec: address.Bech32Codec{ + Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix(), + }, + ValidatorAddressCodec: address.Bech32Codec{ + Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix(), + }, + }, +}) +appCodec := codec.NewProtoCodec(interfaceRegistry) +legacyAmino := codec.NewLegacyAmino() +txConfig := authtx.NewTxConfig(appCodec, authtx.DefaultSignModes) + +std.RegisterLegacyAminoCodec(legacyAmino) +std.RegisterInterfaces(interfaceRegistry) +// ABCI++, v50 +voteExtOp := func(bApp *baseapp.BaseApp) { + voteExtHandler := NewVoteExtensionHandler() + voteExtHandler.SetHandlers(bApp) +} +baseAppOptions = append(baseAppOptions, voteExtOp) + +bApp := baseapp.NewBaseApp(AppName, logger, db, txConfig.TxDecoder(), baseAppOptions...) +``` + +* register streaming services so ibc-testing can listen for packets +```go +// register streaming services +if err := bApp.RegisterStreamingServices(appOpts, keys); err != nil { + panic(err) +} + +``` + +* function additions +```go + +func (app *App) PreBlocker(ctx sdk.Context, _ *abci.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error) { + return app.MM.PreBlock(ctx) +} + +// Configurator returns the configurator for the app +func (app *App) Configurator() module.Configurator { + return app.configurator +} + +func (app *App) setPostHandler() { + postHandler, err := posthandler.NewPostHandler( + posthandler.HandlerOptions{}, + ) + if err != nil { + panic(err) + } + + app.SetPostHandler(postHandler) +} + +// AutoCliOpts returns the autocli options for the app. +func (app *App) AutoCliOpts() autocli.AppOptions { + modules := make(map[string]appmodule.AppModule, 0) + for _, m := range app.MM.Modules { + if moduleWithName, ok := m.(module.HasName); ok { + moduleName := moduleWithName.Name() + if appModule, ok := moduleWithName.(appmodule.AppModule); ok { + modules[moduleName] = appModule + } + } + } + + return autocli.AppOptions{ + Modules: modules, + ModuleOptions: runtimeservices.ExtractAutoCLIOptions(app.MM.Modules), + AddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), + ValidatorAddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + ConsensusAddressCodec: authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), + } +} + +``` + +* function updates +```go +func (app *App) BeginBlocker(ctx sdk.Context) (sdk.BeginBlock, error) { + return app.MM.BeginBlock(ctx) +} + +func (app *App) EndBlocker(ctx sdk.Context) (sdk.EndBlock, error) { + return app.MM.EndBlock(ctx) +} + +func (app *App) InitChainer(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) {...} + +func (app *App) RegisterNodeService(clientCtx client.Context, cfg config.Config) { + nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter(), cfg) +} +``` + +* `cmd/nterchain-security-p/root.go was wired to autoCLI diff --git a/docs/upgrades_reference/consumer.md b/docs/upgrades_reference/consumer.md new file mode 100644 index 0000000000..506fd86f62 --- /dev/null +++ b/docs/upgrades_reference/consumer.md @@ -0,0 +1,17 @@ +# consumer app +```go +func (k Keeper) UpdateSlashingSigningInfo(ctx sdk.Context) +``` +* GetValidatorSigningInfo has extra panics that were not there before + +In `app/consumer/app.go` the configuration options were updated to allow using a different consumer chain address prefix: +```go +func init() { + ... + cfg := sdk.GetConfig() + cfg.SetBech32PrefixForAccount(Bech32MainPrefix, Bech32MainPrefix+"pub") + cfg.SetBech32PrefixForValidator(Bech32MainPrefix+"valoper", Bech32MainPrefix+"valoperpub") + cfg.SetBech32PrefixForConsensusNode(Bech32MainPrefix+"valcons", Bech32MainPrefix+"valconspub") + cfg.Seal() +} +``` \ No newline at end of file diff --git a/docs/upgrades_reference/democracy.md b/docs/upgrades_reference/democracy.md new file mode 100644 index 0000000000..4c89199627 --- /dev/null +++ b/docs/upgrades_reference/democracy.md @@ -0,0 +1,77 @@ +# Democracy modules changes + +## Distribution +Module now implements `appmodule.HasBeginBlocker` + +`BeginBlock` method was refactored to implement the `appmodule.HasBeginBlocker` interface. +```go +func (am AppModule) BeginBlock(goCtx context.Context) error { // this now returns an error + ctx := sdk.UnwrapSDKContext(goCtx) + defer telemetry.ModuleMeasureSince(distrtypes.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker) + + // TODO this is Tendermint-dependent + // ref https://github.com/cosmos/cosmos-sdk/issues/3095 + if ctx.BlockHeight() > 1 { + return am.AllocateTokens(ctx) + } + + return nil +} +``` + +`AllocateTokens` returns errors after refactoring it to match the cosmos-sdk/distribution `AllocateTokens`. + +## Staking +Module now implements `appmodule.HasABCIGenesis` interface. + +`InitGenesis` was refactored to implement the `appmodule.HasABCIGenesis` interface. +```diff ++ func (am AppModule) InitGenesis(ctx context.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate +- func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate +``` + +`EndBlocker` was changed to `EndBlock` to support `module.HasABCIEndBlock` interface. Overriding `EndBlocker` and not `EndBlock` caused the validator changes to be propagated to comet by the staking module instead of the ccv-consumer module. + +## Governance +Module now implements `appmodule.HasEndBlocker` interface. + +`EndBlock` was refactored to implement `appmodule.HasEndBlocker` interface. +```diff ++ func (am AppModule) EndBlock(c context.Context) error +- func (am AppModule) EndBlock(ctx sdk.Context, request abci.RequestEndBlock) []abci.ValidatorUpdate +``` + +The inner workings of `EndBlock` were refactored to allow using the cosmos-sdk governance collection types instead of iterators (there no longer is a way to use raw iterators for iterating gov proposals). +```go + func (am AppModule) EndBlock(c context.Context) error { + ctx := sdk.UnwrapSDKContext(c) + rng := collections.NewPrefixUntilPairRange[time.Time, uint64](ctx.BlockTime()) + keeper := am.keeper + // if there are forbidden proposals in active proposals queue, refund deposit, delete votes for that proposal + // and delete proposal from all storages + err := am.keeper.ActiveProposalsQueue.Walk(ctx, rng, func(key collections.Pair[time.Time, uint64], _ uint64) (bool, error) { + proposal, err := keeper.Proposals.Get(ctx, key.K2()) + if err != nil { + return false, err + } + deleteForbiddenProposal(ctx, am, proposal) + return false, nil + }) + + if err != nil { + return err + } + return am.AppModule.EndBlock(ctx) +} +``` + +## App wiring & tests + +Whitelisted proposal list was changed because `param-change` proposals were deprecated for most modules (they cannot be submitted). + +Added to whitelists: +* `/cosmos.gov.v1beta1.TextProposal` + + +e2e tests were refactored to send the `TextProposal` instead of a `param-change` because there are no modules that can process `param-change` so we cannot use those proposals any longer. + diff --git a/docs/upgrades_reference/imports_only.md b/docs/upgrades_reference/imports_only.md new file mode 100644 index 0000000000..f8f0ab08b5 --- /dev/null +++ b/docs/upgrades_reference/imports_only.md @@ -0,0 +1,56 @@ +# import change only [file list] +* app/consumer-democracy/ante_handler.go +* app/consumer-democracy/proposals_whitelisting.go +* app/consumer-democracy/proposals_whitelisting_test.go +* app/consumer/ante/disabled_modules_ante_test.go +* app/consumer/ante/msg_filter_ante_test.go +* app/consumer/ante_handler.go +* app/provider/ante_handler.go +* app/sovereign/ante_handler.go +* cmd/interchain-security-cdd/cmd/root.go + +## tests + +### Integration +* tests/integration/changeover.go + + +### E2E +* tests/e2e/trace_handlers_test.go +* tests/e2e/json_marshal_test.go +* tests/e2e/state_rapid_test.go +* tests/e2e/steps_consumer_misbehaviour.go + +### Util +* testutil/crypto/evidence.go +* testutil/simibc/ordered_outbox.go +* testutil/simibc/relayed_path.go + + +### Modules +* x/ccv/consumer/ibc_module.go +* x/ccv/consumer/ibc_module_test.go +* x/ccv/consumer/keeper/genesis_test.go +* x/ccv/consumer/keeper/provider_info.go +* x/ccv/consumer/keeper/relay.go +* x/ccv/consumer/keeper/soft_opt_out_test.go [seems long but it's just imports and name updates] +* x/ccv/consumer/types/genesis.go +* x/ccv/consumer/types/genesis_test.go + + +* x/ccv/provider/ibc_module.go +* x/ccv/provider/ibc_module_test.go +* x/ccv/provider/types/genesis.go +* x/ccv/provider/types/legacy_proposal_test.go [rename from proposal_test.go and update imports] +* x/ccv/types/genesis.go +* x/ccv/types/params.go +* x/ccv/types/shared_params.go +* x/ccv/types/utils.go +* x/ccv/types/utils_test.go + + +# Additions +# Sovereign/Standalone chain + +Standalone simapp is modeled after the `app/consumer/app.go`. It must support all features that `app/consumer/app.go` supports so we can use it in standalone to consumer changeover procedures in our test suites. + diff --git a/docs/upgrades_reference/logic_changes.md b/docs/upgrades_reference/logic_changes.md new file mode 100644 index 0000000000..72009cd2c2 --- /dev/null +++ b/docs/upgrades_reference/logic_changes.md @@ -0,0 +1,306 @@ +# logic changes [file list] +Order of changes: +1. x/ +2. app -> integration test setup requires a working app +3. tests/integration & mbt +4. tests/e2e + +* app/consumer-democracy/abci.go +* app/consumer-democracy/export.go +* app/consumer/abci.go [important] +* app/consumer/export.go +* app/params/proto.go [important] +* app/provider/abci.go [important] +* app/provider/export.go [important] +* app/sovereign/abci.go [important] +* app/sovereign/export.go [important] +* cmd/interchain-security-cd/cmd/root.go [important; app setup] +* cmd/interchain-security-pd/cmd/root.go + + +# test changes +* app/consumer-democracy/ante/forbidden_proposals_ante_test.go +* tests/e2e/actions.go +* tests/e2e/config.go [add expedited period] + +* tests/e2e/state.go [important; changes marshalling] +* tests/e2e/state_rapid_test.go +* tests/e2e/steps.go + +### [proposal voting changed -> must provide numeric] +* tests/e2e/steps_democracy.go +* tests/e2e/steps_reward_denom.go +* tests/e2e/steps_sovereign_changeover.go +* tests/e2e/steps_start_chains.go +* tests/e2e/steps_stop_chain.go + +## Update e2e scripts +[must provide `q block --height 0` to force fetching current block] +* tests/e2e/testnet-scripts/start-chain.sh +* tests/e2e/testnet-scripts/start-changeover.sh +* tests/e2e/testnet-scripts/start-sovereign.sh + +## Update integration test setup +* tests/integration/common.go +* tests/integration/setup.go [updates to packet listening and initialization due to interface changes] + +## update assertions (change types etc) +* tests/integration/democracy.go +* tests/integration/distribution.go +* tests/integration/double_vote.go +* tests/integration/expired_client.go +* tests/integration/key_assignment.go +* tests/integration/misbehaviour.go +* tests/integration/normal_operations.go +* tests/integration/slashing.go +* tests/integration/stop_consumer.go +* tests/integration/unbonding.go +* tests/integration/valset_update.go + +MBT Driver +* tests/mbt/driver/common.go +* tests/mbt/driver/core.go +* tests/mbt/driver/mbt_test.go +* tests/mbt/driver/setup.go + + +Not sure needed? +* tests/integration/throttle.go +* tests/integration/throttle_retry.go + +Utils +* testutil/crypto/crypto.go [imports, fetching info] +* testutil/crypto/evidence.go [imports, fetching info] + * MakeVote() interface has changed + +* testutil/ibc_testing/generic_setup.go [init & proposal updates] +* testutil/ibc_testing/specific_setup.go [init & proposal updates] +-> interfaces +* testutil/integration/interfaces.go [support updated interfaces and enforce them] +* testutil/keeper/expectations.go [support updated interfaces and enforce them] +* testutil/keeper/mocks.go [run `make mocks` after updating expectations by hand and expected keepers] +* testutil/keeper/unit_test_helpers.go [imports & setup] +* testutil/simibc/chain_util.go [imports & setup] + * use `FinalizeBlock` and update parsing +* testutil/simibc/relay_util.go + +## Expected keepers +* x/ccv/types/expected_keepers.go [affects mocks and all tests] + + + +## Modules (mostly adapting to new interfaces, checking errs and updating names) + +### Consumer +* x/ccv/consumer/keeper/changeover.go +* x/ccv/consumer/keeper/changeover_test.go +* x/ccv/consumer/keeper/distribution.go +* x/ccv/consumer/keeper/distribution_test.go +* x/ccv/consumer/keeper/hooks.go + +* x/ccv/consumer/keeper/keeper.go +* update `iterator` initialization +```diff +- iterator := sdk.KVStorePrefixIterator(store, []byte{types.PacketMaturityTimeBytePrefix}) ++ iterator := storetypes.KVStorePrefixIterator(store, []byte{types.PacketMaturityTimeBytePrefix}) +``` +* `func (k Keeper) GetLastStandaloneValidators(ctx sdk.Context)` now returns a value and err + + +* x/ccv/consumer/keeper/keeper_test.go +* x/ccv/consumer/keeper/legacy_params.go [addition] +* x/ccv/consumer/keeper/migration.go +* x/ccv/consumer/keeper/migration_test.go +* x/ccv/consumer/keeper/params.go +* x/ccv/consumer/keeper/relay_test.go + +* x/ccv/consumer/keeper/soft_opt_out_test.go +* x/ccv/consumer/keeper/soft_opt_out.go +* interfaces changed `UpdateSlashingSigningInfo` + +* x/ccv/consumer/keeper/validators.go [!important] +* changed all staking interface methods to match cosmos-sdk v50 +* some methods return errs so handling was added + +* x/ccv/consumer/keeper/validators_test.go [imports, err checks, extra assertions] +* x/ccv/consumer/module.go [important!] + +* x/ccv/consumer/types/keys.go [important! params key added to store] +* x/ccv/consumer/types/keys_test.go + + +## Democracy +* x/ccv/democracy/distribution/module.go [important] +* refactor `AllocateTokens` + * adds panics in multiple places due to err handling + +* x/ccv/democracy/governance/module.go [important] +* x/ccv/democracy/staking/module.go [important] + +## Provider +* x/ccv/provider/client/cli/query.go [add params query] +* x/ccv/provider/client/cli/query.go [imports, signer field in NewAssignConsumerKeyCmd] +* x/ccv/provider/client/legacy_proposal_handler.go [rename proposal_handler.go - deprecated] +* x/ccv/provider/client/legacy_proposals.go [added but deprecated] +* x/ccv/provider/handler.go [imports] +* x/ccv/provider/handler_test.go + + + +[sensitive] +* x/ccv/provider/keeper/consumer_equivocation.go [tricky - changes to cometBFT sign.Absent() flags => sign.Absent() changed to comparison sign.BlockIDFlag == tmtypes.BlockIDFlagAbsent] +* added error checks in `JailAndTombstoneValidator(ctx sdk.Context, providerAddr types.ProviderConsAddress)` +* added err checks in `SlashValidator(ctx sdk.Context, providerAddr types.ProviderConsAddress)` + + + +* x/ccv/provider/keeper/consumer_equivocation_test.go + + +-> check that endblock returns correct errors +* x/ccv/provider/module.go [important] +* x/ccv/provider/module_test.go + + +* x/ccv/provider/types/codec.go [double check RegisterLegacyAminoCodec and RegisterInterfaces] +* x/ccv/provider/types/keys.go [adds parameters bytekey -> make sure you don't override it!!] +* x/ccv/provider/types/keys_test.go +* x/ccv/provider/types/legacy_proposal.go [rename from proposal.go, update logic] +* x/ccv/provider/types/legacy_proposal_test.go [check some weird comments about comparisons] +* x/ccv/provider/types/msg.go [new message type] +* x/ccv/provider/types/params.go +* x/ccv/provider/types/params_test.go + + +#### Change to store access +``` +// changes store module imports and iterator initialization + +- iterator := sdk.KVStorePrefixIterator(store, []byte{types.ConsumerRewardDenomsBytePrefix}) ++ iterator := storetypes.KVStorePrefixIterator(store, []byte{types.ConsumerRewardDenomsBytePrefix}) +``` + +* x/ccv/provider/keeper/distribution.go +* update iterator + + +* x/ccv/provider/keeper/keeper_test.go +* x/ccv/provider/keeper/keeper.go +* updated `NewKeeper` and the `types Keeper struct` with v50 types (authority, storeKey, storeService, validatorAddressCodec, consensusAddressCodec) +* rm `SetParamSpace [DEPRECATED]` +* use v50 logger +* update all iterators: +```go +- iterator := sdk.KVStorePrefixIterator(store, []byte{types.ProposedConsumerChainByteKey}) ++ iterator := storetypes.KVStorePrefixIterator(store, []byte{types.ProposedConsumerChainByteKey}) +``` + + +* x/ccv/provider/keeper/key_assignment.go [ also logic changes regarding key assignment and validator access ] +```go +- iterator := sdk.KVStorePrefixIterator(store, prefix) ++ iterator := storetypes.KVStorePrefixIterator(store, prefix) +``` + +Updates changing the logic slightly: +```go +func (k Keeper) AssignConsumerKey( + ctx sdk.Context, + chainID string, + validator stakingtypes.Validator, + consumerKey tmprotocrypto.PublicKey, +) error +``` + +```go +func (k Keeper) ValidatorConsensusKeyInUse(ctx sdk.Context, valAddr sdk.ValAddress) bool +``` + + +* x/ccv/provider/keeper/key_assignment_test.go -> partial + + +#### Other changes +* x/ccv/provider/keeper/genesis_test.go +* x/ccv/provider/keeper/grpc_query.go [adds params query] + +* x/ccv/provider/keeper/hooks.go +* update all methods to use `context.Context` instead of `sdk.Context` +* double check returned values in `func (h Hooks) GetConsumerAdditionLegacyPropFromProp` + +* x/ccv/provider/keeper/hooks_test.go +* x/ccv/provider/keeper/legacy_params.go + +* x/ccv/provider/keeper/migration_test.go +* x/ccv/provider/keeper/migration.go + * was re-done + +* x/ccv/provider/keeper/msg_server.go + +* x/ccv/provider/keeper/params_test.go +* x/ccv/provider/keeper/params.go +* migrated params to the new interface and update all getters +* added legacy params file for accessing deprecated params subspace + +* x/ccv/provider/keeper/proposal_test.go +* x/ccv/provider/keeper/proposal.go +* prefixed deprecated handlers with `Legacy` +* updated `MakeConsumerGenesis`: added err checks +* moved deprecated handlers to `legacy_proposal.go` + + +* x/ccv/provider/keeper/relay_test.go -> generate after updating mocks +* x/ccv/provider/keeper/relay.go +* updated err handling to support new interfaces + * `completeMaturedUnbondingOps(ctx sdk.Context)` + + +* x/ccv/provider/keeper/throttle_test.go +* x/ccv/provider/keeper/throttle.go +* update err handling +* left myself a note: `@MSalopek double check this conversion and see if it's necessary` + + +* x/ccv/provider/proposal_handler.go +* x/ccv/provider/proposal_handler_test.go +* x/ccv/provider/types/codec.go +* x/ccv/provider/types/errors.go +* x/ccv/provider/types/genesis.go + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# less important +* cmd/interchain-security-cd/main.go +* cmd/interchain-security-cdd/main.go +* cmd/interchain-security-pd/main.go +* cmd/interchain-security-sd/main.go \ No newline at end of file diff --git a/go.mod b/go.mod index 9f83b9af09..4e29ee61ea 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/cosmos/interchain-security/v4 +module github.com/cosmos/interchain-security/v5 go 1.21.1 @@ -6,30 +6,28 @@ toolchain go1.21.6 require ( cosmossdk.io/errors v1.0.1 - cosmossdk.io/math v1.3.0 - github.com/cometbft/cometbft v0.37.4 - github.com/cometbft/cometbft-db v0.11.0 - github.com/cosmos/cosmos-sdk v0.47.10 - github.com/cosmos/gogoproto v1.4.10 - github.com/cosmos/ibc-go/v7 v7.3.2 + cosmossdk.io/math v1.2.0 + github.com/cometbft/cometbft v0.38.5 + github.com/cometbft/cometbft-db v0.10.0 // indirect + github.com/cosmos/cosmos-sdk v0.50.4 + github.com/cosmos/gogoproto v1.4.11 github.com/cosmos/ics23/go v0.10.0 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 - github.com/gorilla/mux v1.8.0 // indirect + github.com/gorilla/mux v1.8.1 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/kylelemons/godebug v1.1.0 github.com/oxyno-zeta/gomock-extra-matcher v1.2.0 - github.com/rakyll/statik v0.1.7 // indirect github.com/spf13/cast v1.6.0 github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb + golang.org/x/crypto v0.19.0 // indirect + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a golang.org/x/net v0.20.0 // indirect - golang.org/x/sys v0.16.0 // indirect - google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect - google.golang.org/grpc v1.62.0 + golang.org/x/sys v0.17.0 // indirect + google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 // indirect + google.golang.org/grpc v1.61.1 google.golang.org/protobuf v1.32.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -40,16 +38,13 @@ require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.5 // indirect cloud.google.com/go/storage v1.36.0 // indirect - cosmossdk.io/api v0.3.1 - cosmossdk.io/core v0.5.1 // indirect + cosmossdk.io/api v0.7.3 + cosmossdk.io/core v0.11.0 cosmossdk.io/depinject v1.0.0-alpha.4 // indirect - cosmossdk.io/tools/rosetta v0.2.1 filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect - github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect - github.com/armon/go-metrics v0.4.1 // indirect - github.com/aws/aws-sdk-go v1.44.203 // indirect + github.com/aws/aws-sdk-go v1.44.224 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect @@ -59,19 +54,15 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect - github.com/coinbase/rosetta-sdk-go/types v1.0.0 // indirect - github.com/confio/ics23/go v0.9.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.4 github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect - github.com/cosmos/iavl v0.20.1 // indirect - github.com/cosmos/ledger-cosmos-go v0.12.4 // indirect - github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect - github.com/creachadair/taskgroup v0.4.2 // indirect + github.com/cosmos/iavl v1.0.1 // indirect + github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/danieljoos/wincred v1.1.2 // indirect - github.com/davecgh/go-spew v1.1.1 - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect @@ -79,7 +70,7 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect @@ -95,19 +86,16 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect - github.com/gorilla/handlers v1.5.1 // indirect + github.com/gorilla/handlers v1.5.2 // indirect github.com/gorilla/websocket v1.5.0 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect - github.com/gtank/merlin v0.1.1 // indirect - github.com/gtank/ristretto255 v0.1.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-getter v1.7.1 // indirect + github.com/hashicorp/go-getter v1.7.3 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect - github.com/hashicorp/go-uuid v1.0.2 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect + github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hdevalence/ed25519consensus v0.1.0 // indirect github.com/huandu/skiplist v1.2.0 // indirect @@ -115,38 +103,35 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/klauspost/compress v1.16.7 // indirect + github.com/klauspost/compress v1.17.6 // indirect github.com/lib/pq v1.10.7 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/linxGnu/grocksdb v1.8.12 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mtibben/percent v0.2.1 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect + github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_golang v1.18.0 // indirect + github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/common v0.47.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rs/cors v1.8.3 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect - github.com/spf13/afero v1.9.5 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/afero v1.11.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/subosito/gotenv v1.4.2 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tendermint/go-amino v0.16.0 // indirect - github.com/tidwall/btree v1.6.0 // indirect + github.com/tidwall/btree v1.7.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/ulikunitz/xz v0.5.11 // indirect @@ -155,7 +140,7 @@ require ( go.etcd.io/bbolt v1.3.8 // indirect go.opencensus.io v0.24.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/term v0.16.0 // indirect + golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/api v0.155.0 // indirect google.golang.org/appengine v1.6.8 // indirect @@ -167,38 +152,68 @@ require ( ) require ( + cosmossdk.io/client/v2 v2.0.0-beta.1 + cosmossdk.io/collections v0.4.0 + cosmossdk.io/log v1.3.1 + cosmossdk.io/store v1.0.2 + cosmossdk.io/tools/confix v0.1.1 + cosmossdk.io/x/evidence v0.1.0 + cosmossdk.io/x/feegrant v0.1.0 + cosmossdk.io/x/tx v0.13.0 + cosmossdk.io/x/upgrade v0.1.1 + github.com/cosmos/cosmos-db v1.0.0 + github.com/cosmos/ibc-go/modules/capability v1.0.0 + github.com/cosmos/ibc-go/v8 v8.1.0 github.com/informalsystems/itf-go v0.0.1 - github.com/spf13/viper v1.16.0 - golang.org/x/mod v0.16.0 - google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 + github.com/spf13/viper v1.18.2 + golang.org/x/mod v0.15.0 + google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 ) require ( - cosmossdk.io/log v1.3.1 // indirect - github.com/DataDog/zstd v1.4.5 // indirect + cosmossdk.io/x/circuit v0.1.0 // indirect + github.com/DataDog/datadog-go v3.2.0+incompatible // indirect + github.com/DataDog/zstd v1.5.5 // indirect + github.com/bits-and-blooms/bitset v1.8.0 // indirect github.com/cockroachdb/errors v1.11.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v1.1.0 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/getsentry/sentry-go v0.23.0 // indirect + github.com/creachadair/atomicfile v0.3.1 // indirect + github.com/creachadair/tomledit v0.0.24 // indirect + github.com/emicklei/dot v1.6.1 // indirect + github.com/fatih/color v1.15.0 // indirect + github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/s2a-go v0.1.7 // indirect + github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-metrics v0.5.2 // indirect + github.com/hashicorp/go-plugin v1.5.2 // indirect + github.com/hashicorp/yamux v0.1.1 // indirect + github.com/iancoleman/strcase v0.3.0 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect + github.com/oklog/run v1.1.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/zerolog v1.32.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect go.opentelemetry.io/otel v1.21.0 // indirect go.opentelemetry.io/otel/metric v1.21.0 // indirect go.opentelemetry.io/otel/trace v1.21.0 // indirect go.uber.org/mock v0.2.0 // indirect - golang.org/x/sync v0.6.0 // indirect + go.uber.org/multierr v1.10.0 // indirect + golang.org/x/sync v0.5.0 // indirect golang.org/x/time v0.5.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect + gotest.tools/v3 v3.5.1 // indirect ) // following versions might cause unexpected behavior diff --git a/go.sum b/go.sum index 5617cf2507..e25ba8a80e 100644 --- a/go.sum +++ b/go.sum @@ -3,7 +3,6 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= @@ -16,7 +15,6 @@ cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOY cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= @@ -170,7 +168,6 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= @@ -187,20 +184,36 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE= -cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw= -cosmossdk.io/core v0.5.1 h1:vQVtFrIYOQJDV3f7rw4pjjVqc1id4+mE0L9hHP66pyI= -cosmossdk.io/core v0.5.1/go.mod h1:KZtwHCLjcFuo0nmDc24Xy6CRNEL9Vl/MeimQ2aC7NLE= +cosmossdk.io/api v0.7.3 h1:V815i8YOwOAQa1rLCsSMjVG5Gnzs02JLq+l7ks8s1jk= +cosmossdk.io/api v0.7.3/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= +cosmossdk.io/client/v2 v2.0.0-beta.1 h1:XkHh1lhrLYIT9zKl7cIOXUXg2hdhtjTPBUfqERNA1/Q= +cosmossdk.io/client/v2 v2.0.0-beta.1/go.mod h1:JEUSu9moNZQ4kU3ir1DKD5eU4bllmAexrGWjmb9k8qU= +cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= +cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= +cosmossdk.io/core v0.11.0 h1:vtIafqUi+1ZNAE/oxLOQQ7Oek2n4S48SWLG8h/+wdbo= +cosmossdk.io/core v0.11.0/go.mod h1:LaTtayWBSoacF5xNzoF8tmLhehqlA9z1SWiPuNC6X1w= cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc= cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= -cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= -cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= -cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= +cosmossdk.io/math v1.2.0 h1:8gudhTkkD3NxOP2YyyJIYYmt6dQ55ZfJkDOaxXpy7Ig= +cosmossdk.io/math v1.2.0/go.mod h1:l2Gnda87F0su8a/7FEKJfFdJrM0JZRXQaohlgJeyQh0= +cosmossdk.io/store v1.0.2 h1:lSg5BTvJBHUDwswNNyeh4K/CbqiHER73VU4nDNb8uk0= +cosmossdk.io/store v1.0.2/go.mod h1:EFtENTqVTuWwitGW1VwaBct+yDagk7oG/axBMPH+FXs= +cosmossdk.io/tools/confix v0.1.1 h1:aexyRv9+y15veH3Qw16lxQwo+ki7r2I+g0yNTEFEQM8= +cosmossdk.io/tools/confix v0.1.1/go.mod h1:nQVvP1tHsGXS83PonPVWJtSbddIqyjEw99L4M3rPJyQ= +cosmossdk.io/x/circuit v0.1.0 h1:IAej8aRYeuOMritczqTlljbUVHq1E85CpBqaCTwYgXs= +cosmossdk.io/x/circuit v0.1.0/go.mod h1:YDzblVE8+E+urPYQq5kq5foRY/IzhXovSYXb4nwd39w= +cosmossdk.io/x/evidence v0.1.0 h1:J6OEyDl1rbykksdGynzPKG5R/zm6TacwW2fbLTW4nCk= +cosmossdk.io/x/evidence v0.1.0/go.mod h1:hTaiiXsoiJ3InMz1uptgF0BnGqROllAN8mwisOMMsfw= +cosmossdk.io/x/feegrant v0.1.0 h1:c7s3oAq/8/UO0EiN1H5BIjwVntujVTkYs35YPvvrdQk= +cosmossdk.io/x/feegrant v0.1.0/go.mod h1:4r+FsViJRpcZif/yhTn+E0E6OFfg4n0Lx+6cCtnZElU= +cosmossdk.io/x/tx v0.13.0 h1:8lzyOh3zONPpZv2uTcUmsv0WTXy6T1/aCVDCqShmpzU= +cosmossdk.io/x/tx v0.13.0/go.mod h1:CpNQtmoqbXa33/DVxWQNx5Dcnbkv2xGUhL7tYQ5wUsY= +cosmossdk.io/x/upgrade v0.1.1 h1:aoPe2gNvH+Gwt/Pgq3dOxxQVU3j5P6Xf+DaUJTDZATc= +cosmossdk.io/x/upgrade v0.1.1/go.mod h1:MNLptLPcIFK9CWt7Ra//8WUZAxweyRDNcbs5nkOcQy0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= @@ -208,18 +221,17 @@ github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMb github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o= github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= -github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= +github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= -github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= +github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= -github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= @@ -242,16 +254,15 @@ github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= -github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.44.203 h1:pcsP805b9acL3wUqa4JR2vg1k2wnItkDYNvfmcy6F+U= -github.com/aws/aws-sdk-go v1.44.203/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.44.224 h1:09CiaaF35nRmxrzWZ2uRq5v6Ghg/d2RiPjZnSgtt+RQ= +github.com/aws/aws-sdk-go v1.44.224/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -261,14 +272,16 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5MS5JVb4c= +github.com/bits-and-blooms/bitset v1.8.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= -github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= -github.com/btcsuite/btcd/btcutil v1.1.2/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0= +github.com/btcsuite/btcd/btcutil v1.1.3 h1:xfbtw8lwpp0G6NwSHb+UE67ryTFHJAiNuipusjXSohQ= +github.com/btcsuite/btcd/btcutil v1.1.3/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= -github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= +github.com/bufbuild/protocompile v0.6.0 h1:Uu7WiSQ6Yj9DbkdnOe7U4mNKp58y9WDMKDn28/ZlunY= +github.com/bufbuild/protocompile v0.6.0/go.mod h1:YNP35qEYoYGme7QMtz5SBCoN4kL4g12jTtjuzRNdjpE= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -304,8 +317,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= +github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY= +github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= @@ -322,14 +335,10 @@ github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA= -github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= -github.com/cometbft/cometbft v0.37.4 h1:xyvvEqlyfK8MgNIIKVJaMsuIp03wxOcFmVkT26+Ikpg= -github.com/cometbft/cometbft v0.37.4/go.mod h1:Cmg5Hp4sNpapm7j+x0xRyt2g0juQfmB752ous+pA0G8= -github.com/cometbft/cometbft-db v0.11.0 h1:M3Lscmpogx5NTbb1EGyGDaFRdsoLWrUWimFEyf7jej8= -github.com/cometbft/cometbft-db v0.11.0/go.mod h1:GDPJAC/iFHNjmZZPN8V8C1yr/eyityhi2W1hz2MGKSc= -github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= -github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= +github.com/cometbft/cometbft v0.38.5 h1:4lOcK5VTPrfbLOhNHmPYe6c7eDXHtBdMCQuKbAfFJdU= +github.com/cometbft/cometbft v0.38.5/go.mod h1:0tqKin+KQs8zDwzYD8rPHzSBIDNPuB4NrwwGDNb/hUg= +github.com/cometbft/cometbft-db v0.10.0 h1:VMBQh88zXn64jXVvj39tlu/IgsGR84T7ImjS523DCiU= +github.com/cometbft/cometbft-db v0.10.0/go.mod h1:7RR7NRv99j7keWJ5IkE9iZibUTKYdtepXTp7Ra0FxKk= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -340,44 +349,48 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= +github.com/cosmos/cosmos-db v1.0.0 h1:EVcQZ+qYag7W6uorBKFPvX6gRjw6Uq2hIh4hCWjuQ0E= +github.com/cosmos/cosmos-db v1.0.0/go.mod h1:iBvi1TtqaedwLdcrZVYRSSCb6eSy61NLj4UNmdIgs0U= github.com/cosmos/cosmos-proto v1.0.0-beta.4 h1:aEL7tU/rLOmxZQ9z4i7mzxcLbSCY48OdY7lIWTLG7oU= github.com/cosmos/cosmos-proto v1.0.0-beta.4/go.mod h1:oeB+FyVzG3XrQJbJng0EnV8Vljfk9XvTIpGILNU/9Co= -github.com/cosmos/cosmos-sdk v0.47.10 h1:Wxf5yEN3jZbG4fftxAMKB6rpd8ME0mxuCVihpz65dt0= -github.com/cosmos/cosmos-sdk v0.47.10/go.mod h1:UWpgWkhcsBIATS68uUC0del7IiBN4hPv/vqg8Zz23uw= -github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= +github.com/cosmos/cosmos-sdk v0.50.4 h1:hQT5/+Z1XXNF7skaPq0i247Ts2dzzqg/j2WO/BPHSto= +github.com/cosmos/cosmos-sdk v0.50.4/go.mod h1:UbShFs6P8Ly29xxJvkNGaNaL/UGj5a686NRtb1Cqra0= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= -github.com/cosmos/gogoproto v1.4.10 h1:QH/yT8X+c0F4ZDacDv3z+xE3WU1P1Z3wQoLMBRJoKuI= -github.com/cosmos/gogoproto v1.4.10/go.mod h1:3aAZzeRWpAwr+SS/LLkICX2/kDFyaYVzckBDzygIxek= -github.com/cosmos/iavl v0.20.1 h1:rM1kqeG3/HBT85vsZdoSNsehciqUQPWrR4BYmqE2+zg= -github.com/cosmos/iavl v0.20.1/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= -github.com/cosmos/ibc-go/v7 v7.3.2 h1:FeUDcBX7VYY0e0iRmcVkPPUjYfAqIc//QuHXo8JHz9c= -github.com/cosmos/ibc-go/v7 v7.3.2/go.mod h1:IMeOXb7gwpZ+/nOG5BuUkdW4weM1ezvN4PQPws4uzOI= +github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= +github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= +github.com/cosmos/iavl v1.0.1 h1:D+mYbcRO2wptYzOM1Hxl9cpmmHU1ZEt9T2Wv5nZTeUw= +github.com/cosmos/iavl v1.0.1/go.mod h1:8xIUkgVvwvVrBu81scdPty+/Dx9GqwHnAvXz4cwF7RY= +github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= +github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= +github.com/cosmos/ibc-go/v8 v8.1.0 h1:pf1106wl0Cf+p1+FjXzV6odlS9DnqVunPVWCH1Uz+lQ= +github.com/cosmos/ibc-go/v8 v8.1.0/go.mod h1:o1ipS95xpdjqNcB8Drq0eI3Sn4FRLigjll42ec1ECuU= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= -github.com/cosmos/ledger-cosmos-go v0.12.4 h1:drvWt+GJP7Aiw550yeb3ON/zsrgW0jgh5saFCr7pDnw= -github.com/cosmos/ledger-cosmos-go v0.12.4/go.mod h1:fjfVWRf++Xkygt9wzCsjEBdjcf7wiiY35fv3ctT+k4M= -github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM= -github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= +github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= +github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJFxv2Li8= -github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= +github.com/creachadair/atomicfile v0.3.1 h1:yQORkHjSYySh/tv5th1dkKcn02NEW5JleB84sjt+W4Q= +github.com/creachadair/atomicfile v0.3.1/go.mod h1:mwfrkRxFKwpNAflYZzytbSwxvbK6fdGRRlp0KEQc0qU= +github.com/creachadair/tomledit v0.0.24 h1:5Xjr25R2esu1rKCbQEmjZYlrhFkDspoAbAKb6QKQDhQ= +github.com/creachadair/tomledit v0.0.24/go.mod h1:9qHbShRWQzSCcn617cMzg4eab1vbLCOjOshAWSzWr8U= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= @@ -403,6 +416,8 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/emicklei/dot v1.6.1 h1:ujpDlBkkwgWUY+qPId5IwapRW/xEoligRSYjioR6DFI= +github.com/emicklei/dot v1.6.1/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -414,10 +429,12 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= -github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= +github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= +github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= @@ -428,10 +445,10 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/getsentry/sentry-go v0.23.0 h1:dn+QRCeJv4pPt9OjVXiMcGIBIefaTJPw/h0bZWO05nE= -github.com/getsentry/sentry-go v0.23.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= @@ -448,6 +465,7 @@ github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= @@ -579,7 +597,6 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= @@ -610,34 +627,28 @@ github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMd github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= -github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= +github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= -github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= -github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= -github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= -github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= -github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -645,13 +656,19 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-getter v1.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY= -github.com/hashicorp/go-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-getter v1.7.3 h1:bN2+Fw9XPFvOCjB0UOevFIMICZ7G2XSQHzfvLUyOM5E= +github.com/hashicorp/go-getter v1.7.3/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-metrics v0.5.2 h1:ErEYO2f//CjKsUDw4SmLzelsK6L3ZmOAR/4P9iS7ruY= +github.com/hashicorp/go-metrics v0.5.2/go.mod h1:KEjodfebIOuBYSAe/bHTm+HChmKSxAOXPBieMLYozDE= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-plugin v1.5.2 h1:aWv8eimFqWlsEiMrYZdPYl+FdHaBJSN4AWwGWfT1G2Y= +github.com/hashicorp/go-plugin v1.5.2/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= @@ -668,14 +685,16 @@ github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -684,6 +703,8 @@ github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0Jr github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= +github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= @@ -694,8 +715,8 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/informalsystems/itf-go v0.0.1 h1:lVvdg3v+IMWOsVfIvOOGy1hHFO5KxoS8b8EiwKLbQDg= github.com/informalsystems/itf-go v0.0.1/go.mod h1:wgqaQ/yl2kbNlgw6GaleuHEefpZvkZo6Hc0jc8cGG9M= -github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= -github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= +github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls= +github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -725,11 +746,10 @@ github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= +github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -758,11 +778,14 @@ github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3v github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -770,12 +793,7 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= -github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= -github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -815,8 +833,12 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q= +github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -827,8 +849,8 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= -github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q= +github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -854,12 +876,12 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= -github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc h1:8bQZVK1X6BJR/6nYUPxQEP+ReTsceJTKizeuwjWOPUA= +github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= @@ -870,9 +892,9 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= @@ -880,34 +902,32 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= +github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= +github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= -github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -915,8 +935,8 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= @@ -927,6 +947,10 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= @@ -942,12 +966,14 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= @@ -956,15 +982,13 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= -github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= @@ -981,19 +1005,20 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= -github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI= +github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -1006,8 +1031,8 @@ github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= -github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= @@ -1057,13 +1082,19 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU= go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= +go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1072,14 +1103,11 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1091,8 +1119,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb h1:xIApU0ow1zwMa2uL1VDNeQlNVFTWMQxZUZCMDy0Q4Us= -golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1120,8 +1148,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= -golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1163,7 +1191,6 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= @@ -1171,7 +1198,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -1227,8 +1253,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1285,13 +1311,11 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1303,7 +1327,9 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1323,18 +1349,17 @@ golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1375,6 +1400,7 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1408,7 +1434,6 @@ golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -1417,8 +1442,8 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1527,10 +1552,8 @@ google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1597,12 +1620,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ= -google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= -google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 h1:Lj5rbfG876hIAYFjqiJnPHfhXbv+nzTWfm04Fg/XSVU= -google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= +google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg= +google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0= +google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM= +google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1644,8 +1667,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk= -google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= +google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1696,7 +1719,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/proto/buf.lock b/proto/buf.lock index 1c8fbbc13a..01c20e880a 100644 --- a/proto/buf.lock +++ b/proto/buf.lock @@ -5,23 +5,29 @@ deps: owner: cosmos repository: cosmos-proto commit: 1935555c206d4afb9e94615dfd0fad31 + digest: shake256:c74d91a3ac7ae07d579e90eee33abf9b29664047ac8816500cf22c081fec0d72d62c89ce0bebafc1f6fec7aa5315be72606717740ca95007248425102c365377 - remote: buf.build owner: cosmos repository: cosmos-sdk - commit: 954f7b05f38440fc8250134b15adec47 + commit: aa25660f4ff746388669ce36b3778442 + digest: shake256:a20eb29eb7284d9d0b76e94324a6e24e3665d13682bed0d5beac647d7109b7b2f22080301276779a91f394c97dab334da36dfc01d4252d9f869b090bfc8248aa - remote: buf.build owner: cosmos repository: gogo-proto commit: 34d970b699f84aa382f3c29773a60836 + digest: shake256:3d3bee5229ba579e7d19ffe6e140986a228b48a8c7fe74348f308537ab95e9135210e81812489d42cd8941d33ff71f11583174ccc5972e86e6112924b6ce9f04 - remote: buf.build owner: cosmos repository: ibc - commit: fbb44f5ad3194450af479a615fa715d9 + commit: 7ab44ae956a0488ea04e04511efa5f70 + digest: shake256:95cc5472ddf692d23654b7e5adfd79149469dcc90657f9a1f80ee3fea8af639cff59cd849efca0567d270118eea7c7ff2f7e60c562545bace410b8eece27577e - remote: buf.build owner: cosmos repository: ics23 commit: 55085f7c710a45f58fa09947208eb70b + digest: shake256:9bf0bc495b5a11c88d163d39ef521bc4b00bc1374a05758c91d82821bdc61f09e8c2c51dda8452529bf80137f34d852561eacbe9550a59015d51cecb0dacb628 - remote: buf.build owner: googleapis repository: googleapis - commit: 5ae7f88519b04fe1965da0f8a375a088 + commit: 8d7204855ec14631a499bd7393ce1970 + digest: shake256:40bf4112960cad01281930beed85829910768e32e80e986791596853eccd42c0cbd9d96690b918f658020d2d427e16f8b6514e2ac7f4a10306fd32e77be44329 diff --git a/proto/buf.yaml b/proto/buf.yaml index 5ef6b4b743..b3f16381eb 100644 --- a/proto/buf.yaml +++ b/proto/buf.yaml @@ -6,11 +6,12 @@ version: v1 name: buf.build/cosmos/interchain-security deps: - - buf.build/cosmos/gogo-proto - - buf.build/cosmos/cosmos-sdk:v0.47.0 - - buf.build/cosmos/ibc:fbb44f5ad3194450af479a615fa715d9 - - buf.build/googleapis/googleapis + - buf.build/cosmos/cosmos-sdk:aa25660f4ff746388669ce36b3778442 + - buf.build/cosmos/cosmos-proto:1935555c206d4afb9e94615dfd0fad31 + - buf.build/cosmos/gogo-proto:a14993478f40695898ed8a86931094b6656e8a5d - buf.build/cosmos/ics23:b1abd8678aab07165efd453c96796a179eb3131f + - buf.build/cosmos/ibc:26f7fe338f6d5d1d587887e94aa473302bb26a1a + - buf.build/googleapis/googleapis:8d7204855ec14631a499bd7393ce1970 breaking: use: diff --git a/proto/interchain_security/ccv/consumer/v1/consumer.proto b/proto/interchain_security/ccv/consumer/v1/consumer.proto index 749eedc7ac..959d06c087 100644 --- a/proto/interchain_security/ccv/consumer/v1/consumer.proto +++ b/proto/interchain_security/ccv/consumer/v1/consumer.proto @@ -1,7 +1,7 @@ syntax = "proto3"; package interchain_security.ccv.consumer.v1; -option go_package = "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types"; +option go_package = "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types"; import "google/protobuf/any.proto"; import "gogoproto/gogo.proto"; diff --git a/proto/interchain_security/ccv/consumer/v1/genesis.proto b/proto/interchain_security/ccv/consumer/v1/genesis.proto index a2ceb0f9f6..642b78451d 100644 --- a/proto/interchain_security/ccv/consumer/v1/genesis.proto +++ b/proto/interchain_security/ccv/consumer/v1/genesis.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package interchain_security.ccv.consumer.v1; -option go_package = "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types"; +option go_package = "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types"; import "interchain_security/ccv/v1/shared_consumer.proto"; import "ibc/lightclients/tendermint/v1/tendermint.proto"; diff --git a/proto/interchain_security/ccv/consumer/v1/query.proto b/proto/interchain_security/ccv/consumer/v1/query.proto index eb8eb29a3d..0e9b088e1d 100644 --- a/proto/interchain_security/ccv/consumer/v1/query.proto +++ b/proto/interchain_security/ccv/consumer/v1/query.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package interchain_security.ccv.consumer.v1; import "interchain_security/ccv/v1/shared_consumer.proto"; -option go_package = "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types"; +option go_package = "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types"; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; diff --git a/proto/interchain_security/ccv/provider/v1/genesis.proto b/proto/interchain_security/ccv/provider/v1/genesis.proto index 443ea26b32..269743721e 100644 --- a/proto/interchain_security/ccv/provider/v1/genesis.proto +++ b/proto/interchain_security/ccv/provider/v1/genesis.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package interchain_security.ccv.provider.v1; -option go_package = "github.com/cosmos/interchain-security/v4/x/ccv/provider/types"; +option go_package = "github.com/cosmos/interchain-security/v5/x/ccv/provider/types"; import "gogoproto/gogo.proto"; import "interchain_security/ccv/v1/shared_consumer.proto"; diff --git a/proto/interchain_security/ccv/provider/v1/provider.proto b/proto/interchain_security/ccv/provider/v1/provider.proto index f9bdf0a53f..936a7eeb5b 100644 --- a/proto/interchain_security/ccv/provider/v1/provider.proto +++ b/proto/interchain_security/ccv/provider/v1/provider.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package interchain_security.ccv.provider.v1; -option go_package = "github.com/cosmos/interchain-security/v4/x/ccv/provider/types"; +option go_package = "github.com/cosmos/interchain-security/v5/x/ccv/provider/types"; import "interchain_security/ccv/v1/wire.proto"; import "gogoproto/gogo.proto"; @@ -13,6 +13,7 @@ import "ibc/lightclients/tendermint/v1/tendermint.proto"; import "tendermint/crypto/keys.proto"; import "cosmos/evidence/v1beta1/evidence.proto"; import "cosmos/base/v1beta1/coin.proto"; +import "cosmos_proto/cosmos.proto"; // // Note any type defined in this file is ONLY used internally to the provider CCV module. @@ -24,9 +25,12 @@ import "cosmos/base/v1beta1/coin.proto"; // chain are expected to validate the consumer chain at spawn time or get // slashed. It is recommended that spawn time occurs after the proposal end // time. +// Deprecated: Use MsgConsumerAddition instead message ConsumerAdditionProposal { + option deprecated = true; option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_stringer) = false; + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; // the title of the proposal string title = 1; @@ -89,7 +93,11 @@ message ConsumerAdditionProposal { // remove (and stop) a consumer chain. If it passes, all the consumer chain's // state is removed from the provider chain. The outstanding unbonding operation // funds are released. +// Deprecated: Use MsgConsumerRemoval instead message ConsumerRemovalProposal { + option deprecated = true; + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // the title of the proposal string title = 1; // the description of the proposal @@ -120,7 +128,11 @@ message EquivocationProposal { // ChangeRewardDenomsProposal is a governance proposal on the provider chain to // mutate the set of denoms accepted by the provider as rewards. +// Deprecated: Use MsgChangeRewardDenoms instead message ChangeRewardDenomsProposal { + option deprecated = true; + option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; + // the title of the proposal string title = 1; // the description of the proposal diff --git a/proto/interchain_security/ccv/provider/v1/query.proto b/proto/interchain_security/ccv/provider/v1/query.proto index 56b06a42c3..49527ad76c 100644 --- a/proto/interchain_security/ccv/provider/v1/query.proto +++ b/proto/interchain_security/ccv/provider/v1/query.proto @@ -1,7 +1,7 @@ syntax = "proto3"; package interchain_security.ccv.provider.v1; -option go_package = "github.com/cosmos/interchain-security/v4/x/ccv/provider/types"; +option go_package = "github.com/cosmos/interchain-security/v5/x/ccv/provider/types"; import "google/api/annotations.proto"; import "gogoproto/gogo.proto"; diff --git a/proto/interchain_security/ccv/provider/v1/tx.proto b/proto/interchain_security/ccv/provider/v1/tx.proto index 3294807015..2b14e77dec 100644 --- a/proto/interchain_security/ccv/provider/v1/tx.proto +++ b/proto/interchain_security/ccv/provider/v1/tx.proto @@ -1,25 +1,42 @@ syntax = "proto3"; package interchain_security.ccv.provider.v1; -option go_package = "github.com/cosmos/interchain-security/v4/x/ccv/provider/types"; +option go_package = "github.com/cosmos/interchain-security/v5/x/ccv/provider/types"; +import "amino/amino.proto"; +import "google/api/annotations.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/any.proto"; import "gogoproto/gogo.proto"; import "cosmos_proto/cosmos.proto"; -import "google/protobuf/any.proto"; +import "cosmos/msg/v1/msg.proto"; +import "ibc/core/client/v1/client.proto"; +import "interchain_security/ccv/provider/v1/provider.proto"; import "ibc/lightclients/tendermint/v1/tendermint.proto"; import "tendermint/types/evidence.proto"; - // Msg defines the Msg service. service Msg { + option (cosmos.msg.v1.service) = true; + rpc AssignConsumerKey(MsgAssignConsumerKey) returns (MsgAssignConsumerKeyResponse); rpc SubmitConsumerMisbehaviour(MsgSubmitConsumerMisbehaviour) returns (MsgSubmitConsumerMisbehaviourResponse); rpc SubmitConsumerDoubleVoting(MsgSubmitConsumerDoubleVoting) returns (MsgSubmitConsumerDoubleVotingResponse); + + rpc ConsumerAddition(MsgConsumerAddition)returns (MsgConsumerAdditionResponse); + rpc ConsumerRemoval(MsgConsumerRemoval) returns (MsgConsumerRemovalResponse); + + rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); } + message MsgAssignConsumerKey { + option (cosmos.msg.v1.signer) = "signer"; option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; + + // The chain id of the consumer chain to assign a consensus public key to string chain_id = 1; // The validator address on the provider @@ -28,6 +45,9 @@ message MsgAssignConsumerKey { // in json string format corresponding to proto-any, ex: // `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is="}` string consumer_key = 3; + + // Tx signer address + string signer = 4 [(cosmos_proto.scalar) = "cosmos.AddressString"]; } message MsgAssignConsumerKeyResponse {} @@ -36,9 +56,11 @@ message MsgAssignConsumerKeyResponse {} // MsgSubmitConsumerMisbehaviour defines a message that reports a light client attack, // also known as a misbehaviour, observed on a consumer chain message MsgSubmitConsumerMisbehaviour { + option (cosmos.msg.v1.signer) = "submitter"; option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string submitter = 1; + + string submitter = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // The Misbehaviour of the consumer chain wrapping // two conflicting IBC headers ibc.lightclients.tendermint.v1.Misbehaviour misbehaviour = 2; @@ -50,9 +72,11 @@ message MsgSubmitConsumerMisbehaviourResponse {} // MsgSubmitConsumerDoubleVoting defines a message that reports // a double signing infraction observed on a consumer chain message MsgSubmitConsumerDoubleVoting { + option (cosmos.msg.v1.signer) = "submitter"; option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string submitter = 1; + + string submitter = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // The equivocation of the consumer chain wrapping // an evidence of a validator that signed two conflicting votes tendermint.types.DuplicateVoteEvidence duplicate_vote_evidence = 2; @@ -61,3 +85,128 @@ message MsgSubmitConsumerDoubleVoting { } message MsgSubmitConsumerDoubleVotingResponse {} + +// MsgUpdateParams is the Msg/UpdateParams request type +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "authority"; + + // signer is the address of the governance account. + string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + + // params defines the x/provider parameters to update. + Params params = 2 [(gogoproto.nullable) = false]; +} + +message MsgUpdateParamsResponse {} + + +// MsgConsumerAddition defines the message used to spawn a new consumer chain using a v1 governance proposal. +// If it passes, then all validators on the provider chain are expected to validate +// the consumer chain at spawn time or get slashed. +// It is recommended that spawn time occurs after the proposal end time. +// +// Note: this replaces ConsumerAdditionProposal which is deprecated and will be removed soon +message MsgConsumerAddition { + option (cosmos.msg.v1.signer) = "authority"; + + // the proposed chain-id of the new consumer chain, must be different from all + // other consumer chain ids of the executing provider chain. + string chain_id = 1; + // the proposed initial height of new consumer chain. + // For a completely new chain, this will be {0,1}. However, it may be + // different if this is a chain that is converting to a consumer chain. + ibc.core.client.v1.Height initial_height = 2 [ (gogoproto.nullable) = false ]; + // The hash of the consumer chain genesis state without the consumer CCV + // module genesis params. It is used for off-chain confirmation of + // genesis.json validity by validators and other parties. + bytes genesis_hash = 3; + // The hash of the consumer chain binary that should be run by validators on + // chain initialization. It is used for off-chain confirmation of binary + // validity by validators and other parties. + bytes binary_hash = 4; + // spawn time is the time on the provider chain at which the consumer chain + // genesis is finalized and all validators will be responsible for starting + // their consumer chain validator node. + google.protobuf.Timestamp spawn_time = 5 + [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; + + // Unbonding period for the consumer, + // which should be smaller than that of the provider in general. + google.protobuf.Duration unbonding_period = 6 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + // Sent CCV related IBC packets will timeout after this duration + google.protobuf.Duration ccv_timeout_period = 7 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + // Sent transfer related IBC packets will timeout after this duration + google.protobuf.Duration transfer_timeout_period = 8 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; + // The fraction of tokens allocated to the consumer redistribution address + // during distribution events. The fraction is a string representing a + // decimal number. For example "0.75" would represent 75%. + string consumer_redistribution_fraction = 9; + // BlocksPerDistributionTransmission is the number of blocks between + // ibc-token-transfers from the consumer chain to the provider chain. On + // sending transmission event, `consumer_redistribution_fraction` of the + // accumulated tokens are sent to the consumer redistribution address. + int64 blocks_per_distribution_transmission = 10; + // The number of historical info entries to persist in store. + // This param is a part of the cosmos sdk staking module. In the case of + // a ccv enabled consumer chain, the ccv module acts as the staking module. + int64 historical_entries = 11; + // The ID of a token transfer channel used for the Reward Distribution + // sub-protocol. If DistributionTransmissionChannel == "", a new transfer + // channel is created on top of the same connection as the CCV channel. + // Note that transfer_channel_id is the ID of the channel end on the consumer + // chain. it is most relevant for chains performing a sovereign to consumer + // changeover in order to maintan the existing ibc transfer channel + string distribution_transmission_channel = 12; + + // signer address + string authority = 13 [(cosmos_proto.scalar) = "cosmos.AddressString"]; +} + +// MsgConsumerAdditionResponse defines response type for MsgConsumerAddition messages +message MsgConsumerAdditionResponse {} + + +// MsgConsumerRemoval message contains a governance proposal on the provider chain to +// remove (and stop) a consumer chain. If it passes, all the consumer chain's +// state is removed from the provider chain. The outstanding unbonding operation +// funds are released. +// +// Note: this replaces ConsumerRemovalProposal which is deprecated and will be removed soon +message MsgConsumerRemoval { + option (cosmos.msg.v1.signer) = "authority"; + + // the chain-id of the consumer chain to be stopped + string chain_id = 1; + // the time on the provider chain at which all validators are responsible to + // stop their consumer chain validator node + google.protobuf.Timestamp stop_time = 2 + [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; + + // signer address + string authority = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"]; +} + +// MsgConsumerRemovalResponse defines response type for MsgConsumerRemoval messages +message MsgConsumerRemovalResponse {} + +// ChangeRewardDenomsProposal is a governance proposal on the provider chain to +// mutate the set of denoms accepted by the provider as rewards. +// +// Note: this replaces ChangeRewardDenomsProposal which is deprecated and will be removed soon +message MsgChangeRewardDenoms { + option (cosmos.msg.v1.signer) = "authority"; + + // the list of consumer reward denoms to add + repeated string denoms_to_add = 1; + // the list of consumer reward denoms to remove + repeated string denoms_to_remove = 2; + // signer address + string authority = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + +} + +// MsgChangeRewardDenomsResponse defines response type for MsgChangeRewardDenoms messages +message MsgChangeRewardDenomsResponse {} diff --git a/proto/interchain_security/ccv/v1/shared_consumer.proto b/proto/interchain_security/ccv/v1/shared_consumer.proto index d1f0a5d5a3..ce65df04a6 100644 --- a/proto/interchain_security/ccv/v1/shared_consumer.proto +++ b/proto/interchain_security/ccv/v1/shared_consumer.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package interchain_security.ccv.v1; -option go_package = "github.com/cosmos/interchain-security/v4/x/ccv/types"; +option go_package = "github.com/cosmos/interchain-security/v5/x/ccv/types"; import "tendermint/abci/types.proto"; import "ibc/lightclients/tendermint/v1/tendermint.proto"; diff --git a/proto/interchain_security/ccv/v1/wire.proto b/proto/interchain_security/ccv/v1/wire.proto index 7382b9d0da..f0ba6ab41a 100644 --- a/proto/interchain_security/ccv/v1/wire.proto +++ b/proto/interchain_security/ccv/v1/wire.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package interchain_security.ccv.v1; -option go_package = "github.com/cosmos/interchain-security/v4/x/ccv/types"; +option go_package = "github.com/cosmos/interchain-security/v5/x/ccv/types"; import "cosmos/staking/v1beta1/staking.proto"; diff --git a/scripts/protocgen.sh b/scripts/protocgen.sh index 67ae158143..fdf6a894c1 100644 --- a/scripts/protocgen.sh +++ b/scripts/protocgen.sh @@ -16,6 +16,6 @@ done cd .. # move proto files to the right places -cp -r github.com/cosmos/interchain-security/v4/* ./ +cp -r github.com/cosmos/interchain-security/v5/* ./ rm -rf github.com diff --git a/tests/e2e/action_rapid_test.go b/tests/e2e/action_rapid_test.go index 366f7f61c0..b720d3557c 100644 --- a/tests/e2e/action_rapid_test.go +++ b/tests/e2e/action_rapid_test.go @@ -269,15 +269,12 @@ func GetSubmitConsumerRemovalProposalActionGen() *rapid.Generator[SubmitConsumer }) } -func GetSubmitParamChangeProposalActionGen() *rapid.Generator[SubmitParamChangeLegacyProposalAction] { - return rapid.Custom(func(t *rapid.T) SubmitParamChangeLegacyProposalAction { - return SubmitParamChangeLegacyProposalAction{ - Chain: GetChainIDGen().Draw(t, "Chain"), - From: GetValidatorIDGen().Draw(t, "From"), - Deposit: rapid.Uint().Draw(t, "Deposit"), - Subspace: rapid.String().Draw(t, "Subspace"), - Key: rapid.String().Draw(t, "Key"), - Value: rapid.String().Draw(t, "Value"), // could make this more generic in the future, since Value takes interfaces +func GetSubmitParamChangeProposalActionGen() *rapid.Generator[SubmitEnableTransfersProposalAction] { + return rapid.Custom(func(t *rapid.T) SubmitEnableTransfersProposalAction { + return SubmitEnableTransfersProposalAction{ + Chain: GetChainIDGen().Draw(t, "Chain"), + From: GetValidatorIDGen().Draw(t, "From"), + Deposit: rapid.Uint().Draw(t, "Deposit"), } }) } diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index e63481cb63..18eb65e96b 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -15,13 +15,13 @@ import ( "sync" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/tidwall/gjson" "golang.org/x/mod/semver" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/client" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/client" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) type SendTokensAction struct { @@ -300,7 +300,7 @@ func (tr TestConfig) submitConsumerAdditionProposal( } // CONSUMER ADDITION PROPOSAL - bz, err = target.ExecCommand( + cmd := target.ExecCommand( tr.chainConfigs[action.Chain].BinaryName, "tx", "gov", "submit-legacy-proposal", "consumer-addition", "/temp-proposal.json", `--from`, `validator`+fmt.Sprint(action.From), @@ -310,12 +310,22 @@ func (tr TestConfig) submitConsumerAdditionProposal( `--node`, tr.getValidatorNode(action.Chain, action.From), `--keyring-backend`, `test`, `-y`, - ).CombinedOutput() + ) + + if verbose { + fmt.Println("submitConsumerAdditionProposal cmd:", cmd.String()) + fmt.Println("submitConsumerAdditionProposal json:", jsonStr) + } + bz, err = cmd.CombinedOutput() if err != nil { log.Fatal(err, "\n", string(bz)) } + if verbose { + fmt.Println("submitConsumerAdditionProposal output:", string(bz)) + } + // wait for inclusion in a block -> '--broadcast-mode block' is deprecated tr.waitBlocks(ChainID("provi"), 2, 10*time.Second) } @@ -380,54 +390,43 @@ func (tr TestConfig) submitConsumerRemovalProposal( tr.waitBlocks(ChainID("provi"), 2, 20*time.Second) } -type SubmitParamChangeLegacyProposalAction struct { - Chain ChainID - From ValidatorID - Deposit uint - Subspace string - Key string - Value interface{} -} - -type paramChangeProposalJSON struct { - Title string `json:"title"` - Summary string `json:"summary"` - Description string `json:"description"` - Changes []paramChangeJSON `json:"changes"` - Deposit string `json:"deposit"` -} - -type paramChangeJSON struct { - Subspace string `json:"subspace"` - Key string `json:"key"` - Value interface{} `json:"value"` +type SubmitEnableTransfersProposalAction struct { + Chain ChainID + From ValidatorID + Title string + Deposit uint } -func (tr TestConfig) submitParamChangeProposal( - action SubmitParamChangeLegacyProposalAction, +func (tr TestConfig) submitEnableTransfersProposalAction( + action SubmitEnableTransfersProposalAction, target ExecutionTarget, verbose bool, ) { - prop := paramChangeProposalJSON{ - Title: "Legacy Param change", - Summary: "Changing legacy module params", - Description: "Changing legacy module params", - Changes: []paramChangeJSON{{Subspace: action.Subspace, Key: action.Key, Value: action.Value}}, - Deposit: fmt.Sprint(action.Deposit) + `stake`, - } - - bz, err := json.Marshal(prop) - if err != nil { - log.Fatal(err) - } - - jsonStr := string(bz) - if strings.Contains(jsonStr, "'") { - log.Fatal("prop json contains single quote") - } + // gov signed addres got by checking the gov module acc address in the test container + // interchain-security-cdd q auth module-account gov --node tcp://7.7.9.253:26658 + template := ` + { + "messages": [ + { + "@type": "/ibc.applications.transfer.v1.MsgUpdateParams", + "signer": "consumer10d07y265gmmuvt4z0w9aw880jnsr700jlh7295", + "params": { + "send_enabled": true, + "receive_enabled": true + } + } + ], + "metadata": "ipfs://CID", + "deposit": "%dstake", + "title": "%s", + "summary": "Enable transfer send", + "expedited": false + } + ` + jsonStr := fmt.Sprintf(template, action.Deposit, action.Title) //#nosec G204 -- bypass unsafe quoting warning (no production code) - bz, err = target.ExecCommand( + bz, err := target.ExecCommand( "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/params-proposal.json"), ).CombinedOutput() @@ -437,9 +436,7 @@ func (tr TestConfig) submitParamChangeProposal( cmd := target.ExecCommand( tr.chainConfigs[action.Chain].BinaryName, - - "tx", "gov", "submit-legacy-proposal", "param-change", "/params-proposal.json", - + "tx", "gov", "submit-proposal", "/params-proposal.json", `--from`, `validator`+fmt.Sprint(action.From), `--chain-id`, string(tr.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, action.From), @@ -1648,7 +1645,7 @@ func (tr TestConfig) cancelUnbondTokens( if err != nil { log.Fatal(err, "\n", string(bz)) } - creationHeight := gjson.Get(string(bz), "entries.0.creation_height").Int() + creationHeight := gjson.Get(string(bz), "unbond.entries.0.creation_height").Int() if creationHeight == 0 { log.Fatal("invalid creation height") } @@ -1844,6 +1841,7 @@ func (tr TestConfig) unjailValidator(action UnjailValidatorAction, target Execut `--node`, tr.getValidatorNode(action.Provider, action.Validator), `--gas`, "900000", `--keyring-backend`, `test`, + `--keyring-dir`, tr.getValidatorHome(action.Provider, action.Validator), `-y`, ) @@ -1872,6 +1870,19 @@ func (tr TestConfig) registerRepresentative( target ExecutionTarget, verbose bool, ) { + fileTempl := `{ + "pubkey": %s, + "amount": "%s", + "moniker": "%s", + "identity": "", + "website": "", + "security": "", + "details": "", + "commission-rate": "0.1", + "commission-max-rate": "0.2", + "commission-max-change-rate": "0.01", + "min-self-delegation": "1" + }` var wg sync.WaitGroup for i, val := range action.Representatives { wg.Add(1) @@ -1889,22 +1900,46 @@ func (tr TestConfig) registerRepresentative( log.Fatal(err, "\n", string(bzPubKey)) } - bz, err := target.ExecCommand(tr.chainConfigs[action.Chain].BinaryName, + fileContent := fmt.Sprintf(fileTempl, string(bzPubKey), fmt.Sprint(stake)+"stake", fmt.Sprint(val)) + fileName := fmt.Sprintf("%s_democracy_representative.json", val) + file, err := os.CreateTemp("", fileName) + if err != nil { + panic(fmt.Sprintf("failed writing ccv consumer file : %v", err)) + } + defer file.Close() + err = os.WriteFile(file.Name(), []byte(fileContent), 0600) + if err != nil { + log.Fatalf("Failed writing consumer genesis to file: %v", err) + } + + containerInstance := tr.containerConfig.InstanceName + targetFile := fmt.Sprintf("/tmp/%s", fileName) + sourceFile := file.Name() + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + copyCmd := exec.Command("docker", "cp", sourceFile, + fmt.Sprintf("%s:%s", containerInstance, targetFile)) + writeResult, err := copyCmd.CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(writeResult)) + } + + cmd := target.ExecCommand(tr.chainConfigs[action.Chain].BinaryName, "tx", "staking", "create-validator", - `--amount`, fmt.Sprint(stake)+"stake", - `--pubkey`, string(bzPubKey), - `--moniker`, fmt.Sprint(val), - `--commission-rate`, "0.1", - `--commission-max-rate`, "0.2", - `--commission-max-change-rate`, "0.01", - `--min-self-delegation`, "1", + targetFile, `--from`, `validator`+fmt.Sprint(val), `--chain-id`, string(tr.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, val), `--node`, tr.getValidatorNode(action.Chain, val), `--keyring-backend`, `test`, `-y`, - ).CombinedOutput() + ) + + if verbose { + fmt.Println("register representative cmd:", cmd.String()) + fmt.Println("Tx json:", fileContent) + } + + bz, err := cmd.CombinedOutput() if err != nil { log.Fatal(err, "\n", string(bz)) } diff --git a/tests/e2e/config.go b/tests/e2e/config.go index 243c43ca3d..22997c3df9 100644 --- a/tests/e2e/config.go +++ b/tests/e2e/config.go @@ -368,6 +368,7 @@ func SlashThrottleTestConfig() TestConfig { IpPrefix: "7.7.7", VotingWaitTime: 20, GenesisChanges: ".app_state.gov.params.voting_period = \"20s\" | " + + ".app_state.gov.params.expedited_voting_period = \"10s\" | " + // Custom slashing parameters for testing validator downtime functionality // See https://docs.cosmos.network/main/modules/slashing/04_begin_block.html#uptime-tracking ".app_state.slashing.params.signed_blocks_window = \"10\" | " + @@ -515,6 +516,7 @@ func DefaultTestConfig() TestConfig { IpPrefix: "7.7.7", VotingWaitTime: 20, GenesisChanges: ".app_state.gov.params.voting_period = \"20s\" | " + + ".app_state.gov.params.expedited_voting_period = \"10s\" | " + // Custom slashing parameters for testing validator downtime functionality // See https://docs.cosmos.network/main/modules/slashing/04_begin_block.html#uptime-tracking ".app_state.slashing.params.signed_blocks_window = \"10\" | " + @@ -577,6 +579,7 @@ func DemocracyTestConfig(allowReward bool) TestConfig { IpPrefix: "7.7.7", VotingWaitTime: 20, GenesisChanges: ".app_state.gov.params.voting_period = \"20s\" | " + + ".app_state.gov.params.expedited_voting_period = \"10s\" | " + // Custom slashing parameters for testing validator downtime functionality // See https://docs.cosmos.network/main/modules/slashing/04_begin_block.html#uptime-tracking ".app_state.slashing.params.signed_blocks_window = \"10\" | " + @@ -619,6 +622,7 @@ func MultiConsumerTestConfig() TestConfig { IpPrefix: "7.7.7", VotingWaitTime: 20, GenesisChanges: ".app_state.gov.params.voting_period = \"30s\" | " + + ".app_state.gov.params.expedited_voting_period = \"10s\" | " + // Custom slashing parameters for testing validator downtime functionality // See https://docs.cosmos.network/main/modules/slashing/04_begin_block.html#uptime-tracking ".app_state.slashing.params.signed_blocks_window = \"10\" | " + @@ -677,6 +681,7 @@ func ChangeoverTestConfig() TestConfig { IpPrefix: "7.7.7", VotingWaitTime: 20, GenesisChanges: ".app_state.gov.params.voting_period = \"20s\" | " + + ".app_state.gov.params.expedited_voting_period = \"10s\" | " + // Custom slashing parameters for testing validator downtime functionality // See https://docs.cosmos.network/main/modules/slashing/04_begin_block.html#uptime-tracking ".app_state.slashing.params.signed_blocks_window = \"10\" | " + diff --git a/tests/e2e/json_marshal_test.go b/tests/e2e/json_marshal_test.go index 5ee91dcb66..9a7694587f 100644 --- a/tests/e2e/json_marshal_test.go +++ b/tests/e2e/json_marshal_test.go @@ -3,10 +3,12 @@ package main import ( "encoding/json" "reflect" + "strconv" "strings" "testing" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/davecgh/go-spew/spew" ) @@ -20,7 +22,7 @@ func TestProposalUnmarshal(t *testing.T) { "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" } }` @@ -29,7 +31,7 @@ func TestProposalUnmarshal(t *testing.T) { Chain: ChainID("consu"), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, - Status: "PROPOSAL_STATUS_PASSED", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), } type ProposalAndType struct { @@ -79,7 +81,7 @@ var testCases = []ChainStateTestCase{ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" } } } @@ -96,7 +98,7 @@ var testCases = []ChainStateTestCase{ Chain: ChainID("consu"), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, - Status: "PROPOSAL_STATUS_PASSED", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), }, }, }, @@ -125,7 +127,7 @@ var testCases = []ChainStateTestCase{ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" } } }, diff --git a/tests/e2e/json_utils.go b/tests/e2e/json_utils.go index aeb59eee3a..d94f599588 100644 --- a/tests/e2e/json_utils.go +++ b/tests/e2e/json_utils.go @@ -95,8 +95,8 @@ func UnmarshalMapToActionType(rawAction json.RawMessage, actionTypeString string if err == nil { return a, nil } - case "main.SubmitParamChangeLegacyProposalAction": - var a SubmitParamChangeLegacyProposalAction + case "main.SubmitEnableTransfersProposalAction": + var a SubmitEnableTransfersProposalAction err := json.Unmarshal(rawAction, &a) if err == nil { return a, nil @@ -372,8 +372,8 @@ func UnmarshalProposalWithType(inputMap json.RawMessage, proposalType string) (P if err == nil { return prop, nil } - case "main.ParamsProposal": - prop := ParamsProposal{} + case "main.IBCTransferParamsProposal": + prop := IBCTransferParamsProposal{} err := json.Unmarshal(inputMap, &prop) if err == nil { return prop, nil diff --git a/tests/e2e/main.go b/tests/e2e/main.go index a14610def5..16b4864356 100644 --- a/tests/e2e/main.go +++ b/tests/e2e/main.go @@ -438,12 +438,12 @@ Summary: for _, t := range failedTests { report += t.Report() } - report += fmt.Sprintln("\n\nPASSED TESTS:\n") + report += fmt.Sprintln("\n\nPASSED TESTS:") for _, t := range passedTests { report += t.Report() } - report += fmt.Sprintln("\n\nREMAINING TESTS:\n") + report += fmt.Sprintln("\n\nREMAINING TESTS:") for _, t := range remainingTests { report += t.Report() } diff --git a/tests/e2e/state.go b/tests/e2e/state.go index 91379a0705..e4cb225392 100644 --- a/tests/e2e/state.go +++ b/tests/e2e/state.go @@ -2,6 +2,7 @@ package main import ( "bufio" + "encoding/json" "fmt" "log" "os/exec" @@ -9,7 +10,7 @@ import ( "strconv" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/kylelemons/godebug/pretty" "github.com/tidwall/gjson" "gopkg.in/yaml.v2" @@ -23,7 +24,7 @@ type ChainState struct { ProposedConsumerChains *[]string ValPowers *map[ValidatorID]uint StakedTokens *map[ValidatorID]uint - Params *[]Param + IBCTransferParams *IBCTransferParams Rewards *Rewards ConsumerChains *map[ChainID]bool AssignedKeys *map[ValidatorID]string @@ -45,6 +46,15 @@ type TextProposal struct { func (p TextProposal) isProposal() {} +type IBCTransferParamsProposal struct { + Title string + Deposit uint + Status string + Params IBCTransferParams +} + +func (ibct IBCTransferParamsProposal) isProposal() {} + type ConsumerAdditionProposal struct { Deposit uint Chain ChainID @@ -101,6 +111,11 @@ type Param struct { Value string } +type IBCTransferParams struct { + SendEnabled bool `json:"send_enabled"` + ReceiveEnabled bool `json:"receive_enabled"` +} + func (tr TestConfig) getState(modelState State, verbose bool) State { systemState := State{} for k, modelState := range modelState { @@ -142,9 +157,9 @@ func (tr TestConfig) getChainState(chain ChainID, modelState ChainState) ChainSt chainState.StakedTokens = &representPowers } - if modelState.Params != nil { - params := tr.getParams(chain, *modelState.Params) - chainState.Params = ¶ms + if modelState.IBCTransferParams != nil { + params := tr.getIBCTransferParams(chain) + chainState.IBCTransferParams = ¶ms } if modelState.Rewards != nil { @@ -290,15 +305,6 @@ func (tr TestConfig) getStakedTokens(chain ChainID, modelState map[ValidatorID]u return actualState } -func (tr TestConfig) getParams(chain ChainID, modelState []Param) []Param { - actualState := []Param{} - for _, p := range modelState { - actualState = append(actualState, Param{Subspace: p.Subspace, Key: p.Key, Value: tr.getParam(chain, p)}) - } - - return actualState -} - func (tr TestConfig) getRewards(chain ChainID, modelState Rewards) Rewards { receivedRewards := map[ValidatorID]bool{} @@ -331,17 +337,18 @@ func (tr TestConfig) getReward(chain ChainID, validator ValidatorID, blockHeight } //#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", "distribution", "rewards", - delAddresss, - + cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, + "query", "distribution", "delegation-total-rewards", + "--delegator-address", delAddresss, `--height`, fmt.Sprint(blockHeight), `--node`, tr.getQueryNode(chain), `-o`, `json`, - ).CombinedOutput() + ) + + bz, err := cmd.CombinedOutput() + if err != nil { - log.Fatal(err, "\n", string(bz)) + log.Fatal("failed getting rewards: ", err, "\n", string(bz)) } denomCondition := `total.#(denom!="stake").amount` @@ -390,10 +397,8 @@ var noProposalRegex = regexp.MustCompile(`doesn't exist: key not found`) func (tr TestConfig) getProposal(chain ChainID, proposal uint) Proposal { //#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", "gov", "proposal", fmt.Sprint(proposal), - `--node`, tr.getQueryNode(chain), `-o`, `json`, ).CombinedOutput() @@ -408,14 +413,24 @@ func (tr TestConfig) getProposal(chain ChainID, proposal uint) Proposal { log.Fatal(err, "\n", string(bz)) } - propType := gjson.Get(string(bz), `messages.0.content.@type`).String() - deposit := gjson.Get(string(bz), `total_deposit.#(denom=="stake").amount`).Uint() - status := gjson.Get(string(bz), `status`).String() + // for legacy proposal types submitted using "tx submit-legacyproposal" (cosmos-sdk/v1/MsgExecLegacyContent) + propType := gjson.Get(string(bz), `proposal.messages.0.value.content.type`).String() + rawContent := gjson.Get(string(bz), `proposal.messages.0.value.content.value`) + + // for current (>= v47) prop types submitted using "tx submit-proposal" + if propType == "" { + propType = gjson.Get(string(bz), `proposal.messages.0.type`).String() + rawContent = gjson.Get(string(bz), `proposal.messages.0.value`) + } + + title := gjson.Get(string(bz), `proposal.title`).String() + deposit := gjson.Get(string(bz), `proposal.total_deposit.#(denom=="stake").amount`).Uint() + status := gjson.Get(string(bz), `proposal.status`).String() switch propType { case "/cosmos.gov.v1beta1.TextProposal": - title := gjson.Get(string(bz), `content.title`).String() - description := gjson.Get(string(bz), `content.description`).String() + title := rawContent.Get("title").String() + description := rawContent.Get("description").String() return TextProposal{ Deposit: uint(deposit), @@ -424,8 +439,8 @@ func (tr TestConfig) getProposal(chain ChainID, proposal uint) Proposal { Description: description, } case "/interchain_security.ccv.provider.v1.ConsumerAdditionProposal": - chainId := gjson.Get(string(bz), `messages.0.content.chain_id`).String() - spawnTime := gjson.Get(string(bz), `messages.0.content.spawn_time`).Time().Sub(tr.containerConfig.Now) + chainId := rawContent.Get("chain_id").String() + spawnTime := rawContent.Get("spawn_time").Time().Sub(tr.containerConfig.Now) var chain ChainID for i, conf := range tr.chainConfigs { @@ -441,13 +456,13 @@ func (tr TestConfig) getProposal(chain ChainID, proposal uint) Proposal { Chain: chain, SpawnTime: int(spawnTime.Milliseconds()), InitialHeight: clienttypes.Height{ - RevisionNumber: gjson.Get(string(bz), `messages.0.content.initial_height.revision_number`).Uint(), - RevisionHeight: gjson.Get(string(bz), `messages.0.content.initial_height.revision_height`).Uint(), + RevisionNumber: rawContent.Get("initial_height.revision_number").Uint(), + RevisionHeight: rawContent.Get("initial_height.revision_height").Uint(), }, } case "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal": - height := gjson.Get(string(bz), `messages.0.content.plan.height`).Uint() - title := gjson.Get(string(bz), `messages.0.content.plan.name`).String() + height := rawContent.Get("plan.height").Uint() + title := rawContent.Get("plan.name").String() return UpgradeProposal{ Deposit: uint(deposit), Status: status, @@ -456,8 +471,8 @@ func (tr TestConfig) getProposal(chain ChainID, proposal uint) Proposal { Type: "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", } case "/interchain_security.ccv.provider.v1.ConsumerRemovalProposal": - chainId := gjson.Get(string(bz), `messages.0.content.chain_id`).String() - stopTime := gjson.Get(string(bz), `messages.0.content.stop_time`).Time().Sub(tr.containerConfig.Now) + chainId := rawContent.Get("chain_id").String() + stopTime := rawContent.Get("stop_time").Time().Sub(tr.containerConfig.Now) var chain ChainID for i, conf := range tr.chainConfigs { @@ -473,23 +488,31 @@ func (tr TestConfig) getProposal(chain ChainID, proposal uint) Proposal { Chain: chain, StopTime: int(stopTime.Milliseconds()), } - case "/cosmos.params.v1beta1.ParameterChangeProposal": - return ParamsProposal{ - Deposit: uint(deposit), - Status: status, - Subspace: gjson.Get(string(bz), `messages.0.content.changes.0.subspace`).String(), - Key: gjson.Get(string(bz), `messages.0.content.changes.0.key`).String(), - Value: gjson.Get(string(bz), `messages.0.content.changes.0.value`).String(), + case "/ibc.applications.transfer.v1.MsgUpdateParams": + var params IBCTransferParams + if err := json.Unmarshal([]byte(rawContent.Get("params").String()), ¶ms); err != nil { + log.Fatal("cannot unmarshal ibc-transfer params: ", err, "\n", string(bz)) + } + + return IBCTransferParamsProposal{ + Deposit: uint(deposit), + Status: status, + Title: title, + Params: params, } } - log.Fatal("unknown proposal type", string(bz)) + log.Fatal("received unknosn proposal type: ", propType, "proposal JSON:", string(bz)) return nil } type TmValidatorSetYaml struct { - Total string `yaml:"total"` + BlockHeight string `yaml:"block_height"` + Pagination struct { + NextKey string `yaml:"next_key"` + Total string `yaml:"total"` + } `yaml:"pagination"` Validators []struct { Address string `yaml:"address"` VotingPower string `yaml:"voting_power"` @@ -525,14 +548,14 @@ func (tr TestConfig) getValPower(chain ChainID, validator ValidatorID) uint { log.Fatalf("yaml.Unmarshal returned an error while unmarshalling validator set: %v, input: %s", err, string(bz)) } - total, err := strconv.Atoi(valset.Total) + total, err := strconv.Atoi(valset.Pagination.Total) if err != nil { - log.Fatalf("strconv.Atoi returned an error while converting total for validator set: %v, input: %s, validator set: %s", err, valset.Total, pretty.Sprint(valset)) + log.Fatalf("strconv.Atoi returned an error while coonverting total for validator set: %v, input: %s, validator set: %s", err, valset.Pagination.Total, pretty.Sprint(valset)) } if total != len(valset.Validators) { log.Fatalf("Total number of validators %v does not match number of validators in list %v. Probably a query pagination issue. Validator set: %v", - valset.Total, uint(len(valset.Validators)), pretty.Sprint(valset)) + valset.Pagination.Total, uint(len(valset.Validators)), pretty.Sprint(valset)) } for _, val := range valset.Validators { @@ -586,7 +609,7 @@ func (tr TestConfig) getValStakedTokens(chain ChainID, validator ValidatorID) ui log.Fatal(err, "\n", string(bz)) } - amount := gjson.Get(string(bz), `tokens`) + amount := gjson.Get(string(bz), `validator.tokens`) return uint(amount.Uint()) } @@ -611,6 +634,25 @@ func (tr TestConfig) getParam(chain ChainID, param Param) string { return value.String() } +func (tr TestConfig) getIBCTransferParams(chain ChainID) IBCTransferParams { + //#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", "ibc-transfer", "params", + `--node`, tr.getQueryNode(chain), + `-o`, `json`, + ).CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + var params IBCTransferParams + if err := json.Unmarshal(bz, ¶ms); err != nil { + log.Fatal("cannot unmarshal ibc-transfer params: ", err, "\n", string(bz)) + } + + return params +} + // getConsumerChains returns a list of consumer chains that're being secured by the provider chain, // determined by querying the provider chain. func (tr TestConfig) getConsumerChains(chain ChainID) map[ChainID]bool { diff --git a/tests/e2e/state_rapid_test.go b/tests/e2e/state_rapid_test.go index 3192662d27..1ca36d5578 100644 --- a/tests/e2e/state_rapid_test.go +++ b/tests/e2e/state_rapid_test.go @@ -3,7 +3,7 @@ package main import ( "testing" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "pgregory.net/rapid" ) @@ -40,7 +40,7 @@ func GetChainStateGen() *rapid.Generator[ChainState] { proposals := GetProposalsGen().Draw(t, "Proposals") valPowers := GetValPowersGen().Draw(t, "ValPowers") stakedTokens := GetStakedTokensGen().Draw(t, "StakedTokens") - params := GetParamsGen().Draw(t, "Params") + ibctransferparams := GetIBCTransferParamsGen().Draw(t, "IBCTransferParams") rewards := GetRewardsGen().Draw(t, "Rewards") consumerChains := GetConsumerChainsGen().Draw(t, "ConsumerChains") assignedKeys := GetAssignedKeysGen().Draw(t, "AssignedKeys") @@ -53,7 +53,7 @@ func GetChainStateGen() *rapid.Generator[ChainState] { Proposals: &proposals, ValPowers: &valPowers, StakedTokens: &stakedTokens, - Params: ¶ms, + IBCTransferParams: &ibctransferparams, Rewards: &rewards, ConsumerChains: &consumerChains, AssignedKeys: &assignedKeys, @@ -110,17 +110,26 @@ func GetRewardsGen() *rapid.Generator[Rewards] { }) } -func GetParamsGen() *rapid.Generator[[]Param] { - return rapid.Custom(func(t *rapid.T) []Param { - return rapid.SliceOf(GetParamGen()).Draw(t, "Params") +func GetIBCTransferParamsGen() *rapid.Generator[IBCTransferParams] { + return rapid.Custom(func(t *rapid.T) IBCTransferParams { + return IBCTransferParams{ + SendEnabled: rapid.Bool().Draw(t, "SendEnabled"), + ReceiveEnabled: rapid.Bool().Draw(t, "ReceiveEnabled"), + } }) + } -func GetParamGen() *rapid.Generator[Param] { - return rapid.Custom(func(t *rapid.T) Param { - return Param{ - Key: rapid.String().Draw(t, "Key"), - Value: rapid.String().Draw(t, "Value"), +func GetIBCTransferParamsProposalGen() *rapid.Generator[IBCTransferParamsProposal] { + return rapid.Custom(func(t *rapid.T) IBCTransferParamsProposal { + return IBCTransferParamsProposal{ + Title: rapid.String().Draw(t, "Title"), + Deposit: rapid.Uint().Draw(t, "Deposit"), + Status: rapid.String().Draw(t, "Status"), + Params: IBCTransferParams{ + SendEnabled: rapid.Bool().Draw(t, "SendEnabled"), + ReceiveEnabled: rapid.Bool().Draw(t, "ReceiveEnabled"), + }, } }) } @@ -173,7 +182,7 @@ func GetProposalGen() *rapid.Generator[Proposal] { GetConsumerAdditionProposalGen().AsAny(), GetConsumerRemovalProposalGen().AsAny(), GetTextProposalGen().AsAny(), - GetParamsProposalGen().AsAny(), + GetIBCTransferParamsProposalGen().AsAny(), ) return gen.Draw(t, "Proposal").(Proposal) }) @@ -213,18 +222,6 @@ func GetTextProposalGen() *rapid.Generator[TextProposal] { }) } -func GetParamsProposalGen() *rapid.Generator[ParamsProposal] { - return rapid.Custom(func(t *rapid.T) ParamsProposal { - return ParamsProposal{ - Subspace: rapid.String().Draw(t, "Subspace"), - Key: rapid.String().Draw(t, "Key"), - Value: rapid.String().Draw(t, "Value"), - Deposit: rapid.Uint().Draw(t, "Deposit"), - Status: rapid.String().Draw(t, "Status"), - } - }) -} - func GetHeightGen() *rapid.Generator[clienttypes.Height] { return rapid.Custom(func(t *rapid.T) clienttypes.Height { return clienttypes.Height{ diff --git a/tests/e2e/steps_compatibility.go b/tests/e2e/steps_compatibility.go index 1fc6ced315..db65bf00f9 100644 --- a/tests/e2e/steps_compatibility.go +++ b/tests/e2e/steps_compatibility.go @@ -4,7 +4,10 @@ package main // sanity checks across different ICS versions. import ( - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "strconv" + + gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" ) func compstepStartProviderChain() []Step { @@ -135,7 +138,7 @@ func compstepsStartConsumerChain(consumerName string, proposalIndex, chainIndex Chain: ChainID(consumerName), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, - Status: "PROPOSAL_STATUS_PASSED", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), }, }, ValBalances: &map[ValidatorID]uint{ diff --git a/tests/e2e/steps_consumer_misbehaviour.go b/tests/e2e/steps_consumer_misbehaviour.go index 3cb4ce0f1b..8eb7a72973 100644 --- a/tests/e2e/steps_consumer_misbehaviour.go +++ b/tests/e2e/steps_consumer_misbehaviour.go @@ -1,7 +1,10 @@ package main import ( - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "strconv" + + gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" ) // starts a provider chain and a consumer chain with two validators, @@ -93,7 +96,7 @@ func stepsStartChainsWithSoftOptOut(consumerName string) []Step { Chain: ChainID(consumerName), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, - Status: "PROPOSAL_STATUS_PASSED", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), }, }, ValBalances: &map[ValidatorID]uint{ diff --git a/tests/e2e/steps_democracy.go b/tests/e2e/steps_democracy.go index 30288e7ba9..82e1d237af 100644 --- a/tests/e2e/steps_democracy.go +++ b/tests/e2e/steps_democracy.go @@ -1,5 +1,11 @@ package main +import ( + "strconv" + + gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1" +) + const consumerRewardDenom = "ibc/3C3D7B3BE4ECC85A0E5B52A3AEC3B7DFC2AA9CA47C37821E57020D6807043BE9" func stepsDemocracy(consumerName string, expectRegisteredRewardDistribution bool) []Step { @@ -25,6 +31,12 @@ func stepsDemocracy(consumerName string, expectRegisteredRewardDistribution bool IsIncrementalReward: true, IsNativeDenom: true, }, + // Check that delegating on gov-consumer does not change validator powers + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 511, + ValidatorID("bob"): 500, + ValidatorID("carol"): 500, + }, }, }, }, @@ -62,14 +74,12 @@ func stepsDemocracy(consumerName string, expectRegisteredRewardDistribution bool }, }, { - // this proposal will allow ibc transfer by setting SendEnabled to true - Action: SubmitParamChangeLegacyProposalAction{ - Chain: ChainID(consumerName), - From: ValidatorID("alice"), - Deposit: 10000001, - Subspace: "transfer", - Key: "SendEnabled", - Value: true, + // whitelisted legacy proposal can only handle ibctransfer.SendEnabled/ReceiveEnabled + Action: SubmitEnableTransfersProposalAction{ + Chain: ChainID(consumerName), + From: ValidatorID("alice"), + Deposit: 10000001, + Title: "Enable IBC Send", }, State: State{ ChainID(consumerName): ChainState{ @@ -77,15 +87,13 @@ func stepsDemocracy(consumerName string, expectRegisteredRewardDistribution bool ValidatorID("alice"): 9889999998, ValidatorID("bob"): 9960000001, }, - // Check that the "SendEnabled" transfer parameter is set to false - Params: &([]Param{{Subspace: "transfer", Key: "SendEnabled", Value: "false"}}), + // confirm the Proposals: &map[uint]Proposal{ - 1: ParamsProposal{ - Deposit: 10000001, - Status: "PROPOSAL_STATUS_VOTING_PERIOD", - Subspace: "transfer", - Key: "SendEnabled", - Value: "true", + 1: IBCTransferParamsProposal{ + Deposit: 10000001, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), + Title: "Enable IBC Send", + Params: IBCTransferParams{SendEnabled: true, ReceiveEnabled: true}, }, }, }, @@ -108,16 +116,13 @@ func stepsDemocracy(consumerName string, expectRegisteredRewardDistribution bool }, // Check that the prop passed Proposals: &map[uint]Proposal{ - 1: ParamsProposal{ - Deposit: 10000001, - Status: "PROPOSAL_STATUS_PASSED", - Subspace: "transfer", - Key: "SendEnabled", - Value: "true", + 1: IBCTransferParamsProposal{ + Deposit: 10000001, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), + Title: "Enable IBC Send", + Params: IBCTransferParams{SendEnabled: true, ReceiveEnabled: true}, }, }, - // Check that the parameter is changed on gov-consumer chain - Params: &([]Param{{Subspace: "transfer", Key: "SendEnabled", Value: "true"}}), }, }, }, diff --git a/tests/e2e/steps_sovereign_changeover.go b/tests/e2e/steps_sovereign_changeover.go index 69e6680677..e3c6563204 100644 --- a/tests/e2e/steps_sovereign_changeover.go +++ b/tests/e2e/steps_sovereign_changeover.go @@ -1,6 +1,11 @@ package main -import clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" +import ( + "strconv" + + gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" +) // this creates new clients on both chains and a connection (connection-0) between them // connection-0 is used to create a transfer channel between the chains @@ -61,7 +66,7 @@ func stepsChangeoverToConsumer(consumerName string) []Step { Chain: ChainID(consumerName), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 111}, - Status: "PROPOSAL_STATUS_VOTING_PERIOD", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), }, }, }, @@ -82,7 +87,7 @@ func stepsChangeoverToConsumer(consumerName string) []Step { Chain: ChainID(consumerName), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 111}, - Status: "PROPOSAL_STATUS_PASSED", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), }, }, ValBalances: &map[ValidatorID]uint{ @@ -206,7 +211,7 @@ func stepsUpgradeChain() []Step { UpgradeHeight: 110, Type: "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", Deposit: 10000000, - Status: "PROPOSAL_STATUS_VOTING_PERIOD", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), }, }, }, @@ -227,7 +232,7 @@ func stepsUpgradeChain() []Step { UpgradeHeight: 110, Title: "sovereign-changeover", Type: "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", - Status: "PROPOSAL_STATUS_PASSED", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), }, }, }, diff --git a/tests/e2e/steps_start_chains.go b/tests/e2e/steps_start_chains.go index 08732e3f37..5e25981691 100644 --- a/tests/e2e/steps_start_chains.go +++ b/tests/e2e/steps_start_chains.go @@ -1,7 +1,10 @@ package main import ( - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "strconv" + + gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" ) func stepStartProviderChain() []Step { @@ -51,7 +54,7 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint Chain: ChainID(consumerName), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, - Status: "PROPOSAL_STATUS_VOTING_PERIOD", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), }, }, ProposedConsumerChains: &[]string{consumerName}, @@ -131,7 +134,7 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint Chain: ChainID(consumerName), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, - Status: "PROPOSAL_STATUS_PASSED", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), }, }, ValBalances: &map[ValidatorID]uint{ diff --git a/tests/e2e/steps_stop_chain.go b/tests/e2e/steps_stop_chain.go index 36c0788901..fbf86e4733 100644 --- a/tests/e2e/steps_stop_chain.go +++ b/tests/e2e/steps_stop_chain.go @@ -1,6 +1,11 @@ package main -import "time" +import ( + "strconv" + "time" + + gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1" +) // start relayer so that all messages are relayed func stepsStartRelayer() []Step { @@ -33,7 +38,7 @@ func stepsStopChain(consumerName string, propNumber uint) []Step { Deposit: 10000001, Chain: ChainID(consumerName), StopTime: 0, - Status: "PROPOSAL_STATUS_VOTING_PERIOD", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), }, }, ConsumerChains: &map[ChainID]bool{"consu": true}, // consumer chain not yet removed @@ -54,7 +59,7 @@ func stepsStopChain(consumerName string, propNumber uint) []Step { Deposit: 10000001, Chain: ChainID(consumerName), StopTime: 0, - Status: "PROPOSAL_STATUS_PASSED", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), }, }, ValBalances: &map[ValidatorID]uint{ @@ -91,7 +96,7 @@ func stepsConsumerRemovalPropNotPassing(consumerName string, propNumber uint) [] Deposit: 10000001, Chain: ChainID(consumerName), StopTime: 0, - Status: "PROPOSAL_STATUS_VOTING_PERIOD", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), }, }, ConsumerChains: &map[ChainID]bool{"consu": true}, // consumer chain not removed @@ -112,7 +117,7 @@ func stepsConsumerRemovalPropNotPassing(consumerName string, propNumber uint) [] Deposit: 10000001, Chain: ChainID(consumerName), StopTime: 0, - Status: "PROPOSAL_STATUS_REJECTED", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_REJECTED)), }, }, ValBalances: &map[ValidatorID]uint{ diff --git a/tests/e2e/test_driver.go b/tests/e2e/test_driver.go index 052559b3ba..0ca3bc29ed 100644 --- a/tests/e2e/test_driver.go +++ b/tests/e2e/test_driver.go @@ -80,8 +80,8 @@ func (td *DefaultDriver) runAction(action interface{}) error { td.testCfg.submitConsumerAdditionProposal(action, td.target, td.verbose) case SubmitConsumerRemovalProposalAction: td.testCfg.submitConsumerRemovalProposal(action, td.target, td.verbose) - case SubmitParamChangeLegacyProposalAction: - td.testCfg.submitParamChangeProposal(action, td.target, td.verbose) + case SubmitEnableTransfersProposalAction: + td.testCfg.submitEnableTransfersProposalAction(action, td.target, td.verbose) case VoteGovProposalAction: td.testCfg.voteGovProposal(action, td.target, td.verbose) case StartConsumerChainAction: diff --git a/tests/e2e/testdata/rapid/TestChainStateMarshalling/TestChainStateMarshalling-20240314151749-32478.fail b/tests/e2e/testdata/rapid/TestChainStateMarshalling/TestChainStateMarshalling-20240314151749-32478.fail new file mode 100644 index 0000000000..14da620099 --- /dev/null +++ b/tests/e2e/testdata/rapid/TestChainStateMarshalling/TestChainStateMarshalling-20240314151749-32478.fail @@ -0,0 +1,10 @@ +# +v0.4.8#14881217339431652995 +0x0 +0x5555555555555 +0x0 +0x0 +0x38e38e38e38e4 +0x3 +0x0 +0x0 \ No newline at end of file diff --git a/tests/e2e/testdata/rapid/TestReadAndWriteTrace/TestReadAndWriteTrace-20240314151749-32478.fail b/tests/e2e/testdata/rapid/TestReadAndWriteTrace/TestReadAndWriteTrace-20240314151749-32478.fail new file mode 100644 index 0000000000..12af62a4bf --- /dev/null +++ b/tests/e2e/testdata/rapid/TestReadAndWriteTrace/TestReadAndWriteTrace-20240314151749-32478.fail @@ -0,0 +1,18 @@ +# +v0.4.8#2933927387728423654 +0x5555555555555 +0x0 +0x0 +0x0 +0x0 +0x0 +0x5555555555555 +0x0 +0x0 +0x5555555555555 +0x0 +0x0 +0x38e38e38e38e4 +0x3 +0x0 +0x0 \ No newline at end of file diff --git a/tests/e2e/testnet-scripts/start-chain.sh b/tests/e2e/testnet-scripts/start-chain.sh index 50ac05f75b..29091d8b19 100644 --- a/tests/e2e/testnet-scripts/start-chain.sh +++ b/tests/e2e/testnet-scripts/start-chain.sh @@ -377,11 +377,11 @@ fi # poll for chain start if [[ "$USE_COMETMOCK" == "true" ]]; then set +e - until $BIN query block --node "tcp://$CHAIN_IP_PREFIX.$QUERY_IP_SUFFIX:26658"; do sleep 0.3 ; done + until $BIN query block --type=height 0 --node "tcp://$CHAIN_IP_PREFIX.$QUERY_IP_SUFFIX:26658"; do sleep 0.3 ; done set -e else set +e - until $BIN query block --node "tcp://$CHAIN_IP_PREFIX.$QUERY_IP_SUFFIX:26658" | grep -q -v '{"block_id":{"hash":"","parts":{"total":0,"hash": + until $BIN query block --type=height 0 --node "tcp://$CHAIN_IP_PREFIX.$QUERY_IP_SUFFIX:26658" | grep -q -v '{"block_id":{"hash":"","parts":{"total":0,"hash": ""}},"block":null}'; do sleep 0.3 ; done set -e fi diff --git a/tests/e2e/testnet-scripts/start-changeover.sh b/tests/e2e/testnet-scripts/start-changeover.sh index c8a8e698ae..f41b6ce626 100644 --- a/tests/e2e/testnet-scripts/start-changeover.sh +++ b/tests/e2e/testnet-scripts/start-changeover.sh @@ -179,7 +179,7 @@ QUERY_NODE_SUFFIX=$(echo "$VALIDATORS" | jq -r ".[0].ip_suffix") echo "NODE SUFFIX: $QUERY_NODE_SUFFIX" # poll for chain start set +e -until $BIN query block --node "tcp://$CHAIN_IP_PREFIX.$QUERY_NODE_SUFFIX:26658" | grep -q -v '{"block_id":{"hash":"","parts":{"total":0,"hash":""}},"block":null}'; do sleep 0.3 ; done +until $BIN query block query block --type=height 0 --node "tcp://$CHAIN_IP_PREFIX.$QUERY_NODE_SUFFIX:26658" | grep -q -v '{"block_id":{"hash":"","parts":{"total":0,"hash":""}},"block":null}'; do sleep 0.3 ; done set -e echo "done!!!!!!!!" diff --git a/tests/e2e/testnet-scripts/start-sovereign.sh b/tests/e2e/testnet-scripts/start-sovereign.sh index 443b8ab6b0..54e14dfcf3 100644 --- a/tests/e2e/testnet-scripts/start-sovereign.sh +++ b/tests/e2e/testnet-scripts/start-sovereign.sh @@ -125,7 +125,7 @@ ip netns exec $NET_NAMESPACE_NAME $BIN $ARGS start &> /$CHAIN_ID/validator$VAL_I # poll for chain start set +e -until $BIN query block --node "tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26658" | grep -q -v '{"block_id":{"hash":"","parts":{"total":0,"hash":""}},"block":null}'; do sleep 0.3 ; done +until $BIN query block --type=height 0 --node "tcp://$CHAIN_IP_PREFIX.$VAL_IP_SUFFIX:26658" | grep -q -v '{"block_id":{"hash":"","parts":{"total":0,"hash":""}},"block":null}'; do sleep 0.3 ; done set -e echo "done!!!!!!!!" diff --git a/tests/e2e/trace_handlers_test.go b/tests/e2e/trace_handlers_test.go index 9b83d1c774..8fcbb60c67 100644 --- a/tests/e2e/trace_handlers_test.go +++ b/tests/e2e/trace_handlers_test.go @@ -6,9 +6,11 @@ import ( "log" "os" "path/filepath" + "strconv" "testing" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/google/go-cmp/cmp" ) @@ -28,7 +30,7 @@ var proposalInStateSteps = []Step{ Deposit: 10000001, Chain: ChainID("foo"), StopTime: 0, - Status: "PROPOSAL_STATUS_VOTING_PERIOD", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), }, }, }, @@ -114,22 +116,20 @@ func TestMarshalAndUnmarshalChainState(t *testing.T) { Chain: ChainID("test"), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 5, RevisionHeight: 5}, - Status: "PROPOSAL_STATUS_VOTING_PERIOD", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), }, }, }}, - "params-proposal": {ChainState{ + "IBC trasfer update params": {ChainState{ ValBalances: &map[ValidatorID]uint{ ValidatorID("alice"): 9889999998, ValidatorID("bob"): 9960000001, }, Proposals: &map[uint]Proposal{ - 1: ParamsProposal{ - Deposit: 10000001, - Status: "PROPOSAL_STATUS_VOTING_PERIOD", - Subspace: "staking", - Key: "MaxValidators", - Value: "105", + 1: IBCTransferParamsProposal{ + Deposit: 10000001, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), + Params: IBCTransferParams{true, true}, }, }, }}, @@ -139,7 +139,7 @@ func TestMarshalAndUnmarshalChainState(t *testing.T) { Deposit: 10000001, Chain: ChainID("test123"), StopTime: 5000000000, - Status: "PROPOSAL_STATUS_PASSED", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), }, }, ValBalances: &map[ValidatorID]uint{ diff --git a/tests/e2e/tracehandler_testdata/changeover.json b/tests/e2e/tracehandler_testdata/changeover.json index 47d6fc621d..b7f3de992e 100644 --- a/tests/e2e/tracehandler_testdata/changeover.json +++ b/tests/e2e/tracehandler_testdata/changeover.json @@ -20,7 +20,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -50,7 +50,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -96,7 +96,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -143,7 +143,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -159,7 +159,7 @@ "UpgradeHeight": 110, "Type": "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", "Deposit": 10000000, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + "Status": "2" }, "Type": "main.UpgradeProposal" } @@ -185,7 +185,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -201,7 +201,7 @@ "UpgradeHeight": 110, "Type": "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", "Deposit": 10000000, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" }, "Type": "main.UpgradeProposal" } @@ -240,7 +240,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -257,7 +257,7 @@ "InitialHeight": { "revision_height": 111 }, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + "Status": "2" }, "Type": "main.ConsumerAdditionProposal" } @@ -290,7 +290,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -307,7 +307,7 @@ "InitialHeight": { "revision_height": 111 }, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" }, "Type": "main.ConsumerAdditionProposal" } @@ -349,7 +349,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -368,7 +368,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -419,7 +419,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -449,7 +449,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -468,7 +468,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -498,7 +498,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -526,7 +526,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -556,7 +556,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -575,7 +575,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -605,7 +605,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, diff --git a/tests/e2e/tracehandler_testdata/consumer-double-sign.json b/tests/e2e/tracehandler_testdata/consumer-double-sign.json index e93049cf8b..cf113f3db9 100644 --- a/tests/e2e/tracehandler_testdata/consumer-double-sign.json +++ b/tests/e2e/tracehandler_testdata/consumer-double-sign.json @@ -33,7 +33,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -70,7 +70,7 @@ ], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -87,7 +87,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + "Status": "2" }, "Type": "main.ConsumerAdditionProposal" } @@ -111,7 +111,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -155,7 +155,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -197,7 +197,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -214,7 +214,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" }, "Type": "main.ConsumerAdditionProposal" } @@ -256,7 +256,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -275,7 +275,7 @@ "ProposedConsumerChains": [], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -326,7 +326,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -349,7 +349,7 @@ "bob": 500000000, "carol": 500000000 }, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -376,7 +376,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -399,7 +399,7 @@ "bob": 475000000, "carol": 500000000 }, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -429,7 +429,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -452,7 +452,7 @@ "bob": 475000000, "carol": 500000000 }, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, diff --git a/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json b/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json index 43e242e7dc..d2df468fb3 100644 --- a/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json +++ b/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json @@ -27,7 +27,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -62,7 +62,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -103,7 +103,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -142,7 +142,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -159,7 +159,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" }, "Type": "main.ConsumerAdditionProposal" } @@ -189,7 +189,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -207,7 +207,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -259,7 +259,7 @@ "bob": 20 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -277,7 +277,7 @@ "bob": 20 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -306,7 +306,7 @@ "bob": 20 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -347,7 +347,7 @@ "bob": 20 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -368,7 +368,7 @@ "alice": 511000000, "bob": 20000000 }, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -397,7 +397,7 @@ "bob": 20 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -418,7 +418,7 @@ "alice": 485450000, "bob": 20000000 }, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, diff --git a/tests/e2e/tracehandler_testdata/democracy.json b/tests/e2e/tracehandler_testdata/democracy.json index 10c9838122..72b2b6c508 100644 --- a/tests/e2e/tracehandler_testdata/democracy.json +++ b/tests/e2e/tracehandler_testdata/democracy.json @@ -33,7 +33,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -70,7 +70,7 @@ ], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -87,7 +87,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + "Status": "2" }, "Type": "main.ConsumerAdditionProposal" } @@ -111,7 +111,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -155,7 +155,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -197,7 +197,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -214,7 +214,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" }, "Type": "main.ConsumerAdditionProposal" } @@ -256,7 +256,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -275,7 +275,7 @@ "ProposedConsumerChains": [], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -342,7 +342,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -361,7 +361,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -390,7 +390,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -420,7 +420,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -449,7 +449,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -478,12 +478,16 @@ "democ": { "ValBalances": null, "ProposedConsumerChains": null, - "ValPowers": null, + "ValPowers": { + "alice": 511, + "bob": 500, + "carol": 500 + }, "StakedTokens": { "alice": 100000000, "bob": 40000000 }, - "Params": null, + "IBCTransferParams": null, "Rewards": { "IsRewarded": { "alice": true, @@ -524,7 +528,7 @@ "alice": 100500000, "bob": 40000000 }, - "Params": null, + "IBCTransferParams": null, "Rewards": { "IsRewarded": { "alice": true, @@ -545,14 +549,12 @@ } }, { - "ActionType": "main.SubmitParamChangeLegacyProposalAction", + "ActionType": "main.SubmitEnableTransfersProposalAction", "Action": { "Chain": "democ", "From": "alice", - "Deposit": 10000001, - "Subspace": "transfer", - "Key": "SendEnabled", - "Value": true + "Title": "Enable IBC Send", + "Deposit": 10000001 }, "State": { "democ": { @@ -563,13 +565,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": [ - { - "Subspace": "transfer", - "Key": "SendEnabled", - "Value": "false" - } - ], + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -580,13 +576,15 @@ "Proposals": { "1": { "RawProposal": { + "Title": "Enable IBC Send", "Deposit": 10000001, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD", - "Subspace": "transfer", - "Key": "SendEnabled", - "Value": "true" + "Status": "2", + "Params": { + "send_enabled": true, + "receive_enabled": true + } }, - "Type": "main.ParamsProposal" + "Type": "main.IBCTransferParamsProposal" } } } @@ -615,13 +613,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": [ - { - "Subspace": "transfer", - "Key": "SendEnabled", - "Value": "true" - } - ], + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -632,13 +624,15 @@ "Proposals": { "1": { "RawProposal": { + "Title": "Enable IBC Send", "Deposit": 10000001, - "Status": "PROPOSAL_STATUS_PASSED", - "Subspace": "transfer", - "Key": "SendEnabled", - "Value": "true" + "Status": "3", + "Params": { + "send_enabled": true, + "receive_enabled": true + } }, - "Type": "main.ParamsProposal" + "Type": "main.IBCTransferParamsProposal" } } } @@ -658,7 +652,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": { "IsRewarded": { "alice": false, @@ -691,7 +685,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -725,7 +719,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -753,7 +747,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": { "IsRewarded": { "alice": false, @@ -789,7 +783,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -808,7 +802,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -838,7 +832,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -857,7 +851,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -887,7 +881,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -915,7 +909,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -934,7 +928,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -967,7 +961,7 @@ "alice": 100500000, "bob": 40000000 }, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, diff --git a/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json b/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json index 7e6d90cace..4a37cd6d0c 100644 --- a/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json +++ b/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json @@ -33,7 +33,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -70,7 +70,7 @@ ], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -87,7 +87,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + "Status": "2" }, "Type": "main.ConsumerAdditionProposal" } @@ -111,7 +111,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -155,7 +155,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -197,7 +197,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -214,7 +214,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" }, "Type": "main.ConsumerAdditionProposal" } @@ -256,7 +256,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -275,7 +275,7 @@ "ProposedConsumerChains": [], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -342,7 +342,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -361,7 +361,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -390,7 +390,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -420,7 +420,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -449,7 +449,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -478,12 +478,16 @@ "democ": { "ValBalances": null, "ProposedConsumerChains": null, - "ValPowers": null, + "ValPowers": { + "alice": 511, + "bob": 500, + "carol": 500 + }, "StakedTokens": { "alice": 100000000, "bob": 40000000 }, - "Params": null, + "IBCTransferParams": null, "Rewards": { "IsRewarded": { "alice": true, @@ -524,7 +528,7 @@ "alice": 100500000, "bob": 40000000 }, - "Params": null, + "IBCTransferParams": null, "Rewards": { "IsRewarded": { "alice": true, @@ -545,14 +549,12 @@ } }, { - "ActionType": "main.SubmitParamChangeLegacyProposalAction", + "ActionType": "main.SubmitEnableTransfersProposalAction", "Action": { "Chain": "democ", "From": "alice", - "Deposit": 10000001, - "Subspace": "transfer", - "Key": "SendEnabled", - "Value": true + "Title": "Enable IBC Send", + "Deposit": 10000001 }, "State": { "democ": { @@ -563,13 +565,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": [ - { - "Subspace": "transfer", - "Key": "SendEnabled", - "Value": "false" - } - ], + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -580,13 +576,15 @@ "Proposals": { "1": { "RawProposal": { + "Title": "Enable IBC Send", "Deposit": 10000001, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD", - "Subspace": "transfer", - "Key": "SendEnabled", - "Value": "true" + "Status": "2", + "Params": { + "send_enabled": true, + "receive_enabled": true + } }, - "Type": "main.ParamsProposal" + "Type": "main.IBCTransferParamsProposal" } } } @@ -615,13 +613,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": [ - { - "Subspace": "transfer", - "Key": "SendEnabled", - "Value": "true" - } - ], + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -632,13 +624,15 @@ "Proposals": { "1": { "RawProposal": { + "Title": "Enable IBC Send", "Deposit": 10000001, - "Status": "PROPOSAL_STATUS_PASSED", - "Subspace": "transfer", - "Key": "SendEnabled", - "Value": "true" + "Status": "3", + "Params": { + "send_enabled": true, + "receive_enabled": true + } }, - "Type": "main.ParamsProposal" + "Type": "main.IBCTransferParamsProposal" } } } @@ -658,7 +652,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": { "IsRewarded": { "alice": false, @@ -691,7 +685,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -725,7 +719,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -753,7 +747,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": { "IsRewarded": { "alice": true, @@ -789,7 +783,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -808,7 +802,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -838,7 +832,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -857,7 +851,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -887,7 +881,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -915,7 +909,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -934,7 +928,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -967,7 +961,7 @@ "alice": 100500000, "bob": 40000000 }, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, diff --git a/tests/e2e/tracehandler_testdata/happyPath.json b/tests/e2e/tracehandler_testdata/happyPath.json index 5b9505e848..aba049cb5d 100644 --- a/tests/e2e/tracehandler_testdata/happyPath.json +++ b/tests/e2e/tracehandler_testdata/happyPath.json @@ -33,7 +33,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -70,7 +70,7 @@ ], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -87,7 +87,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + "Status": "2" }, "Type": "main.ConsumerAdditionProposal" } @@ -111,7 +111,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -155,7 +155,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -197,7 +197,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -214,7 +214,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" }, "Type": "main.ConsumerAdditionProposal" } @@ -256,7 +256,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -275,7 +275,7 @@ "ProposedConsumerChains": [], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -328,7 +328,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -347,7 +347,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -376,7 +376,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -406,7 +406,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -435,7 +435,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -467,7 +467,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -492,7 +492,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -522,7 +522,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -547,7 +547,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -577,7 +577,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -596,7 +596,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -626,7 +626,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -656,7 +656,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -675,7 +675,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -705,7 +705,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -735,7 +735,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -754,7 +754,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -784,7 +784,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -815,7 +815,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -834,7 +834,7 @@ "carol": 950 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -864,7 +864,7 @@ "carol": 950 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -892,7 +892,7 @@ "carol": 950 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -911,7 +911,7 @@ "carol": 950 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -941,7 +941,7 @@ "carol": 950 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -960,7 +960,7 @@ "carol": 950 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -991,7 +991,7 @@ "carol": 950 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1010,7 +1010,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1040,7 +1040,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1068,7 +1068,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1087,7 +1087,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1116,7 +1116,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1135,7 +1135,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1165,7 +1165,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1193,7 +1193,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1212,7 +1212,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1242,7 +1242,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1270,7 +1270,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1289,7 +1289,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1319,7 +1319,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1347,7 +1347,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1366,7 +1366,7 @@ "carol": 495 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1396,7 +1396,7 @@ "carol": 495 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1424,7 +1424,7 @@ "carol": 495 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1443,7 +1443,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1473,7 +1473,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1492,7 +1492,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1526,7 +1526,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": { "consu": true @@ -1542,7 +1542,7 @@ "Deposit": 10000001, "Chain": "consu", "StopTime": 0, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + "Status": "2" }, "Type": "main.ConsumerRemovalProposal" } @@ -1574,7 +1574,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": { "consu": true @@ -1590,7 +1590,7 @@ "Deposit": 10000001, "Chain": "consu", "StopTime": 0, - "Status": "PROPOSAL_STATUS_REJECTED" + "Status": "4" }, "Type": "main.ConsumerRemovalProposal" } @@ -1615,7 +1615,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": { "consu": true @@ -1631,7 +1631,7 @@ "Deposit": 10000001, "Chain": "consu", "StopTime": 0, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + "Status": "2" }, "Type": "main.ConsumerRemovalProposal" } @@ -1663,7 +1663,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": {}, "AssignedKeys": null, @@ -1677,7 +1677,7 @@ "Deposit": 10000001, "Chain": "consu", "StopTime": 0, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" }, "Type": "main.ConsumerRemovalProposal" } diff --git a/tests/e2e/tracehandler_testdata/multipleConsumers.json b/tests/e2e/tracehandler_testdata/multipleConsumers.json index fdb69d1e47..ac6c6b6b96 100644 --- a/tests/e2e/tracehandler_testdata/multipleConsumers.json +++ b/tests/e2e/tracehandler_testdata/multipleConsumers.json @@ -33,7 +33,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -70,7 +70,7 @@ ], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -87,7 +87,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + "Status": "2" }, "Type": "main.ConsumerAdditionProposal" } @@ -111,7 +111,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -155,7 +155,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -197,7 +197,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -214,7 +214,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" }, "Type": "main.ConsumerAdditionProposal" } @@ -256,7 +256,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -275,7 +275,7 @@ "ProposedConsumerChains": [], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -335,7 +335,7 @@ ], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -352,7 +352,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + "Status": "2" }, "Type": "main.ConsumerAdditionProposal" } @@ -376,7 +376,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -420,7 +420,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -462,7 +462,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -479,7 +479,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" }, "Type": "main.ConsumerAdditionProposal" } @@ -521,7 +521,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -540,7 +540,7 @@ "ProposedConsumerChains": [], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -593,7 +593,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -612,7 +612,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -631,7 +631,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -661,7 +661,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -680,7 +680,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -699,7 +699,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -729,7 +729,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -748,7 +748,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -767,7 +767,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -797,7 +797,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -816,7 +816,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -835,7 +835,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -865,7 +865,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -884,7 +884,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -903,7 +903,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -933,7 +933,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -952,7 +952,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -971,7 +971,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1002,7 +1002,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1021,7 +1021,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1040,7 +1040,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1070,7 +1070,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1089,7 +1089,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1108,7 +1108,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1138,7 +1138,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1157,7 +1157,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1176,7 +1176,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1204,7 +1204,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1223,7 +1223,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1242,7 +1242,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1272,7 +1272,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1291,7 +1291,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1310,7 +1310,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1340,7 +1340,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1359,7 +1359,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1389,7 +1389,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1408,7 +1408,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1436,7 +1436,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1455,7 +1455,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1474,7 +1474,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1504,7 +1504,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1523,7 +1523,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1542,7 +1542,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1572,7 +1572,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1591,7 +1591,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1610,7 +1610,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1638,7 +1638,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1657,7 +1657,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1676,7 +1676,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1706,7 +1706,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1725,7 +1725,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1744,7 +1744,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1774,7 +1774,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1793,7 +1793,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1812,7 +1812,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1840,7 +1840,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1859,7 +1859,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1878,7 +1878,7 @@ "carol": 495 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1908,7 +1908,7 @@ "carol": 495 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1927,7 +1927,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1946,7 +1946,7 @@ "carol": 495 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1976,7 +1976,7 @@ "carol": 495 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1995,7 +1995,7 @@ "carol": 495 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2014,7 +2014,7 @@ "carol": 495 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2042,7 +2042,7 @@ "carol": 495 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2061,7 +2061,7 @@ "carol": 495 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2080,7 +2080,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2110,7 +2110,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2129,7 +2129,7 @@ "carol": 495 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2148,7 +2148,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2178,7 +2178,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2197,7 +2197,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2216,7 +2216,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2244,7 +2244,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2263,7 +2263,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2282,7 +2282,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2312,7 +2312,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2331,7 +2331,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2350,7 +2350,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2380,7 +2380,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2399,7 +2399,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2418,7 +2418,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2448,7 +2448,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -2467,7 +2467,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, diff --git a/tests/e2e/tracehandler_testdata/shorthappy.json b/tests/e2e/tracehandler_testdata/shorthappy.json index 607c1d6d7c..490d67e5c5 100644 --- a/tests/e2e/tracehandler_testdata/shorthappy.json +++ b/tests/e2e/tracehandler_testdata/shorthappy.json @@ -33,7 +33,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -70,7 +70,7 @@ ], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -87,7 +87,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + "Status": "2" }, "Type": "main.ConsumerAdditionProposal" } @@ -111,7 +111,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -155,7 +155,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -197,7 +197,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -214,7 +214,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" }, "Type": "main.ConsumerAdditionProposal" } @@ -256,7 +256,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -275,7 +275,7 @@ "ProposedConsumerChains": [], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -328,7 +328,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -347,7 +347,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -376,7 +376,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -406,7 +406,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -435,7 +435,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -465,7 +465,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -484,7 +484,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -514,7 +514,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -545,7 +545,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -564,7 +564,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -594,7 +594,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -622,7 +622,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -641,7 +641,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -670,7 +670,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -689,7 +689,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -719,7 +719,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -747,7 +747,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -766,7 +766,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -796,7 +796,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -824,7 +824,7 @@ "carol": 501 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -843,7 +843,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -873,7 +873,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -901,7 +901,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -920,7 +920,7 @@ "carol": 495 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -950,7 +950,7 @@ "carol": 495 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -978,7 +978,7 @@ "carol": 495 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -997,7 +997,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1027,7 +1027,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1046,7 +1046,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -1080,7 +1080,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": { "consu": true @@ -1096,7 +1096,7 @@ "Deposit": 10000001, "Chain": "consu", "StopTime": 0, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + "Status": "2" }, "Type": "main.ConsumerRemovalProposal" } @@ -1128,7 +1128,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": { "consu": true @@ -1144,7 +1144,7 @@ "Deposit": 10000001, "Chain": "consu", "StopTime": 0, - "Status": "PROPOSAL_STATUS_REJECTED" + "Status": "4" }, "Type": "main.ConsumerRemovalProposal" } @@ -1169,7 +1169,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": { "consu": true @@ -1185,7 +1185,7 @@ "Deposit": 10000001, "Chain": "consu", "StopTime": 0, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + "Status": "2" }, "Type": "main.ConsumerRemovalProposal" } @@ -1217,7 +1217,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": {}, "AssignedKeys": null, @@ -1231,7 +1231,7 @@ "Deposit": 10000001, "Chain": "consu", "StopTime": 0, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" }, "Type": "main.ConsumerRemovalProposal" } diff --git a/tests/e2e/tracehandler_testdata/slashThrottle.json b/tests/e2e/tracehandler_testdata/slashThrottle.json index e99e7e2973..9d35c04d85 100644 --- a/tests/e2e/tracehandler_testdata/slashThrottle.json +++ b/tests/e2e/tracehandler_testdata/slashThrottle.json @@ -33,7 +33,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -70,7 +70,7 @@ ], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -87,7 +87,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + "Status": "2" }, "Type": "main.ConsumerAdditionProposal" } @@ -111,7 +111,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -155,7 +155,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": { @@ -197,7 +197,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -214,7 +214,7 @@ "InitialHeight": { "revision_height": 1 }, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" }, "Type": "main.ConsumerAdditionProposal" } @@ -256,7 +256,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -275,7 +275,7 @@ "ProposedConsumerChains": [], "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -328,7 +328,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -347,7 +347,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -376,7 +376,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -406,7 +406,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -435,7 +435,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -463,7 +463,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -482,7 +482,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -512,7 +512,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -531,7 +531,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -559,7 +559,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -578,7 +578,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -608,7 +608,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -627,7 +627,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -655,7 +655,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -674,7 +674,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -697,7 +697,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -716,7 +716,7 @@ "carol": 500 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -742,7 +742,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -761,7 +761,7 @@ "carol": 0 }, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, @@ -790,7 +790,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": { "consu": true @@ -806,7 +806,7 @@ "Deposit": 10000001, "Chain": "consu", "StopTime": 0, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + "Status": "2" }, "Type": "main.ConsumerRemovalProposal" } @@ -838,7 +838,7 @@ "ProposedConsumerChains": null, "ValPowers": null, "StakedTokens": null, - "Params": null, + "IBCTransferParams": null, "Rewards": null, "ConsumerChains": {}, "AssignedKeys": null, @@ -852,7 +852,7 @@ "Deposit": 10000001, "Chain": "consu", "StopTime": 0, - "Status": "PROPOSAL_STATUS_PASSED" + "Status": "3" }, "Type": "main.ConsumerRemovalProposal" } diff --git a/tests/integration/changeover.go b/tests/integration/changeover.go index bd94857598..3c258dfc24 100644 --- a/tests/integration/changeover.go +++ b/tests/integration/changeover.go @@ -1,8 +1,8 @@ package integration import ( - transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" ) func (suite *CCVTestSuite) TestRecycleTransferChannel() { diff --git a/tests/integration/common.go b/tests/integration/common.go index a4ff9e254a..4858c376e2 100644 --- a/tests/integration/common.go +++ b/tests/integration/common.go @@ -4,12 +4,12 @@ import ( "fmt" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" - "github.com/cosmos/ibc-go/v7/modules/core/exported" - ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctesting "github.com/cosmos/ibc-go/v7/testing" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" + "github.com/cosmos/ibc-go/v8/modules/core/exported" + ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v8/testing" "github.com/stretchr/testify/require" "cosmossdk.io/math" @@ -22,10 +22,10 @@ import ( abci "github.com/cometbft/cometbft/abci/types" tmtypes "github.com/cometbft/cometbft/types" - icstestingutils "github.com/cosmos/interchain-security/v4/testutil/ibc_testing" - testutil "github.com/cosmos/interchain-security/v4/testutil/integration" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + icstestingutils "github.com/cosmos/interchain-security/v5/testutil/ibc_testing" + testutil "github.com/cosmos/interchain-security/v5/testutil/integration" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // ChainType defines the type of chain (either provider or consumer) @@ -54,7 +54,7 @@ func (s *CCVTestSuite) consumerCtx() sdk.Context { return s.consumerChain.GetContext() } -func (s *CCVTestSuite) providerBondDenom() string { +func (s *CCVTestSuite) providerBondDenom() (string, error) { return s.providerApp.GetTestStakingKeeper().BondDenom(s.providerCtx()) } @@ -67,8 +67,8 @@ func (s *CCVTestSuite) getValByIdx(index int) (validator stakingtypes.Validator, } func (s *CCVTestSuite) getVal(ctx sdk.Context, valAddr sdk.ValAddress) stakingtypes.Validator { - validator, found := s.providerApp.GetTestStakingKeeper().GetValidator(s.providerCtx(), valAddr) - s.Require().True(found) + validator, err := s.providerApp.GetTestStakingKeeper().GetValidator(s.providerCtx(), valAddr) + s.Require().NoError(err) return validator } @@ -90,7 +90,9 @@ func (s *CCVTestSuite) setDefaultValSigningInfo(tmVal tmtypes.Validator) { } func getBalance(s *CCVTestSuite, providerCtx sdk.Context, delAddr sdk.AccAddress) math.Int { - return s.providerApp.GetTestBankKeeper().GetBalance(providerCtx, delAddr, s.providerBondDenom()).Amount + denom, err := s.providerBondDenom() + s.Require().NoError(err) + return s.providerApp.GetTestBankKeeper().GetBalance(providerCtx, delAddr, denom).Amount } // delegateAndUndelegate delegates bondAmt from delAddr to the first validator @@ -147,12 +149,12 @@ func delegateAndRedelegate(s *CCVTestSuite, delAddr sdk.AccAddress, } // delegate delegates bondAmt to the first validator -func delegate(s *CCVTestSuite, delAddr sdk.AccAddress, bondAmt math.Int) (initBalance math.Int, shares sdk.Dec, valAddr sdk.ValAddress) { +func delegate(s *CCVTestSuite, delAddr sdk.AccAddress, bondAmt math.Int) (initBalance math.Int, shares math.LegacyDec, valAddr sdk.ValAddress) { return delegateByIdx(s, delAddr, bondAmt, 0) } // delegateByIdx delegates bondAmt to the validator at specified index in provider val set -func delegateByIdx(s *CCVTestSuite, delAddr sdk.AccAddress, bondAmt math.Int, idx int) (initBalance math.Int, shares sdk.Dec, valAddr sdk.ValAddress) { +func delegateByIdx(s *CCVTestSuite, delAddr sdk.AccAddress, bondAmt math.Int, idx int) (initBalance math.Int, shares math.LegacyDec, valAddr sdk.ValAddress) { initBalance = getBalance(s, s.providerCtx(), delAddr) // choose a validator validator, valAddr := s.getValByIdx(idx) @@ -172,8 +174,8 @@ func delegateByIdx(s *CCVTestSuite, delAddr sdk.AccAddress, bondAmt math.Int, id } // undelegate unbonds an amount of delegator shares from a given validator -func undelegate(s *CCVTestSuite, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount sdk.Dec) (valsetUpdateId uint64) { - _, err := s.providerApp.GetTestStakingKeeper().Undelegate(s.providerCtx(), delAddr, valAddr, sharesAmount) +func undelegate(s *CCVTestSuite, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount math.LegacyDec) (valsetUpdateId uint64) { + _, _, err := s.providerApp.GetTestStakingKeeper().Undelegate(s.providerCtx(), delAddr, valAddr, sharesAmount) s.Require().NoError(err) // save the current valset update ID @@ -185,7 +187,7 @@ func undelegate(s *CCVTestSuite, delAddr sdk.AccAddress, valAddr sdk.ValAddress, // Executes a BeginRedelegation (unbonding and redelegation) operation // on the provider chain using delegated funds from delAddr func redelegate(s *CCVTestSuite, delAddr sdk.AccAddress, valSrcAddr sdk.ValAddress, - valDstAddr sdk.ValAddress, sharesAmount sdk.Dec, + valDstAddr sdk.ValAddress, sharesAmount math.LegacyDec, ) { stakingKeeper := s.providerApp.GetTestStakingKeeper() ctx := s.providerCtx() @@ -200,10 +202,11 @@ func redelegate(s *CCVTestSuite, delAddr sdk.AccAddress, valSrcAddr sdk.ValAddre ) s.Require().NoError(err) - providerUnbondingPeriod := stakingKeeper.UnbondingTime(ctx) + providerUnbondingPeriod, err := stakingKeeper.UnbondingTime(ctx) + s.Require().NoError(err) - valSrc, found := stakingKeeper.GetValidator(ctx, valSrcAddr) - s.Require().True(found) + valSrc, err := stakingKeeper.GetValidator(ctx, valSrcAddr) + s.Require().NoError(err) // Completion time of redelegation operation will be after unbonding period if source val is bonded if valSrc.IsBonded() { @@ -300,7 +303,8 @@ func relayAllCommittedPackets( // to be one day larger than the consumer unbonding period. func incrementTimeByUnbondingPeriod(s *CCVTestSuite, chainType ChainType) { // Get unboding periods - providerUnbondingPeriod := s.providerApp.GetTestStakingKeeper().UnbondingTime(s.providerCtx()) + providerUnbondingPeriod, err := s.providerApp.GetTestStakingKeeper().UnbondingTime(s.providerCtx()) + s.Require().NoError(err) consumerUnbondingPeriod := s.consumerApp.GetConsumerKeeper().GetUnbondingPeriod(s.consumerCtx()) var jumpPeriod time.Duration if chainType == Provider { @@ -353,8 +357,8 @@ func checkCCVUnbondingOp(s *CCVTestSuite, providerCtx sdk.Context, chainID strin func checkRedelegations(s *CCVTestSuite, delAddr sdk.AccAddress, expect uint16, ) []stakingtypes.Redelegation { - redelegations := s.providerApp.GetTestStakingKeeper().GetRedelegations(s.providerCtx(), delAddr, 2) - + redelegations, err := s.providerApp.GetTestStakingKeeper().GetRedelegations(s.providerCtx(), delAddr, 2) + s.Require().NoError(err) s.Require().Len(redelegations, int(expect)) return redelegations } @@ -367,7 +371,11 @@ func checkRedelegationEntryCompletionTime( } func getStakingUnbondingDelegationEntry(ctx sdk.Context, k testutil.TestStakingKeeper, id uint64) (stakingUnbondingOp stakingtypes.UnbondingDelegationEntry, found bool) { - stakingUbd, found := k.GetUnbondingDelegationByUnbondingID(ctx, id) + found := false + stakingUbd, err := k.GetUnbondingDelegationByUnbondingID(ctx, id) + if err != nil { + return found + } for _, entry := range stakingUbd.Entries { if entry.UnbondingId == id { @@ -547,11 +555,11 @@ func (suite *CCVTestSuite) CreateCustomClient(endpoint *ibctesting.Endpoint, unb suite.Require().Equal(exported.Tendermint, endpoint.ClientConfig.GetClientType(), "only Tendermint client supported") tmConfig, ok := endpoint.ClientConfig.(*ibctesting.TendermintConfig) - require.True(endpoint.Chain.T, ok) + require.True(endpoint.Chain.TB, ok) tmConfig.UnbondingPeriod = unbondingPeriod trustPeriod, err := ccv.CalculateTrustPeriod(unbondingPeriod, providertypes.DefaultTrustingPeriodFraction) - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) tmConfig.TrustingPeriod = trustPeriod height := endpoint.Counterparty.Chain.LastHeader.GetHeight().(clienttypes.Height) @@ -565,13 +573,13 @@ func (suite *CCVTestSuite) CreateCustomClient(endpoint *ibctesting.Endpoint, unb msg, err := clienttypes.NewMsgCreateClient( clientState, consensusState, endpoint.Chain.SenderAccount.GetAddress().String(), ) - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) res, err := endpoint.Chain.SendMsgs(msg) - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) endpoint.ClientID, err = ibctesting.ParseClientIDFromEvents(res.GetEvents()) - require.NoError(endpoint.Chain.T, err) + require.NoError(endpoint.Chain.TB, err) } // GetConsumerEndpointClientAndConsState returns the client and consensus state @@ -601,8 +609,8 @@ func (s *CCVTestSuite) setupValidatorPowers(powers []int64) { delAddr := s.providerChain.SenderAccount.GetAddress() s.Require().Equal(len(powers), len(s.providerChain.Vals.Validators)) for idx := range s.providerChain.Vals.Validators { - bondAmt := sdk.NewInt(powers[idx]).Mul(sdk.DefaultPowerReduction) - bondAmt = bondAmt.Sub(sdk.NewInt(1)) // 1 token is bonded during the initial setup + bondAmt := math.NewInt(powers[idx]).Mul(sdk.DefaultPowerReduction) + bondAmt = bondAmt.Sub(math.NewInt(1)) // 1 token is bonded during the initial setup delegateByIdx(s, delAddr, bondAmt, idx) } @@ -611,17 +619,21 @@ func (s *CCVTestSuite) setupValidatorPowers(powers []int64) { stakingKeeper := s.providerApp.GetTestStakingKeeper() expectedTotalPower := int64(0) for idx, val := range s.providerChain.Vals.Validators { - actualPower := stakingKeeper.GetLastValidatorPower(s.providerCtx(), sdk.ValAddress(val.Address)) + actualPower, err := stakingKeeper.GetLastValidatorPower(s.providerCtx(), sdk.ValAddress(val.Address)) + s.Require().NoError(err) s.Require().Equal(powers[idx], actualPower) expectedTotalPower += powers[idx] } - s.Require().Equal(expectedTotalPower, stakingKeeper.GetLastTotalPower(s.providerCtx()).Int64()) + + totalPower, err := stakingKeeper.GetLastTotalPower(s.providerCtx()) + s.Require().NoError(err) + s.Require().Equal(expectedTotalPower, totalPower.Int64()) } // mustGetStakingValFromTmVal returns the staking validator from the current state of the staking keeper, // corresponding to a given tendermint validator. Note this func will fail the test if the validator is not found. func (s *CCVTestSuite) mustGetStakingValFromTmVal(tmVal tmtypes.Validator) (stakingVal stakingtypes.Validator) { - stakingVal, found := s.providerApp.GetTestStakingKeeper().GetValidatorByConsAddr(s.providerCtx(), sdk.ConsAddress(tmVal.Address)) - s.Require().True(found) + stakingVal, err := s.providerApp.GetTestStakingKeeper().GetValidatorByConsAddr(s.providerCtx(), sdk.ConsAddress(tmVal.Address)) + s.Require().NoError(err) return stakingVal } diff --git a/tests/integration/democracy.go b/tests/integration/democracy.go index bbada900a8..63ca348bf8 100644 --- a/tests/integration/democracy.go +++ b/tests/integration/democracy.go @@ -3,20 +3,23 @@ package integration import ( "time" - ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibctesting "github.com/cosmos/ibc-go/v8/testing" "github.com/stretchr/testify/suite" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + sdkdistrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" - icstestingutils "github.com/cosmos/interchain-security/v4/testutil/ibc_testing" - testutil "github.com/cosmos/interchain-security/v4/testutil/integration" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" + icstestingutils "github.com/cosmos/interchain-security/v5/testutil/ibc_testing" + testutil "github.com/cosmos/interchain-security/v5/testutil/integration" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" ) type ConsumerDemocracyTestSuite struct { @@ -74,15 +77,18 @@ func (s *ConsumerDemocracyTestSuite) TestDemocracyRewardsDistribution() { accountKeeper := s.consumerApp.GetTestAccountKeeper() distrKeeper := s.consumerApp.GetTestDistributionKeeper() bankKeeper := s.consumerApp.GetTestBankKeeper() - bondDenom := stakingKeeper.BondDenom(s.consumerCtx()) + bondDenom, err := stakingKeeper.BondDenom(s.consumerCtx()) + s.Require().NoError(err) - currentRepresentativesRewards := map[string]sdk.Dec{} - nextRepresentativesRewards := map[string]sdk.Dec{} + currentRepresentativesRewards := map[string]math.LegacyDec{} + nextRepresentativesRewards := map[string]math.LegacyDec{} representativesTokens := map[string]math.Int{} - for _, representative := range stakingKeeper.GetAllValidators(s.consumerCtx()) { - currentRepresentativesRewards[representative.OperatorAddress] = sdk.NewDec(0) - nextRepresentativesRewards[representative.OperatorAddress] = sdk.NewDec(0) + representatives, err := stakingKeeper.GetAllValidators(s.consumerCtx()) + s.Require().NoError(err) + for _, representative := range representatives { + currentRepresentativesRewards[representative.OperatorAddress] = math.LegacyNewDec(0) + nextRepresentativesRewards[representative.OperatorAddress] = math.LegacyNewDec(0) representativesTokens[representative.OperatorAddress] = representative.GetTokens() } @@ -90,30 +96,37 @@ func (s *ConsumerDemocracyTestSuite) TestDemocracyRewardsDistribution() { providerRedistributeAccount := accountKeeper.GetModuleAccount(s.consumerCtx(), consumertypes.ConsumerToSendToProviderName) // balance of consumer redistribute address will always be 0 when checked between 2 NextBlock() calls - currentDistrModuleAccountBalance := sdk.NewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), distrModuleAccount.GetAddress(), bondDenom).Amount) - currentProviderFeeAccountBalance := sdk.NewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), providerRedistributeAccount.GetAddress(), bondDenom).Amount) - currentCommunityPoolBalance := distrKeeper.GetFeePoolCommunityCoins(s.consumerCtx()).AmountOf(bondDenom) + dk, ok := distrKeeper.(sdkdistrkeeper.Keeper) + s.Require().True(ok) + feePool, err := dk.FeePool.Get(s.consumerCtx().Context()) + s.Require().NoError(err) + s.Require().NotEmpty(feePool) + currentDistrModuleAccountBalance := math.LegacyNewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), distrModuleAccount.GetAddress(), bondDenom).Amount) + currentProviderFeeAccountBalance := math.LegacyNewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), providerRedistributeAccount.GetAddress(), bondDenom).Amount) + currentCommunityPoolBalance := feePool.GetCommunityPool().AmountOf(bondDenom) for key := range currentRepresentativesRewards { representativeAddr, _ := sdk.ValAddressFromBech32(key) - representativeReward := distrKeeper.GetValidatorOutstandingRewards(s.consumerCtx(), representativeAddr).Rewards.AmountOf(bondDenom) - currentRepresentativesRewards[key] = representativeReward + representativeReward, err := distrKeeper.GetValidatorOutstandingRewards(s.consumerCtx(), representativeAddr) + s.Require().NoError(err) + currentRepresentativesRewards[key] = representativeReward.Rewards.AmountOf(bondDenom) } s.consumerChain.NextBlock() - nextDistrModuleAccountBalance := sdk.NewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), distrModuleAccount.GetAddress(), bondDenom).Amount) - nextProviderFeeAccountBalance := sdk.NewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), providerRedistributeAccount.GetAddress(), bondDenom).Amount) - nextCommunityPoolBalance := distrKeeper.GetFeePoolCommunityCoins(s.consumerCtx()).AmountOf(bondDenom) + nextDistrModuleAccountBalance := math.LegacyNewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), distrModuleAccount.GetAddress(), bondDenom).Amount) + nextProviderFeeAccountBalance := math.LegacyNewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), providerRedistributeAccount.GetAddress(), bondDenom).Amount) + nextCommunityPoolBalance := feePool.GetCommunityPool().AmountOf(bondDenom) for key := range nextRepresentativesRewards { representativeAddr, _ := sdk.ValAddressFromBech32(key) - representativeReward := distrKeeper.GetValidatorOutstandingRewards(s.consumerCtx(), representativeAddr).Rewards.AmountOf(bondDenom) - nextRepresentativesRewards[key] = representativeReward + representativeReward, err := distrKeeper.GetValidatorOutstandingRewards(s.consumerCtx(), representativeAddr) + s.Require().NoError(err) + nextRepresentativesRewards[key] = representativeReward.Rewards.AmountOf(bondDenom) } distrModuleDifference := nextDistrModuleAccountBalance.Sub(currentDistrModuleAccountBalance) providerDifference := nextProviderFeeAccountBalance.Sub(currentProviderFeeAccountBalance) communityPoolDifference := nextCommunityPoolBalance.Sub(currentCommunityPoolBalance) - representativeDifference := map[string]sdk.Dec{} + representativeDifference := map[string]math.LegacyDec{} consumerRedistributeDifference := communityPoolDifference for key, currentReward := range currentRepresentativesRewards { @@ -121,13 +134,14 @@ func (s *ConsumerDemocracyTestSuite) TestDemocracyRewardsDistribution() { consumerRedistributeDifference = consumerRedistributeDifference.Add(representativeDifference[key]) } - consumerRedistributionFraction := sdk.MustNewDecFromStr(s.consumerApp.GetConsumerKeeper().GetConsumerRedistributionFrac(s.consumerCtx())) + consumerRedistributionFraction := math.LegacyMustNewDecFromStr(s.consumerApp.GetConsumerKeeper().GetConsumerRedistributionFrac(s.consumerCtx())) // confirm that the total amount given to the community pool plus all representatives is equal to the total amount taken out of distribution s.Require().Equal(distrModuleDifference, consumerRedistributeDifference) // confirm that the percentage given to the community pool is equal to the configured community tax percentage. - s.Require().Equal(communityPoolDifference.Quo(consumerRedistributeDifference), - distrKeeper.GetCommunityTax(s.consumerCtx())) + tax, err := distrKeeper.GetCommunityTax(s.consumerCtx()) + s.Require().NoError(err) + s.Require().Equal(communityPoolDifference.Quo(consumerRedistributeDifference), tax) // check that the fraction actually kept by the consumer is the correct fraction. using InEpsilon because the math code uses truncations s.Require().InEpsilon(distrModuleDifference.Quo( providerDifference.Add(distrModuleDifference)).MustFloat64(), @@ -135,39 +149,44 @@ func (s *ConsumerDemocracyTestSuite) TestDemocracyRewardsDistribution() { // check that the fraction actually kept by the provider is the correct fraction. using InEpsilon because the math code uses truncations s.Require().InEpsilon(providerDifference.Quo( providerDifference.Add(distrModuleDifference)).MustFloat64(), - sdk.NewDec(1).Sub(consumerRedistributionFraction).MustFloat64(), float64(0.0001)) + math.LegacyNewDec(1).Sub(consumerRedistributionFraction).MustFloat64(), float64(0.0001)) - totalRepresentativePower := stakingKeeper.GetValidatorSet().TotalBondedTokens(s.consumerCtx()) + totalRepresentativePower, err := stakingKeeper.GetValidatorSet().TotalBondedTokens(s.consumerCtx()) + s.Require().NoError(err) // check that each representative has gotten the correct amount of rewards for key, representativeTokens := range representativesTokens { - powerFraction := sdk.NewDecFromInt(representativeTokens).QuoTruncate(sdk.NewDecFromInt(totalRepresentativePower)) + powerFraction := math.LegacyNewDecFromInt(representativeTokens).QuoTruncate(math.LegacyNewDecFromInt(totalRepresentativePower)) s.Require().Equal(powerFraction, representativeDifference[key].Quo(consumerRedistributeDifference.Sub(communityPoolDifference))) } } func (s *ConsumerDemocracyTestSuite) TestDemocracyGovernanceWhitelisting() { govKeeper := s.consumerApp.GetTestGovKeeper() - params := govKeeper.GetParams(s.consumerCtx()) + params, err := govKeeper.Params.Get(s.consumerCtx()) + s.Require().NoError(err) + stakingKeeper := s.consumerApp.GetTestStakingKeeper() bankKeeper := s.consumerApp.GetTestBankKeeper() accountKeeper := s.consumerApp.GetTestAccountKeeper() mintKeeper := s.consumerApp.GetTestMintKeeper() newAuthParamValue := uint64(128) - newMintParamValue := sdk.NewDecWithPrec(1, 1) // "0.100000000000000000" + newMintParamValue := math.LegacyNewDecWithPrec(1, 1) // "0.100000000000000000" votingAccounts := s.consumerChain.SenderAccounts - bondDenom := stakingKeeper.BondDenom(s.consumerCtx()) + bondDenom, err := stakingKeeper.BondDenom(s.consumerCtx()) + s.Require().NoError(err) depositAmount := params.MinDeposit duration := (3 * time.Second) params.VotingPeriod = &duration - err := govKeeper.SetParams(s.consumerCtx(), params) + err = govKeeper.Params.Set(s.consumerCtx(), params) s.Assert().NoError(err) proposer := s.consumerChain.SenderAccount s.consumerChain.NextBlock() votersOldBalances := getAccountsBalances(s.consumerCtx(), bankKeeper, bondDenom, votingAccounts) // submit proposal with forbidden and allowed changes - mintParams := mintKeeper.GetParams(s.consumerCtx()) + mintParams, err := mintKeeper.Params.Get(s.consumerCtx()) + s.Require().NoError(err) mintParams.InflationMax = newMintParamValue msg_1 := &minttypes.MsgUpdateParams{ Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), @@ -187,11 +206,15 @@ func (s *ConsumerDemocracyTestSuite) TestDemocracyGovernanceWhitelisting() { s.consumerChain.NextBlock() // at this moment, proposal is added, but not yet executed. we are saving old param values for comparison oldAuthParamValue := accountKeeper.GetParams(s.consumerCtx()).MaxMemoCharacters - oldMintParamValue := mintKeeper.GetParams(s.consumerCtx()).InflationMax + oldMintParams, err := mintKeeper.Params.Get(s.consumerCtx()) + s.Require().NoError(err) + oldMintParamValue := oldMintParams.InflationMax s.consumerChain.NextBlock() // at this moment, proposal is executed or deleted if forbidden currentAuthParamValue := accountKeeper.GetParams(s.consumerCtx()).MaxMemoCharacters - currentMintParamValue := mintKeeper.GetParams(s.consumerCtx()).InflationMax + currentMintParam, err := mintKeeper.Params.Get(s.consumerCtx()) + s.Require().NoError(err) + currentMintParamValue := currentMintParam.InflationMax // check that parameters are not changed, since the proposal contained both forbidden and allowed changes s.Assert().Equal(oldAuthParamValue, currentAuthParamValue) s.Assert().NotEqual(newAuthParamValue, currentAuthParamValue) @@ -205,9 +228,14 @@ func (s *ConsumerDemocracyTestSuite) TestDemocracyGovernanceWhitelisting() { s.Assert().NoError(err) s.consumerChain.CurrentHeader.Time = s.consumerChain.CurrentHeader.Time.Add(*params.VotingPeriod) s.consumerChain.NextBlock() - oldMintParamValue = mintKeeper.GetParams(s.consumerCtx()).InflationMax + oldMintParam, err := mintKeeper.Params.Get(s.consumerCtx()) + s.Require().NoError(err) + oldMintParamValue = oldMintParam.InflationMax s.consumerChain.NextBlock() - currentMintParamValue = mintKeeper.GetParams(s.consumerCtx()).InflationMax + currentMintParam, err = mintKeeper.Params.Get(s.consumerCtx()) + s.Require().NoError(err) + + currentMintParamValue = currentMintParam.InflationMax // check that parameters are changed, since the proposal contained only allowed changes s.Assert().Equal(newMintParamValue, currentMintParamValue) s.Assert().NotEqual(oldMintParamValue, currentMintParamValue) @@ -230,10 +258,10 @@ func (s *ConsumerDemocracyTestSuite) TestDemocracyGovernanceWhitelisting() { s.Assert().Equal(votersOldBalances, getAccountsBalances(s.consumerCtx(), bankKeeper, bondDenom, votingAccounts)) } -func submitProposalWithDepositAndVote(govKeeper testutil.TestGovKeeper, ctx sdk.Context, msgs []sdk.Msg, +func submitProposalWithDepositAndVote(govKeeper govkeeper.Keeper, ctx sdk.Context, msgs []sdk.Msg, accounts []ibctesting.SenderAccount, proposer sdk.AccAddress, depositAmount sdk.Coins, ) error { - proposal, err := govKeeper.SubmitProposal(ctx, msgs, "", "title", "summary", proposer) + proposal, err := govKeeper.SubmitProposal(ctx, msgs, "", "title", "summary", proposer, false) if err != nil { return err } diff --git a/tests/integration/distribution.go b/tests/integration/distribution.go index 25cbcb3132..c33ddada0a 100644 --- a/tests/integration/distribution.go +++ b/tests/integration/distribution.go @@ -3,16 +3,18 @@ package integration import ( "strings" - transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + "cosmossdk.io/math" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + sdkdistrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" - icstestingutils "github.com/cosmos/interchain-security/v4/testutil/integration" - consumerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + icstestingutils "github.com/cosmos/interchain-security/v5/testutil/integration" + consumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // This test is valid for minimal viable consumer chain @@ -20,7 +22,7 @@ func (s *CCVTestSuite) TestRewardsDistribution() { // set up channel and delegate some tokens in order for validator set update to be sent to the consumer chain s.SetupCCVChannel(s.path) s.SetupTransferChannel() - bondAmt := sdk.NewInt(10000000) + bondAmt := math.NewInt(10000000) delAddr := s.providerChain.SenderAccount.GetAddress() delegate(s, delAddr, bondAmt) s.providerChain.NextBlock() @@ -46,14 +48,14 @@ func (s *CCVTestSuite) TestRewardsDistribution() { // send coins to the fee pool which is used for reward distribution consumerFeePoolAddr := consumerAccountKeeper.GetModuleAccount(s.consumerCtx(), authtypes.FeeCollectorName).GetAddress() feePoolTokensOld := consumerBankKeeper.GetAllBalances(s.consumerCtx(), consumerFeePoolAddr) - fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))) + fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100))) err := consumerBankKeeper.SendCoinsFromAccountToModule(s.consumerCtx(), s.consumerChain.SenderAccount.GetAddress(), authtypes.FeeCollectorName, fees) s.Require().NoError(err) feePoolTokens := consumerBankKeeper.GetAllBalances(s.consumerCtx(), consumerFeePoolAddr) - s.Require().Equal(sdk.NewInt(100).Add(feePoolTokensOld.AmountOf(sdk.DefaultBondDenom)), feePoolTokens.AmountOf(sdk.DefaultBondDenom)) + s.Require().Equal(math.NewInt(100).Add(feePoolTokensOld.AmountOf(sdk.DefaultBondDenom)), feePoolTokens.AmountOf(sdk.DefaultBondDenom)) // calculate the reward for consumer and provider chain. Consumer will receive ConsumerRedistributeFrac, the rest is going to provider - frac, err := sdk.NewDecFromStr(s.consumerApp.GetConsumerKeeper().GetConsumerRedistributionFrac(s.consumerCtx())) + frac, err := math.LegacyNewDecFromStr(s.consumerApp.GetConsumerKeeper().GetConsumerRedistributionFrac(s.consumerCtx())) s.Require().NoError(err) consumerExpectedRewards, _ := sdk.NewDecCoinsFromCoins(feePoolTokens...).MulDec(frac).TruncateDecimal() providerExpectedRewards := feePoolTokens.Sub(consumerExpectedRewards...) @@ -110,7 +112,17 @@ func (s *CCVTestSuite) TestRewardsDistribution() { s.Require().Equal(0, len(rewardCoins)) // check that the fee pool has the expected amount of coins - communityCoins := s.providerApp.GetTestDistributionKeeper().GetFeePoolCommunityCoins(s.providerCtx()) + testDistKeeper := s.providerApp.GetTestDistributionKeeper() + // try casting to the sdk distribution keeper + sdkDistKeeper, ok := testDistKeeper.(sdkdistrkeeper.Keeper) + s.Require().True(ok) + s.Require().NotEmpty(sdkDistKeeper) + + feePool, err := sdkDistKeeper.FeePool.Get(s.consumerCtx().Context()) + s.Require().NoError(err) + s.Require().NotEmpty(feePool) + + communityCoins := feePool.GetCommunityPool() s.Require().True(communityCoins[ibcCoinIndex].Amount.Equal(sdk.NewDecCoinFromCoin(providerExpectedRewards[0]).Amount)) } @@ -121,7 +133,7 @@ func (s *CCVTestSuite) TestSendRewardsRetries() { // ccv and transmission channels setup s.SetupCCVChannel(s.path) s.SetupTransferChannel() - bondAmt := sdk.NewInt(10000000) + bondAmt := math.NewInt(10000000) delAddr := s.providerChain.SenderAccount.GetAddress() delegate(s, delAddr, bondAmt) s.providerChain.NextBlock() @@ -142,7 +154,7 @@ func (s *CCVTestSuite) TestSendRewardsRetries() { consumerParams.Set(s.consumerCtx(), ccv.KeyBlocksPerDistributionTransmission, int64(1000)) // fill fee pool - fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))) + fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100))) err := consumerBankKeeper.SendCoinsFromAccountToModule(s.consumerCtx(), s.consumerChain.SenderAccount.GetAddress(), authtypes.FeeCollectorName, fees) s.Require().NoError(err) @@ -250,7 +262,7 @@ func (s *CCVTestSuite) TestEndBlockRD() { // ccv and transmission channels setup s.SetupCCVChannel(s.path) s.SetupTransferChannel() - bondAmt := sdk.NewInt(10000000) + bondAmt := math.NewInt(10000000) delAddr := s.providerChain.SenderAccount.GetAddress() delegate(s, delAddr, bondAmt) s.providerChain.NextBlock() @@ -272,7 +284,7 @@ func (s *CCVTestSuite) TestEndBlockRD() { consumerParams.Set(s.consumerCtx(), ccv.KeyBlocksPerDistributionTransmission, int64(1000)) // fill fee pool - fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))) + fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100))) err := consumerBankKeeper.SendCoinsFromAccountToModule(s.consumerCtx(), s.consumerChain.SenderAccount.GetAddress(), authtypes.FeeCollectorName, fees) s.Require().NoError(err) @@ -335,7 +347,7 @@ func (s *CCVTestSuite) TestSendRewardsToProvider() { ctx, s.consumerChain.SenderAccount.GetAddress(), consumertypes.ConsumerToSendToProviderName, - sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), + sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100))), ) s.Require().NoError(err) }, @@ -389,7 +401,7 @@ func (s *CCVTestSuite) TestSendRewardsToProvider() { ctx, s.consumerChain.SenderAccount.GetAddress(), consumertypes.ConsumerToSendToProviderName, - sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), + sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100))), ) s.Require().NoError(err) }, @@ -412,7 +424,7 @@ func (s *CCVTestSuite) TestSendRewardsToProvider() { ctx, s.consumerChain.SenderAccount.GetAddress(), consumertypes.ConsumerToSendToProviderName, - sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), + sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100))), ) s.Require().NoError(err) }, @@ -426,7 +438,7 @@ func (s *CCVTestSuite) TestSendRewardsToProvider() { // ccv channels setup s.SetupCCVChannel(s.path) - bondAmt := sdk.NewInt(10000000) + bondAmt := math.NewInt(10000000) delAddr := s.providerChain.SenderAccount.GetAddress() delegate(s, delAddr, bondAmt) s.providerChain.NextBlock() diff --git a/tests/integration/double_vote.go b/tests/integration/double_vote.go index c22ba3b063..9ebd4b727f 100644 --- a/tests/integration/double_vote.go +++ b/tests/integration/double_vote.go @@ -1,14 +1,15 @@ package integration import ( + "cosmossdk.io/math" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" tmcrypto "github.com/cometbft/cometbft/crypto" tmtypes "github.com/cometbft/cometbft/types" - testutil "github.com/cosmos/interchain-security/v4/testutil/crypto" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + testutil "github.com/cosmos/interchain-security/v5/testutil/crypto" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) // TestHandleConsumerDoubleVoting verifies that handling a double voting evidence @@ -209,7 +210,7 @@ func (s *CCVTestSuite) TestHandleConsumerDoubleVoting() { provAddr := s.providerApp.GetProviderKeeper().GetProviderAddrFromConsumerAddr(s.providerCtx(), s.consumerChain.ChainID, consuAddr) validator, _ := s.providerApp.GetTestStakingKeeper().GetValidator(s.providerCtx(), provAddr.ToSdkConsAddr().Bytes()) - initialTokens := sdk.NewDecFromInt(validator.GetTokens()) + initialTokens := math.LegacyNewDecFromInt(validator.GetTokens()) // reset context for each run provCtx, _ := s.providerCtx().CacheContext() @@ -241,8 +242,9 @@ func (s *CCVTestSuite) TestHandleConsumerDoubleVoting() { // verifies that the val gets slashed and has fewer tokens after the slashing val, _ := s.providerApp.GetTestStakingKeeper().GetValidator(provCtx, provAddr.ToSdkConsAddr().Bytes()) - slashFraction := s.providerApp.GetTestSlashingKeeper().SlashFractionDoubleSign(provCtx) - actualTokens := sdk.NewDecFromInt(val.GetTokens()) + slashFraction, err := s.providerApp.GetTestSlashingKeeper().SlashFractionDoubleSign(provCtx) + s.Require().NoError(err) + actualTokens := math.LegacyNewDecFromInt(val.GetTokens()) s.Require().True(initialTokens.Sub(initialTokens.Mul(slashFraction)).Equal(actualTokens)) } else { s.Require().Error(err) @@ -316,11 +318,11 @@ func (s *CCVTestSuite) TestHandleConsumerDoubleVotingSlashesUndelegationsAndRele consuAddr2 := types.NewConsumerConsAddress(sdk.ConsAddress(consuVal2.Address.Bytes())) provAddr2 := s.providerApp.GetProviderKeeper().GetProviderAddrFromConsumerAddr(s.providerCtx(), s.consumerChain.ChainID, consuAddr2) - validator, found := s.providerApp.GetTestStakingKeeper().GetValidator(s.providerCtx(), provAddr.ToSdkConsAddr().Bytes()) - s.Require().True(found) + validator, err := s.providerApp.GetTestStakingKeeper().GetValidator(s.providerCtx(), provAddr.ToSdkConsAddr().Bytes()) + s.Require().NoError(err) - validator2, found := s.providerApp.GetTestStakingKeeper().GetValidator(s.providerCtx(), provAddr2.ToSdkConsAddr().Bytes()) - s.Require().True(found) + validator2, err := s.providerApp.GetTestStakingKeeper().GetValidator(s.providerCtx(), provAddr2.ToSdkConsAddr().Bytes()) + s.Require().NoError(err) s.Run("slash undelegations and redelegations when getting double voting evidence", func() { // convert validator public key @@ -328,7 +330,7 @@ func (s *CCVTestSuite) TestHandleConsumerDoubleVotingSlashesUndelegationsAndRele s.Require().NoError(err) // perform a delegation and an undelegation of the whole amount - bondAmt := sdk.NewInt(10000000) + bondAmt := math.NewInt(10000000) delAddr := s.providerChain.SenderAccount.GetAddress() // in order to perform a delegation we need to know the validator's `idx` (that might not be 0) @@ -347,24 +349,30 @@ func (s *CCVTestSuite) TestHandleConsumerDoubleVotingSlashesUndelegationsAndRele s.Require().NotZero(shares) // undelegate 1/2 of the bound amount - undelegate(s, delAddr, validator.GetOperator(), shares.Quo(sdk.NewDec(4))) - undelegate(s, delAddr, validator.GetOperator(), shares.Quo(sdk.NewDec(4))) + valAddr, err := sdk.ValAddressFromHex(validator.GetOperator()) + s.Require().NoError(err) + undelegate(s, delAddr, valAddr, shares.Quo(math.LegacyNewDec(4))) + undelegate(s, delAddr, valAddr, shares.Quo(math.LegacyNewDec(4))) // check that undelegations were successful - ubds, _ := s.providerApp.GetTestStakingKeeper().GetUnbondingDelegation(s.providerCtx(), delAddr, validator.GetOperator()) + ubds, _ := s.providerApp.GetTestStakingKeeper().GetUnbondingDelegation(s.providerCtx(), delAddr, valAddr) // should have a single entry since undelegations are merged s.Require().Len(ubds.Entries, 1) // save the delegation shares of the validator to redelegate to // Note this shares should not be slashed! - delShares := s.providerApp.GetTestStakingKeeper().Delegation(s.providerCtx(), delAddr, validator2.GetOperator()).GetShares() + valAddr2, err := sdk.ValAddressFromHex(validator2.GetOperator()) + del, err := s.providerApp.GetTestStakingKeeper().Delegation(s.providerCtx(), delAddr, valAddr2) + s.Require().NoError(err) + delShares := del.GetShares() // redelegate 1/2 of the bound amount - redelegate(s, delAddr, validator.GetOperator(), validator2.GetOperator(), shares.Quo(sdk.NewDec(4))) - redelegate(s, delAddr, validator.GetOperator(), validator2.GetOperator(), shares.Quo(sdk.NewDec(4))) + redelegate(s, delAddr, valAddr, valAddr2, shares.Quo(math.LegacyNewDec(4))) + redelegate(s, delAddr, valAddr, valAddr2, shares.Quo(math.LegacyNewDec(4))) // check that redelegation was successful - rdel := s.providerApp.GetTestStakingKeeper().GetRedelegations(s.providerCtx(), delAddr, uint16(10)) + rdel, err := s.providerApp.GetTestStakingKeeper().GetRedelegations(s.providerCtx(), delAddr, uint16(10)) + s.Require().NoError(err) s.Require().Len(rdel[0].Entries, 2) redelShares := rdel[0].Entries[0].SharesDst.Add(rdel[0].Entries[1].SharesDst) @@ -378,18 +386,20 @@ func (s *CCVTestSuite) TestHandleConsumerDoubleVotingSlashesUndelegationsAndRele ) s.Require().NoError(err) - slashFraction := s.providerApp.GetTestSlashingKeeper().SlashFractionDoubleSign(s.providerCtx()) + slashFraction, err := s.providerApp.GetTestSlashingKeeper().SlashFractionDoubleSign(s.providerCtx()) + s.Require().NoError(err) // check undelegations are slashed - ubds, _ = s.providerApp.GetTestStakingKeeper().GetUnbondingDelegation(s.providerCtx(), delAddr, validator.GetOperator()) + ubds, _ = s.providerApp.GetTestStakingKeeper().GetUnbondingDelegation(s.providerCtx(), delAddr, valAddr) s.Require().True(len(ubds.Entries) > 0) for _, unb := range ubds.Entries { - initialBalance := sdk.NewDecFromInt(unb.InitialBalance) - currentBalance := sdk.NewDecFromInt(unb.Balance) + initialBalance := math.LegacyNewDecFromInt(unb.InitialBalance) + currentBalance := math.LegacyNewDecFromInt(unb.Balance) s.Require().True(initialBalance.Sub(initialBalance.Mul(slashFraction)).Equal(currentBalance)) } // check that redelegations are slashed - delegations := s.providerApp.GetTestStakingKeeper().Delegation(s.providerCtx(), delAddr, validator2.GetOperator()) + delegations, err := s.providerApp.GetTestStakingKeeper().Delegation(s.providerCtx(), delAddr, valAddr2) + s.Require().NoError(err) s.Require().Equal(delegations.GetShares(), delShares.Add(redelShares).Sub(redelShares.Mul(slashFraction))) }) } diff --git a/tests/integration/expired_client.go b/tests/integration/expired_client.go index 1981e85828..249283ce9f 100644 --- a/tests/integration/expired_client.go +++ b/tests/integration/expired_client.go @@ -1,20 +1,20 @@ -package integration +gpackage integration import ( "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" - ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctesting "github.com/cosmos/ibc-go/v7/testing" + "cosmossdk.io/math" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" + ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v8/testing" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" abci "github.com/cometbft/cometbft/abci/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // TestVSCPacketSendWithExpiredClient tests queueing of VSCPackets when the consumer client is expired. @@ -28,7 +28,7 @@ func (s *CCVTestSuite) TestVSCPacketSendExpiredClient() { expireClient(s, Consumer) // bond some tokens on provider to change validator powers - bondAmt := sdk.NewInt(1000000) + bondAmt := math.NewInt(1000000) delAddr := s.providerChain.SenderAccount.GetAddress() delegate(s, delAddr, bondAmt) @@ -91,7 +91,7 @@ func (s *CCVTestSuite) TestConsumerPacketSendExpiredClient() { s.SetupCCVChannel(s.path) // bond some tokens on provider to change validator powers - bondAmt := sdk.NewInt(1000000) + bondAmt := math.NewInt(1000000) delAddr := s.providerChain.SenderAccount.GetAddress() delegate(s, delAddr, bondAmt) @@ -285,10 +285,10 @@ func upgradeExpiredClient(s *CCVTestSuite, clientTo ChainType) { tmClientState.AllowUpdateAfterExpiry = true hostChain.App.GetIBCKeeper().ClientKeeper.SetClientState(hostChain.GetContext(), substitute, tmClientState) - content := clienttypes.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute) + recoverMsg := clienttypes.NewMsgRecoverClient(hostChain.App.GetIBCKeeper().GetAuthority(), subject, substitute) + err = recoverMsg.ValidateBasic() + s.Require().NoError(err) - updateProp, ok := content.(*clienttypes.ClientUpdateProposal) - s.Require().True(ok) - err = hostChain.App.GetIBCKeeper().ClientKeeper.ClientUpdateProposal(hostChain.GetContext(), updateProp) + res, err := hostChain.App.GetIBCKeeper().RecoverClient(hostChain.GetContext(), recoverMsg) s.Require().NoError(err) } diff --git a/tests/integration/instance_test.go b/tests/integration/instance_test.go index d2896ad964..424c6c85f5 100644 --- a/tests/integration/instance_test.go +++ b/tests/integration/instance_test.go @@ -5,11 +5,11 @@ import ( "github.com/stretchr/testify/suite" - appConsumer "github.com/cosmos/interchain-security/v4/app/consumer" - appConsumerDemocracy "github.com/cosmos/interchain-security/v4/app/consumer-democracy" - appProvider "github.com/cosmos/interchain-security/v4/app/provider" - intg "github.com/cosmos/interchain-security/v4/tests/integration" - icstestingutils "github.com/cosmos/interchain-security/v4/testutil/ibc_testing" + appConsumer "github.com/cosmos/interchain-security/v5/app/consumer" + appConsumerDemocracy "github.com/cosmos/interchain-security/v5/app/consumer-democracy" + appProvider "github.com/cosmos/interchain-security/v5/app/provider" + intg "github.com/cosmos/interchain-security/v5/tests/integration" + icstestingutils "github.com/cosmos/interchain-security/v5/testutil/ibc_testing" ) // This file can be used as an example integration testing instance for any provider/consumer applications. diff --git a/tests/integration/key_assignment.go b/tests/integration/key_assignment.go index 20e746ae63..9f47b2ef40 100644 --- a/tests/integration/key_assignment.go +++ b/tests/integration/key_assignment.go @@ -1,16 +1,16 @@ package integration import ( - "github.com/cosmos/ibc-go/v7/testing/mock" + "cosmossdk.io/math" + "github.com/cosmos/ibc-go/v8/testing/mock" - sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" tmencoding "github.com/cometbft/cometbft/crypto/encoding" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" - providerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) func (s *CCVTestSuite) TestKeyAssignment() { @@ -69,7 +69,7 @@ func (s *CCVTestSuite) TestKeyAssignment() { } // Bond some tokens on provider to change validator powers - bondAmt := sdk.NewInt(1000000) + bondAmt := math.NewInt(1000000) delAddr := s.providerChain.SenderAccount.GetAddress() delegate(s, delAddr, bondAmt) @@ -206,7 +206,7 @@ func (s *CCVTestSuite) TestKeyAssignment() { if !tc.expError { // Bond some tokens on provider to change validator powers - bondAmt := sdk.NewInt(1000000) + bondAmt := math.NewInt(1000000) delAddr := s.providerChain.SenderAccount.GetAddress() delegate(s, delAddr, bondAmt) diff --git a/tests/integration/misbehaviour.go b/tests/integration/misbehaviour.go index acdcd0071c..912f8c71d7 100644 --- a/tests/integration/misbehaviour.go +++ b/tests/integration/misbehaviour.go @@ -3,14 +3,15 @@ package integration import ( "time" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + "cosmossdk.io/math" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" sdk "github.com/cosmos/cosmos-sdk/types" tmtypes "github.com/cometbft/cometbft/types" - testutil "github.com/cosmos/interchain-security/v4/testutil/crypto" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + testutil "github.com/cosmos/interchain-security/v5/testutil/crypto" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) // TestHandleConsumerMisbehaviour tests that handling a valid misbehaviour, @@ -58,7 +59,7 @@ func (s *CCVTestSuite) TestHandleConsumerMisbehaviour() { // we assume that all validators have the same number of initial tokens validator, _ := s.getValByIdx(0) - initialTokens := sdk.NewDecFromInt(validator.GetTokens()) + initialTokens := math.LegacyNewDecFromInt(validator.GetTokens()) err := s.providerApp.GetProviderKeeper().HandleConsumerMisbehaviour(s.providerCtx(), *misb) s.NoError(err) @@ -67,14 +68,15 @@ func (s *CCVTestSuite) TestHandleConsumerMisbehaviour() { for _, v := range clientTMValset.Validators { consuAddr := sdk.ConsAddress(v.Address.Bytes()) provAddr := s.providerApp.GetProviderKeeper().GetProviderAddrFromConsumerAddr(s.providerCtx(), s.consumerChain.ChainID, types.NewConsumerConsAddress(consuAddr)) - val, ok := s.providerApp.GetTestStakingKeeper().GetValidatorByConsAddr(s.providerCtx(), provAddr.Address) - s.Require().True(ok) + val, err := s.providerApp.GetTestStakingKeeper().GetValidatorByConsAddr(s.providerCtx(), provAddr.Address) + s.Require().NoError(err) s.Require().True(val.Jailed) s.Require().True(s.providerApp.GetTestSlashingKeeper().IsTombstoned(s.providerCtx(), provAddr.ToSdkConsAddr())) validator, _ := s.providerApp.GetTestStakingKeeper().GetValidator(s.providerCtx(), provAddr.ToSdkConsAddr().Bytes()) - slashFraction := s.providerApp.GetTestSlashingKeeper().SlashFractionDoubleSign(s.providerCtx()) - actualTokens := sdk.NewDecFromInt(validator.GetTokens()) + slashFraction, err := s.providerApp.GetTestSlashingKeeper().SlashFractionDoubleSign(s.providerCtx()) + s.Require().NoError(err) + actualTokens := math.LegacyNewDecFromInt(validator.GetTokens()) s.Require().True(initialTokens.Sub(initialTokens.Mul(slashFraction)).Equal(actualTokens)) } } diff --git a/tests/integration/normal_operations.go b/tests/integration/normal_operations.go index 81c742eeed..61f7507793 100644 --- a/tests/integration/normal_operations.go +++ b/tests/integration/normal_operations.go @@ -5,8 +5,8 @@ import ( tmproto "github.com/cometbft/cometbft/proto/tendermint/types" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // Tests the tracking of historical info in the context of new blocks being committed diff --git a/tests/integration/setup.go b/tests/integration/setup.go index e401324c82..0cd23d2a3e 100644 --- a/tests/integration/setup.go +++ b/tests/integration/setup.go @@ -3,29 +3,25 @@ package integration import ( "context" "fmt" - "sync" "testing" - transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctesting "github.com/cosmos/ibc-go/v7/testing" - "github.com/cosmos/ibc-go/v7/testing/mock" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v8/testing" + "github.com/cosmos/ibc-go/v8/testing/mock" "github.com/stretchr/testify/suite" - "github.com/cosmos/cosmos-sdk/baseapp" - store "github.com/cosmos/cosmos-sdk/store/types" + store "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" abci "github.com/cometbft/cometbft/abci/types" tmencoding "github.com/cometbft/cometbft/crypto/encoding" - icstestingutils "github.com/cosmos/interchain-security/v4/testutil/ibc_testing" - testutil "github.com/cosmos/interchain-security/v4/testutil/integration" - "github.com/cosmos/interchain-security/v4/testutil/simibc" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + icstestingutils "github.com/cosmos/interchain-security/v5/testutil/ibc_testing" + testutil "github.com/cosmos/interchain-security/v5/testutil/integration" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // Callback for instantiating a new coordinator with a provider test chains @@ -129,12 +125,6 @@ func (suite *CCVTestSuite) SetupTest() { suite.registerPacketSniffer(suite.providerChain) providerKeeper := suite.providerApp.GetProviderKeeper() - // re-assign all validator keys for the first consumer chain - providerKeeper.SetPendingConsumerAdditionProp(suite.providerCtx(), &types.ConsumerAdditionProposal{ - ChainId: icstestingutils.FirstConsumerChainID, - }) - preProposalKeyAssignment(suite, icstestingutils.FirstConsumerChainID) - // start consumer chains numConsumers := 5 suite.consumerBundles = make(map[string]*icstestingutils.ConsumerBundle) @@ -142,6 +132,11 @@ func (suite *CCVTestSuite) SetupTest() { bundle := suite.setupConsumerCallback(&suite.Suite, suite.coordinator, i) suite.consumerBundles[bundle.Chain.ChainID] = bundle suite.registerPacketSniffer(bundle.Chain) + + // re-assign all validator keys for the first consumer chain + if i == 0 { + consumerKeyAssignment(suite, icstestingutils.FirstConsumerChainID) + } } // initialize each consumer chain with it's corresponding genesis state @@ -177,7 +172,9 @@ func (s *CCVTestSuite) registerPacketSniffer(chain *ibctesting.TestChain) { s.packetSniffers = make(map[*ibctesting.TestChain]*packetSniffer) } p := newPacketSniffer() - chain.App.GetBaseApp().SetStreamingService(p) + chain.App.GetBaseApp().SetStreamingManager(store.StreamingManager{ + ABCIListeners: []store.ABCIListener{p}, + }) s.packetSniffers[chain] = p } @@ -344,7 +341,8 @@ func (s CCVTestSuite) validateEndpointsClientConfig(consumerBundle icstestinguti "unexpected unbonding period in consumer client state", ) - providerUnbondingPeriod := providerStakingKeeper.UnbondingTime(s.providerCtx()) + providerUnbondingPeriod, err := providerStakingKeeper.UnbondingTime(s.providerCtx()) + s.Require().NoError(err) cs, ok = consumerBundle.App.GetIBCKeeper().ClientKeeper.GetClientState( consumerBundle.GetCtx(), consumerBundle.Path.EndpointA.ClientID) s.Require().True(ok) @@ -355,10 +353,10 @@ func (s CCVTestSuite) validateEndpointsClientConfig(consumerBundle icstestinguti ) } -// preProposalKeyAssignment assigns keys to all provider validators for +// consumerKeyAssignmentt assigns keys to all provider validators for // the consumer with chainID before the chain is registered, i.e., // before a client to the consumer is created -func preProposalKeyAssignment(s *CCVTestSuite, chainID string) { +func consumerKeyAssignment(s *CCVTestSuite, chainID string) { providerKeeper := s.providerApp.GetProviderKeeper() for _, val := range s.providerChain.Vals.Validators { @@ -389,7 +387,7 @@ type packetSniffer struct { packets map[string]channeltypes.Packet } -var _ baseapp.StreamingService = &packetSniffer{} +var _ store.ABCIListener = &packetSniffer{} func newPacketSniffer() *packetSniffer { return &packetSniffer{ @@ -397,8 +395,8 @@ func newPacketSniffer() *packetSniffer { } } -func (ps *packetSniffer) ListenEndBlock(ctx context.Context, req abci.RequestEndBlock, res abci.ResponseEndBlock) error { - packets := simibc.ParsePacketsFromEvents(simibc.ABCIToSDKEvents(res.GetEvents())) +func (ps *packetSniffer) ListenFinalizeBlock(ctx context.Context, req abci.RequestFinalizeBlock, res abci.ResponseFinalizeBlock) error { + packets := ParsePacketsFromEvents(res.GetEvents()) for _, packet := range packets { ps.packets[getSentPacketKey(packet.Sequence, packet.SourceChannel)] = packet } @@ -411,17 +409,20 @@ func getSentPacketKey(sequence uint64, channelID string) string { return fmt.Sprintf("%s-%d", channelID, sequence) } -func (*packetSniffer) ListenBeginBlock(ctx context.Context, req abci.RequestBeginBlock, res abci.ResponseBeginBlock) error { +func (*packetSniffer) ListenCommit(ctx context.Context, res abci.ResponseCommit, cs []*store.StoreKVPair) error { return nil } -func (*packetSniffer) ListenCommit(ctx context.Context, res abci.ResponseCommit) error { - return nil -} - -func (*packetSniffer) ListenDeliverTx(ctx context.Context, req abci.RequestDeliverTx, res abci.ResponseDeliverTx) error { - return nil +// ParsePacketsFromEvents returns all packets found in events. +func ParsePacketsFromEvents(events []abci.Event) (packets []channeltypes.Packet) { + for i, ev := range events { + if ev.Type == channeltypes.EventTypeSendPacket { + packet, err := ibctesting.ParsePacketFromEvents(events[i:]) + if err != nil { + panic(err) + } + packets = append(packets, packet) + } + } + return } -func (*packetSniffer) Close() error { return nil } -func (*packetSniffer) Listeners() map[store.StoreKey][]store.WriteListener { return nil } -func (*packetSniffer) Stream(wg *sync.WaitGroup) error { return nil } diff --git a/tests/integration/slashing.go b/tests/integration/slashing.go index 2339538292..e1f6fe4cbc 100644 --- a/tests/integration/slashing.go +++ b/tests/integration/slashing.go @@ -4,13 +4,15 @@ import ( "fmt" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + "cosmossdk.io/core/comet" + "cosmossdk.io/math" + evidencetypes "cosmossdk.io/x/evidence/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkaddress "github.com/cosmos/cosmos-sdk/types/address" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -18,9 +20,9 @@ import ( "github.com/cometbft/cometbft/crypto/ed25519" tmtypes "github.com/cometbft/cometbft/types" - keepertestutil "github.com/cosmos/interchain-security/v4/testutil/keeper" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + keepertestutil "github.com/cosmos/interchain-security/v5/testutil/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // TestRelayAndApplyDowntimePacket tests that downtime slash packets can be properly relayed @@ -56,8 +58,8 @@ func (s *CCVTestSuite) TestRelayAndApplyDowntimePacket() { ) s.Require().True(found) - stakingVal, found := providerStakingKeeper.GetValidatorByConsAddr(s.providerCtx(), providerConsAddr.ToSdkConsAddr()) - s.Require().True(found) + stakingVal, err := providerStakingKeeper.GetValidatorByConsAddr(s.providerCtx(), providerConsAddr.ToSdkConsAddr()) + s.Require().NoError(err) valOldBalance := stakingVal.Tokens // Setup first val with mapped consensus address to be jailed on provider by setting signing info @@ -132,16 +134,16 @@ func (s *CCVTestSuite) TestRelayAndApplyDowntimePacket() { } // Get staking keeper's validator obj after the relayed slash packet - stakingValAfter, ok := providerStakingKeeper.GetValidatorByConsAddr(s.providerCtx(), providerConsAddr.ToSdkConsAddr()) - s.Require().True(ok) + stakingValAfter, err := providerStakingKeeper.GetValidatorByConsAddr(s.providerCtx(), providerConsAddr.ToSdkConsAddr()) + s.Require().NoError(err) // check that the validator's tokens were NOT slashed on provider valNewBalance := stakingValAfter.GetTokens() s.Require().Equal(valOldBalance, valNewBalance) // Get signing info for the validator - valSignInfo, found := providerSlashingKeeper.GetValidatorSigningInfo(s.providerCtx(), providerConsAddr.ToSdkConsAddr()) - s.Require().True(found) + valSignInfo, err := providerSlashingKeeper.GetValidatorSigningInfo(s.providerCtx(), providerConsAddr.ToSdkConsAddr()) + s.Require().NoError(err) // check that the validator is successfully jailed on provider s.Require().True(stakingValAfter.Jailed) @@ -189,8 +191,8 @@ func (s *CCVTestSuite) TestRelayAndApplyDoubleSignPacket() { consumerConsAddr) s.Require().True(found) - stakingVal, found := providerStakingKeeper.GetValidatorByConsAddr(s.providerCtx(), providerConsAddr.ToSdkConsAddr()) - s.Require().True(found) + stakingVal, err := providerStakingKeeper.GetValidatorByConsAddr(s.providerCtx(), providerConsAddr.ToSdkConsAddr()) + s.Require().NoError(err) valOldBalance := stakingVal.Tokens // Setup first val with mapped consensus address to be jailed on provider by setting signing info @@ -218,16 +220,16 @@ func (s *CCVTestSuite) TestRelayAndApplyDoubleSignPacket() { s.Require().Len(s.providerChain.Vals.Validators, validatorsPerChain) // Get staking keeper's validator obj after the relayed slash packet - stakingValAfter, ok := providerStakingKeeper.GetValidatorByConsAddr(s.providerCtx(), providerConsAddr.ToSdkConsAddr()) - s.Require().True(ok) + stakingValAfter, err := providerStakingKeeper.GetValidatorByConsAddr(s.providerCtx(), providerConsAddr.ToSdkConsAddr()) + s.Require().NoError(err) // check that the validator's tokens were NOT slashed on provider valNewBalance := stakingValAfter.GetTokens() s.Require().Equal(valOldBalance, valNewBalance) // Get signing info for the validator - valSignInfo, found := providerSlashingKeeper.GetValidatorSigningInfo(s.providerCtx(), providerConsAddr.ToSdkConsAddr()) - s.Require().True(found) + valSignInfo, err := providerSlashingKeeper.GetValidatorSigningInfo(s.providerCtx(), providerConsAddr.ToSdkConsAddr()) + s.Require().NoError(err) // check that the validator's unjailing time is NOT updated on provider s.Require().Zero(valSignInfo.JailedUntil) @@ -299,8 +301,8 @@ func (suite *CCVTestSuite) TestHandleSlashPacketDowntime() { consAddr := sdk.ConsAddress(tmVal.Address) // check that validator bonded status - validator, found := providerStakingKeeper.GetValidatorByConsAddr(suite.providerCtx(), consAddr) - suite.Require().True(found) + validator, err := providerStakingKeeper.GetValidatorByConsAddr(suite.providerCtx(), consAddr) + suite.Require().NoError(err) suite.Require().Equal(stakingtypes.Bonded, validator.GetStatus()) // set init VSC id for chain0 @@ -325,7 +327,8 @@ func (suite *CCVTestSuite) TestHandleSlashPacketDowntime() { suite.Require().True(providerStakingKeeper.IsValidatorJailed(suite.providerCtx(), consAddr)) signingInfo, _ := providerSlashingKeeper.GetValidatorSigningInfo(suite.providerCtx(), consAddr) - jailDuration := providerSlashingKeeper.DowntimeJailDuration(suite.providerCtx()) + jailDuration, err := providerSlashingKeeper.DowntimeJailDuration(suite.providerCtx()) + suite.Require().NoError(err) suite.Require().Equal(suite.providerCtx().BlockTime().Add(jailDuration), signingInfo.JailedUntil) } @@ -405,13 +408,13 @@ func (suite *CCVTestSuite) TestOnRecvSlashPacketErrors() { slashPacketData.Infraction = stakingtypes.Infraction_INFRACTION_DOWNTIME // Expect the packet to bounce if the slash meter is negative - providerKeeper.SetSlashMeter(ctx, sdk.NewInt(-1)) + providerKeeper.SetSlashMeter(ctx, math.NewInt(-1)) ackResult, err = providerKeeper.OnRecvSlashPacket(ctx, packet, *slashPacketData) suite.Require().NoError(err, "no error expected") suite.Require().Equal(ccv.SlashPacketBouncedResult, ackResult, "expected successful ack") // Expect the packet to be handled if the slash meter is positive - providerKeeper.SetSlashMeter(ctx, sdk.NewInt(0)) + providerKeeper.SetSlashMeter(ctx, math.NewInt(0)) ackResult, err = providerKeeper.OnRecvSlashPacket(ctx, packet, *slashPacketData) suite.Require().NoError(err, "no error expected") suite.Require().Equal(ccv.SlashPacketHandledResult, ackResult, "expected successful ack") @@ -445,13 +448,17 @@ func (suite *CCVTestSuite) TestValidatorDowntime() { // Sign 100 blocks (default value for slashing.SignedBlocksWindow param). valPower := int64(1) - height, signedBlocksWindow := int64(0), consumerSlashingKeeper.SignedBlocksWindow(ctx) + height := int64(0) + signedBlocksWindow, err := consumerSlashingKeeper.SignedBlocksWindow(ctx) + suite.Require().NoError(err) for ; height < signedBlocksWindow; height++ { ctx = ctx.WithBlockHeight(height) - consumerSlashingKeeper.HandleValidatorSignature(ctx, vals[0].Address, valPower, true) + consumerSlashingKeeper.HandleValidatorSignature(ctx, vals[0].Address, valPower, comet.BlockIDFlagCommit) } - missedBlockThreshold := (2 * signedBlocksWindow) - consumerSlashingKeeper.MinSignedPerWindow(ctx) + minSigned, err := consumerSlashingKeeper.MinSignedPerWindow(ctx) + suite.Require().NoError(err) + missedBlockThreshold := (2 * signedBlocksWindow) - minSigned ctx = suite.consumerCtx() // construct slash packet to be sent and get its commit @@ -466,7 +473,7 @@ func (suite *CCVTestSuite) TestValidatorDowntime() { // Miss 50 blocks and expect a slash packet to be sent for ; height <= missedBlockThreshold; height++ { ctx = ctx.WithBlockHeight(height) - consumerSlashingKeeper.HandleValidatorSignature(ctx, vals[0].Address, valPower, false) + consumerSlashingKeeper.HandleValidatorSignature(ctx, vals[0].Address, valPower, comet.BlockIDFlagAbsent) } ctx = suite.consumerCtx() @@ -474,11 +481,13 @@ func (suite *CCVTestSuite) TestValidatorDowntime() { // check validator signing info res, _ := consumerSlashingKeeper.GetValidatorSigningInfo(ctx, consAddr) // expect increased jail time - suite.Require().True(res.JailedUntil.Equal(ctx.BlockTime().Add(consumerSlashingKeeper.DowntimeJailDuration(ctx))), "did not update validator jailed until signing info") + jailDuration, err := consumerSlashingKeeper.DowntimeJailDuration(ctx) + suite.Require().NoError(err) + suite.Require().True(res.JailedUntil.Equal(ctx.BlockTime().Add(jailDuration)), "did not update validator jailed until signing info") // expect missed block counters reset suite.Require().Zero(res.MissedBlocksCounter, "did not reset validator missed block counter") suite.Require().Zero(res.IndexOffset) - consumerSlashingKeeper.IterateValidatorMissedBlockBitArray(ctx, consAddr, func(_ int64, missed bool) bool { + consumerSlashingKeeper.IterateMissedBlockBitmap(ctx, consAddr, func(_ int64, missed bool) bool { suite.Require().True(missed) return false }) @@ -512,14 +521,14 @@ func (suite *CCVTestSuite) TestValidatorDowntime() { // check that the outstanding slashing flag prevents the jailed validator to keep missing block for ; height < missedBlockThreshold+signedBlocksWindow; height++ { ctx = ctx.WithBlockHeight(height) - consumerSlashingKeeper.HandleValidatorSignature(ctx, vals[0].Address, valPower, false) + consumerSlashingKeeper.HandleValidatorSignature(ctx, vals[0].Address, valPower, comet.BlockIDFlagAbsent) } res, _ = consumerSlashingKeeper.GetValidatorSigningInfo(ctx, consAddr) suite.Require().Zero(res.MissedBlocksCounter, "did not reset validator missed block counter") suite.Require().Zero(res.IndexOffset) - consumerSlashingKeeper.IterateValidatorMissedBlockBitArray(ctx, consAddr, func(_ int64, missed bool) bool { + consumerSlashingKeeper.IterateMissedBlockBitmap(ctx, consAddr, func(_ int64, missed bool) bool { suite.Require().True(missed, "did not reset validator missed block bit array") return false }) @@ -574,7 +583,13 @@ func (suite *CCVTestSuite) TestValidatorDoubleSigning() { expCommit := suite.commitSlashPacket(ctx, *packetData) // expect to send slash packet when handling double-sign evidence - suite.consumerApp.GetTestEvidenceKeeper().HandleEquivocationEvidence(ctx, e) + // NOTE: using IBCKeeper Authority as msg submitter (equal to gov module addr) + addr, err := sdk.AccAddressFromBech32(suite.consumerApp.GetIBCKeeper().GetAuthority()) + suite.Require().NoError(err) + evidenceMsg, err := evidencetypes.NewMsgSubmitEvidence(addr, e) + suite.Require().NoError(err) + suite.Require().NotEmpty(evidenceMsg) + suite.consumerApp.GetTestEvidenceKeeper().SubmitEvidence(ctx, e) // check slash packet is queued pendingPackets := suite.consumerApp.GetConsumerKeeper().GetPendingPackets(ctx) @@ -695,7 +710,7 @@ func (suite *CCVTestSuite) TestCISBeforeCCVEstablished() { suite.Require().False(found) consumerKeeper.SlashWithInfractionReason(suite.consumerCtx(), []byte{0x01, 0x02, 0x3}, - 66, 4324, sdk.MustNewDecFromStr("0.05"), stakingtypes.Infraction_INFRACTION_DOWNTIME) + 66, 4324, math.LegacyMustNewDecFromStr("0.05"), stakingtypes.Infraction_INFRACTION_DOWNTIME) // Check slash packet was queued pendingPackets = consumerKeeper.GetPendingPackets(suite.consumerCtx()) diff --git a/tests/integration/soft_opt_out.go b/tests/integration/soft_opt_out.go index a5ee566a4b..58eb6cea84 100644 --- a/tests/integration/soft_opt_out.go +++ b/tests/integration/soft_opt_out.go @@ -4,12 +4,16 @@ import ( "bytes" "sort" + "cosmossdk.io/core/comet" + "cosmossdk.io/math" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - consumerKeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + consumerKeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" + + cmttypes "github.com/cometbft/cometbft/proto/tendermint/types" ) // TestSoftOptOut tests the soft opt-out feature @@ -32,10 +36,17 @@ func (suite *CCVTestSuite) TestSoftOptOut() { func(ck *consumerKeeper.Keeper, sk *slashingkeeper.Keeper, valAddr []byte, valIdx int) { for i, voteInfo := range votes { if bytes.Equal(voteInfo.Validator.Address, valAddr) { - votes[i].SignedLastBlock = false + votes[i].BlockIdFlag = cmttypes.BlockIDFlagAbsent } } - blocksToDowntime := sk.SignedBlocksWindow(suite.consumerCtx()) - sk.MinSignedPerWindow(suite.consumerCtx()) + 1 + blocksToDowntime, err := sk.SignedBlocksWindow(suite.consumerCtx()) + suite.Require().NoError(err) + + minSigned, err := sk.MinSignedPerWindow(suite.consumerCtx()) + suite.Require().NoError(err) + + blocksToDowntime = blocksToDowntime - minSigned + 1 + slashingBeginBlocker(suite, votes, blocksToDowntime) }, 0, @@ -47,10 +58,16 @@ func (suite *CCVTestSuite) TestSoftOptOut() { func(ck *consumerKeeper.Keeper, sk *slashingkeeper.Keeper, valAddr []byte, valIdx int) { for i, voteInfo := range votes { if bytes.Equal(voteInfo.Validator.Address, valAddr) { - votes[i].SignedLastBlock = false + votes[i].BlockIdFlag = cmttypes.BlockIDFlagAbsent } } - blocksToDowntime := sk.SignedBlocksWindow(suite.consumerCtx()) - sk.MinSignedPerWindow(suite.consumerCtx()) + 1 + blocksToDowntime, err := sk.SignedBlocksWindow(suite.consumerCtx()) + suite.Require().NoError(err) + + minSigned, err := sk.MinSignedPerWindow(suite.consumerCtx()) + suite.Require().NoError(err) + + blocksToDowntime = blocksToDowntime - minSigned + 1 slashingBeginBlocker(suite, votes, blocksToDowntime) }, 3, @@ -62,15 +79,21 @@ func (suite *CCVTestSuite) TestSoftOptOut() { func(ck *consumerKeeper.Keeper, sk *slashingkeeper.Keeper, valAddr []byte, valIdx int) { for i, voteInfo := range votes { if bytes.Equal(voteInfo.Validator.Address, valAddr) { - votes[i].SignedLastBlock = false + votes[i].BlockIdFlag = cmttypes.BlockIDFlagAbsent } } - blocksToDowntime := sk.SignedBlocksWindow(suite.consumerCtx()) - sk.MinSignedPerWindow(suite.consumerCtx()) + blocksToDowntime, err := sk.SignedBlocksWindow(suite.consumerCtx()) + suite.Require().NoError(err) + + minSigned, err := sk.MinSignedPerWindow(suite.consumerCtx()) + suite.Require().NoError(err) + + blocksToDowntime = blocksToDowntime - minSigned + 1 slashingBeginBlocker(suite, votes, blocksToDowntime) // Increase the power of this validator (to bring it in the top 95%) delAddr := suite.providerChain.SenderAccount.GetAddress() - bondAmt := sdk.NewInt(100).Mul(sdk.DefaultPowerReduction) + bondAmt := math.NewInt(100).Mul(sdk.DefaultPowerReduction) delegateByIdx(suite, delAddr, bondAmt, valIdx) suite.providerChain.NextBlock() @@ -101,15 +124,21 @@ func (suite *CCVTestSuite) TestSoftOptOut() { func(ck *consumerKeeper.Keeper, sk *slashingkeeper.Keeper, valAddr []byte, valIdx int) { for i, voteInfo := range votes { if bytes.Equal(voteInfo.Validator.Address, valAddr) { - votes[i].SignedLastBlock = false + votes[i].BlockIdFlag = cmttypes.BlockIDFlagAbsent } } - blocksToDowntime := sk.SignedBlocksWindow(suite.consumerCtx()) - sk.MinSignedPerWindow(suite.consumerCtx()) + blocksToDowntime, err := sk.SignedBlocksWindow(suite.consumerCtx()) + suite.Require().NoError(err) + + minSigned, err := sk.MinSignedPerWindow(suite.consumerCtx()) + suite.Require().NoError(err) + + blocksToDowntime = blocksToDowntime - minSigned + 1 slashingBeginBlocker(suite, votes, blocksToDowntime) // Increase the power of this validator (to bring it in the top 95%) delAddr := suite.providerChain.SenderAccount.GetAddress() - bondAmt := sdk.NewInt(100).Mul(sdk.DefaultPowerReduction) + bondAmt := math.NewInt(100).Mul(sdk.DefaultPowerReduction) delegateByIdx(suite, delAddr, bondAmt, valIdx) suite.providerChain.NextBlock() @@ -130,7 +159,10 @@ func (suite *CCVTestSuite) TestSoftOptOut() { votes[i].Validator.Power = val.Power } } - slashingBeginBlocker(suite, votes, sk.SignedBlocksWindow(suite.consumerCtx())+1) + + sigBlockWindow, err := sk.SignedBlocksWindow(suite.consumerCtx()) + suite.Require().NoError(err) + slashingBeginBlocker(suite, votes, sigBlockWindow+1) }, 2, true, @@ -172,11 +204,14 @@ func (suite *CCVTestSuite) TestSoftOptOut() { votes = []abci.VoteInfo{} for _, val := range vals { votes = append(votes, abci.VoteInfo{ - Validator: abci.Validator{Address: val.Address, Power: val.Power}, - SignedLastBlock: true, + Validator: abci.Validator{Address: val.Address, Power: val.Power}, + BlockIdFlag: cmttypes.BlockIDFlagCommit, }) } - slashingBeginBlocker(suite, votes, consumerSlashingKeeper.SignedBlocksWindow(suite.consumerCtx())) + + consuSlashingWindow, err := consumerSlashingKeeper.SignedBlocksWindow(suite.consumerCtx()) + suite.Require().NoError(err) + slashingBeginBlocker(suite, votes, consuSlashingWindow) // Downtime infraction sk := consumerSlashingKeeper.(slashingkeeper.Keeper) @@ -187,14 +222,16 @@ func (suite *CCVTestSuite) TestSoftOptOut() { info, _ := consumerSlashingKeeper.GetValidatorSigningInfo(suite.consumerCtx(), consAddr) if tc.expJailed { // expect increased jail time + consumerJailDowntimeDuration, err := consumerSlashingKeeper.DowntimeJailDuration(suite.consumerCtx()) + suite.Require().NoError(err) suite.Require().True( - info.JailedUntil.Equal(suite.consumerCtx().BlockTime().Add(consumerSlashingKeeper.DowntimeJailDuration(suite.consumerCtx()))), + info.JailedUntil.Equal(suite.consumerCtx().BlockTime().Add(consumerJailDowntimeDuration)), "test: "+tc.name+"; did not update validator jailed until signing info", ) // expect missed block counters reset suite.Require().Zero(info.MissedBlocksCounter, "test: "+tc.name+"; did not reset validator missed block counter") suite.Require().Zero(info.IndexOffset, "test: "+tc.name) - consumerSlashingKeeper.IterateValidatorMissedBlockBitArray(suite.consumerCtx(), consAddr, func(_ int64, missed bool) bool { + consumerSlashingKeeper.IterateMissedBlockBitmap(suite.consumerCtx(), consAddr, func(_ int64, missed bool) bool { suite.Require().True(missed, "test: "+tc.name) return false }) @@ -239,7 +276,7 @@ func slashingBeginBlocker(s *CCVTestSuite, votes []abci.VoteInfo, blocks int64) s.consumerCtx(), voteInfo.Validator.Address, voteInfo.Validator.Power, - voteInfo.SignedLastBlock, + comet.BlockIDFlag(voteInfo.GetBlockIdFlag()), ) } s.consumerChain.NextBlock() diff --git a/tests/integration/stop_consumer.go b/tests/integration/stop_consumer.go index 6e72679ccd..f7b2d6ef96 100644 --- a/tests/integration/stop_consumer.go +++ b/tests/integration/stop_consumer.go @@ -1,12 +1,13 @@ package integration import ( - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + "cosmossdk.io/math" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // Tests the functionality of stopping a consumer chain at a higher level than unit tests @@ -21,8 +22,8 @@ func (s *CCVTestSuite) TestStopConsumerChain() { valAddr, err := sdk.ValAddressFromHex(tmValidator.Address.String()) s.Require().NoError(err) - validator, found := providerStakingKeeper.GetValidator(s.providerCtx(), valAddr) - s.Require().True(found) + validator, err := providerStakingKeeper.GetValidator(s.providerCtx(), valAddr) + s.Require().NoError(err) // get delegator address delAddr := s.providerChain.SenderAccount.GetAddress() @@ -30,11 +31,11 @@ func (s *CCVTestSuite) TestStopConsumerChain() { // define variables required for test setup var ( // bond amount - bondAmt = sdk.NewInt(1000000) + bondAmt = math.NewInt(1000000) // number of unbonding operations performed ubdOpsNum = 4 // store new shares created - testShares sdk.Dec + testShares math.LegacyDec ) // populate the provider chain states to setup the test using the following operations: @@ -62,7 +63,7 @@ func (s *CCVTestSuite) TestStopConsumerChain() { func(suite *CCVTestSuite) error { for i := 0; i < ubdOpsNum; i++ { // undelegate one quarter of the shares - _, err := providerStakingKeeper.Undelegate(s.providerCtx(), delAddr, valAddr, testShares.QuoInt64(int64(ubdOpsNum))) + _, _, err := providerStakingKeeper.Undelegate(s.providerCtx(), delAddr, valAddr, testShares.QuoInt64(int64(ubdOpsNum))) if err != nil { return err } diff --git a/tests/integration/throttle.go b/tests/integration/throttle.go index ff2d32dade..ed7ce779d2 100644 --- a/tests/integration/throttle.go +++ b/tests/integration/throttle.go @@ -3,17 +3,18 @@ package integration import ( "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "cosmossdk.io/math" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" tmtypes "github.com/cometbft/cometbft/types" - icstestingutils "github.com/cosmos/interchain-security/v4/testutil/ibc_testing" - "github.com/cosmos/interchain-security/v4/x/ccv/provider" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + icstestingutils "github.com/cosmos/interchain-security/v5/testutil/ibc_testing" + "github.com/cosmos/interchain-security/v5/x/ccv/provider" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) const fullSlashMeterString = "1.0" @@ -79,7 +80,8 @@ func (s *CCVTestSuite) TestBasicSlashPacketThrottling() { s.Require().Equal(tc.expectedMeterBeforeFirstSlash, slashMeter.Int64()) // Assert that we start out with no jailings - vals := providerStakingKeeper.GetAllValidators(s.providerCtx()) + vals, err := providerStakingKeeper.GetAllValidators(s.providerCtx()) + s.Require().NoError(err) for _, val := range vals { s.Require().False(val.IsJailed()) } @@ -95,10 +97,14 @@ func (s *CCVTestSuite) TestBasicSlashPacketThrottling() { sendOnConsumerRecvOnProvider(s, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp, slashPacket.GetData()) // Assert validator 0 is jailed and has no power - vals = providerStakingKeeper.GetAllValidators(s.providerCtx()) + vals, err = providerStakingKeeper.GetAllValidators(s.providerCtx()) + s.Require().NoError(err) slashedVal := vals[0] s.Require().True(slashedVal.IsJailed()) - lastValPower := providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), slashedVal.GetOperator()) + slashedValOperator, err := sdk.ValAddressFromHex(slashedVal.GetOperator()) + s.Require().NoError(err) + lastValPower, err := providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), slashedValOperator) + s.Require().NoError(err) s.Require().Equal(int64(0), lastValPower) // Assert expected slash meter and allowance value @@ -115,7 +121,8 @@ func (s *CCVTestSuite) TestBasicSlashPacketThrottling() { // Require that slash packet has not been handled, a bounce result would have // been returned, but the IBC helper throws out acks. - vals = providerStakingKeeper.GetAllValidators(s.providerCtx()) + vals, err = providerStakingKeeper.GetAllValidators(s.providerCtx()) + s.Require().NoError(err) s.Require().False(vals[2].IsJailed()) // Assert slash meter value is still the same @@ -176,7 +183,10 @@ func (s *CCVTestSuite) TestBasicSlashPacketThrottling() { // Assert validator 2 has no power, this should be apparent next block, // since the staking endblocker runs before the ccv endblocker. s.providerChain.NextBlock() - lastValPower = providerStakingKeeper.GetLastValidatorPower(cacheCtx, slashedVal.GetOperator()) + slashedValOperator, err = sdk.ValAddressFromHex(slashedVal.GetOperator()) + s.Require().NoError(err) + lastValPower, err = providerStakingKeeper.GetLastValidatorPower(cacheCtx, slashedValOperator) + s.Require().NoError(err) s.Require().Equal(int64(0), lastValPower) } } @@ -237,8 +247,9 @@ func (s *CCVTestSuite) TestMultiConsumerSlashPacketThrottling() { s.confirmValidatorNotJailed(valsToSlash[2], 1000) // Total power is now 3000 (as one validator was jailed) - s.Require().Equal(int64(3000), - providerStakingKeeper.GetLastTotalPower(s.providerCtx()).Int64()) + power, err := providerStakingKeeper.GetLastTotalPower(s.providerCtx()) + s.Require().NoError(err) + s.Require().Equal(int64(3000), power.Int64()) // Now replenish the slash meter and confirm one of two queued slash // packet entries are then handled, when both are retried. @@ -269,8 +280,9 @@ func (s *CCVTestSuite) TestMultiConsumerSlashPacketThrottling() { s.providerChain.NextBlock() // If one of the entries was handled, total power will be 2000 (1000 power was just slashed) - s.Require().Equal(int64(2000), - providerStakingKeeper.GetLastTotalPower(s.providerCtx()).Int64()) + power, err = providerStakingKeeper.GetLastTotalPower(s.providerCtx()) + s.Require().NoError(err) + s.Require().Equal(int64(2000), power.Int64()) // Now replenish one more time, and handle final slash packet. s.replenishSlashMeterTillPositive() @@ -290,8 +302,9 @@ func (s *CCVTestSuite) TestMultiConsumerSlashPacketThrottling() { s.providerChain.NextBlock() // Total power is now 1000 (just a single validator left) - s.Require().Equal(int64(1000), - providerStakingKeeper.GetLastTotalPower(s.providerCtx()).Int64()) + power, err = providerStakingKeeper.GetLastTotalPower(s.providerCtx()) + s.Require().NoError(err) + s.Require().Equal(int64(1000), power.Int64()) // Now all 3 expected vals are jailed, and there are no more queued // slash/vsc matured packets. @@ -429,12 +442,11 @@ func (s *CCVTestSuite) TestDoubleSignDoesNotAffectThrottling() { stakingKeeper := s.providerApp.GetTestStakingKeeper() for _, val := range s.providerChain.Vals.Validators { - power := stakingKeeper.GetLastValidatorPower(s.providerCtx(), sdk.ValAddress(val.Address)) + power, err := stakingKeeper.GetLastValidatorPower(s.providerCtx(), sdk.ValAddress(val.Address)) + s.Require().NoError(err) s.Require().Equal(int64(1000), power) - stakingVal, found := stakingKeeper.GetValidatorByConsAddr(s.providerCtx(), sdk.ConsAddress(val.Address)) - if !found { - s.Require().Fail("validator not found") - } + stakingVal, err := stakingKeeper.GetValidatorByConsAddr(s.providerCtx(), sdk.ConsAddress(val.Address)) + s.Require().Error(err) s.Require().False(stakingVal.Jailed) // 4th validator should have no slash log, all the others do @@ -455,10 +467,10 @@ func (s *CCVTestSuite) TestSlashingSmallValidators() { // Setup first val with 1000 power and the rest with 10 power. delAddr := s.providerChain.SenderAccount.GetAddress() - delegateByIdx(s, delAddr, sdk.NewInt(999999999), 0) - delegateByIdx(s, delAddr, sdk.NewInt(9999999), 1) - delegateByIdx(s, delAddr, sdk.NewInt(9999999), 2) - delegateByIdx(s, delAddr, sdk.NewInt(9999999), 3) + delegateByIdx(s, delAddr, math.NewInt(999999999), 0) + delegateByIdx(s, delAddr, math.NewInt(9999999), 1) + delegateByIdx(s, delAddr, math.NewInt(9999999), 2) + delegateByIdx(s, delAddr, math.NewInt(9999999), 3) s.providerChain.NextBlock() // Initialize slash meter @@ -466,7 +478,8 @@ func (s *CCVTestSuite) TestSlashingSmallValidators() { // Assert that we start out with no jailings providerStakingKeeper := s.providerApp.GetTestStakingKeeper() - vals := providerStakingKeeper.GetAllValidators(s.providerCtx()) + vals, err := providerStakingKeeper.GetAllValidators(s.providerCtx()) + s.Require().NoError(err) for _, val := range vals { s.Require().False(val.IsJailed()) } @@ -492,19 +505,30 @@ func (s *CCVTestSuite) TestSlashingSmallValidators() { sendOnConsumerRecvOnProvider(s, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp, slashPacket3.GetData()) // Default slash meter replenish fraction is 0.05, so all sent packets should be handled immediately. - vals = providerStakingKeeper.GetAllValidators(s.providerCtx()) - s.Require().False(vals[0].IsJailed()) - s.Require().Equal(int64(1000), - providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), vals[0].GetOperator())) - s.Require().True(vals[1].IsJailed()) - s.Require().Equal(int64(0), - providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), vals[1].GetOperator())) - s.Require().True(vals[2].IsJailed()) - s.Require().Equal(int64(0), - providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), vals[2].GetOperator())) - s.Require().True(vals[3].IsJailed()) - s.Require().Equal(int64(0), - providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), vals[3].GetOperator())) + vals, err = providerStakingKeeper.GetAllValidators(s.providerCtx()) + s.Require().NoError(err) + + val0Operator, err := sdk.ValAddressFromHex(vals[0].GetOperator()) + power, err := providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), val0Operator) + s.Require().NoError(err) + s.Require().Equal(int64(1000), power) + + val1Operator, err := sdk.ValAddressFromHex(vals[1].GetOperator()) + power, err = providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), val1Operator) + s.Require().NoError(err) + s.Require().NoError(err) + s.Require().Equal(int64(0), power) + + val2Operator, err := sdk.ValAddressFromHex(vals[2].GetOperator()) + power, err = providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), val2Operator) + s.Require().NoError(err) + s.Require().NoError(err) + s.Require().Equal(int64(0), power) + + val3Operator, err := sdk.ValAddressFromHex(vals[3].GetOperator()) + power, err = providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), val3Operator) + s.Require().NoError(err) + s.Require().Equal(int64(0), power) } // TestSlashMeterAllowanceChanges tests scenarios where the slash meter allowance is expected to change. @@ -598,24 +622,30 @@ func (s CCVTestSuite) TestSlashAllValidators() { //nolint:govet // this is a tes } func (s *CCVTestSuite) confirmValidatorJailed(tmVal tmtypes.Validator, checkPower bool) { - sdkVal, found := s.providerApp.GetTestStakingKeeper().GetValidator( + sdkVal, err := s.providerApp.GetTestStakingKeeper().GetValidator( s.providerCtx(), sdk.ValAddress(tmVal.Address)) - s.Require().True(found) + s.Require().NoError(err) s.Require().True(sdkVal.IsJailed()) if checkPower { - valPower := s.providerApp.GetTestStakingKeeper().GetLastValidatorPower( - s.providerCtx(), sdkVal.GetOperator()) + valOperator, err := sdk.ValAddressFromHex(sdkVal.GetOperator()) + s.Require().NoError(err) + valPower, err := s.providerApp.GetTestStakingKeeper().GetLastValidatorPower( + s.providerCtx(), valOperator) + s.Require().NoError(err) s.Require().Equal(int64(0), valPower) } } func (s *CCVTestSuite) confirmValidatorNotJailed(tmVal tmtypes.Validator, expectedPower int64) { - sdkVal, found := s.providerApp.GetTestStakingKeeper().GetValidator( + sdkVal, err := s.providerApp.GetTestStakingKeeper().GetValidator( s.providerCtx(), sdk.ValAddress(tmVal.Address)) - s.Require().True(found) - valPower := s.providerApp.GetTestStakingKeeper().GetLastValidatorPower( - s.providerCtx(), sdkVal.GetOperator()) + s.Require().NoError(err) + valOperator, err := sdk.ValAddressFromHex(sdkVal.GetOperator()) + s.Require().NoError(err) + valPower, err := s.providerApp.GetTestStakingKeeper().GetLastValidatorPower( + s.providerCtx(), valOperator) + s.Require().NoError(err) s.Require().Equal(expectedPower, valPower) s.Require().False(sdkVal.IsJailed()) } diff --git a/tests/integration/throttle_retry.go b/tests/integration/throttle_retry.go index 36acad3602..cde17014cf 100644 --- a/tests/integration/throttle_retry.go +++ b/tests/integration/throttle_retry.go @@ -3,11 +3,12 @@ package integration import ( "time" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // TestSlashRetries tests the throttling v2 retry logic at an integration level. @@ -24,7 +25,8 @@ func (s *CCVTestSuite) TestSlashRetries() { providerKeeper.InitializeSlashMeter(s.providerCtx()) // Assert that we start out with no jailings providerStakingKeeper := s.providerApp.GetTestStakingKeeper() - vals := providerStakingKeeper.GetAllValidators(s.providerCtx()) + vals, err := providerStakingKeeper.GetAllValidators(s.providerCtx()) + s.Require().NoError(err) for _, val := range vals { s.Require().False(val.IsJailed()) } @@ -91,15 +93,18 @@ func (s *CCVTestSuite) TestSlashRetries() { // Default slash meter replenish fraction is 0.05, so packet should be handled on provider. stakingVal1 := s.mustGetStakingValFromTmVal(*tmval1) s.Require().True(stakingVal1.IsJailed()) - s.Require().Equal(int64(0), - s.providerApp.GetTestStakingKeeper().GetLastValidatorPower(s.providerCtx(), stakingVal1.GetOperator())) + stakingVal1Addr, err := sdk.ValAddressFromHex(stakingVal1.GetOperator()) + s.Require().NoError(err) + stakingVal1LastPower, err := s.providerApp.GetTestStakingKeeper().GetLastValidatorPower(s.providerCtx(), stakingVal1Addr) + s.Require().NoError(err) + s.Require().Equal(int64(0), stakingVal1LastPower) // Now slash meter should be negative on provider s.Require().True(s.providerApp.GetProviderKeeper().GetSlashMeter(s.providerCtx()).IsNegative()) // Apply ack back on consumer expectedAck := channeltypes.NewResultAcknowledgement([]byte(ccvtypes.SlashPacketHandledResult)) - err := s.getFirstBundle().Path.EndpointA.AcknowledgePacket(packet1, expectedAck.Acknowledgement()) + err = s.getFirstBundle().Path.EndpointA.AcknowledgePacket(packet1, expectedAck.Acknowledgement()) s.Require().NoError(err) // Slash record should have been deleted, head of pending packets should have been popped, @@ -151,8 +156,10 @@ func (s *CCVTestSuite) TestSlashRetries() { // Val 2 shouldn't be jailed on provider. Slash packet should have been bounced. stakingVal2 := s.mustGetStakingValFromTmVal(*tmval2) s.Require().False(stakingVal2.IsJailed()) - s.Require().Equal(int64(1000), - providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), stakingVal2.GetOperator())) + stakingVal2Addr, err := sdk.ValAddressFromHex(stakingVal2.GetOperator()) + s.Require().NoError(err) + stakingVal2LastPower, err := providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), stakingVal2Addr) + s.Require().Equal(int64(1000), stakingVal2LastPower) // Apply ack on consumer expectedAck = channeltypes.NewResultAcknowledgement([]byte(ccvtypes.SlashPacketBouncedResult)) @@ -203,8 +210,11 @@ func (s *CCVTestSuite) TestSlashRetries() { // Provider should have now jailed val 2 stakingVal2 = s.mustGetStakingValFromTmVal(*tmval2) s.Require().True(stakingVal2.IsJailed()) - s.Require().Equal(int64(0), - s.providerApp.GetTestStakingKeeper().GetLastValidatorPower(s.providerCtx(), stakingVal2.GetOperator())) + s.Require().False(stakingVal2.IsJailed()) + stakingVal2Addr, err = sdk.ValAddressFromHex(stakingVal2.GetOperator()) + s.Require().NoError(err) + stakingVal2LastPower, err = providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), stakingVal2Addr) + s.Require().Equal(int64(0), stakingVal2LastPower) // Apply ack on consumer expectedAck = channeltypes.NewResultAcknowledgement([]byte(ccvtypes.SlashPacketHandledResult)) diff --git a/tests/integration/unbonding.go b/tests/integration/unbonding.go index 00f48871c2..fcaae28e82 100644 --- a/tests/integration/unbonding.go +++ b/tests/integration/unbonding.go @@ -5,10 +5,8 @@ import ( "cosmossdk.io/math" - sdk "github.com/cosmos/cosmos-sdk/types" - - providerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // TestUndelegationNormalOperation tests that undelegations complete after @@ -84,12 +82,13 @@ func (s *CCVTestSuite) TestUndelegationNormalOperation() { s.SetupCCVChannel(s.path) // set VSC timeout period to not trigger the removal of the consumer chain - providerUnbondingPeriod := stakingKeeper.UnbondingTime(s.providerCtx()) + providerUnbondingPeriod, err := stakingKeeper.UnbondingTime(s.providerCtx()) + s.Require().NoError(err) consumerUnbondingPeriod := consumerKeeper.GetUnbondingPeriod(s.consumerCtx()) providerKeeper.SetVscTimeoutPeriod(s.providerCtx(), providerUnbondingPeriod+consumerUnbondingPeriod+24*time.Hour) // delegate bondAmt and undelegate tc.shareDiv of it - bondAmt := sdk.NewInt(10000000) + bondAmt := math.NewInt(10000000) delAddr := s.providerChain.SenderAccount.GetAddress() initBalance, valsetUpdateID := delegateAndUndelegate(s, delAddr, bondAmt, tc.shareDiv) // - check that staking unbonding op was created and onHold is true @@ -110,7 +109,7 @@ func (s *CCVTestSuite) TestUndelegationNormalOperation() { // - check that staking unbonding op has been deleted checkStakingUnbondingOps(s, valsetUpdateID, false, false, "test: "+tc.name) // - check that necessary delegated coins have been returned - unbondAmt := bondAmt.Sub(bondAmt.Quo(sdk.NewInt(tc.shareDiv))) + unbondAmt := bondAmt.Sub(bondAmt.Quo(math.NewInt(tc.shareDiv))) s.Require().Equal( initBalance.Sub(unbondAmt), getBalance(s, s.providerCtx(), delAddr), @@ -137,7 +136,7 @@ func (s *CCVTestSuite) TestUndelegationVscTimeout() { vscTimeout := providerKeeper.GetVscTimeoutPeriod(s.providerCtx()) // delegate bondAmt and undelegate 1/2 of it - bondAmt := sdk.NewInt(10000000) + bondAmt := math.NewInt(10000000) delAddr := s.providerChain.SenderAccount.GetAddress() initBalance, valsetUpdateID := delegateAndUndelegate(s, delAddr, bondAmt, 2) // - check that staking unbonding op was created and onHold is true @@ -177,7 +176,7 @@ func (s *CCVTestSuite) TestUndelegationVscTimeout() { // - check that staking unbonding op has been deleted checkStakingUnbondingOps(s, valsetUpdateID, false, false) // - check that necessary delegated coins have been returned - unbondAmt := bondAmt.Sub(bondAmt.Quo(sdk.NewInt(2))) + unbondAmt := bondAmt.Sub(bondAmt.Quo(math.NewInt(2))) s.Require().Equal( initBalance.Sub(unbondAmt), getBalance(s, s.providerCtx(), delAddr), @@ -218,7 +217,7 @@ func (s *CCVTestSuite) TestUndelegationDuringInit() { stakingKeeper := s.providerApp.GetTestStakingKeeper() // delegate bondAmt and undelegate 1/2 of it - bondAmt := sdk.NewInt(10000000) + bondAmt := math.NewInt(10000000) delAddr := s.providerChain.SenderAccount.GetAddress() initBalance, valsetUpdateID := delegateAndUndelegate(s, delAddr, bondAmt, 2) // - check that staking unbonding op was created and onHold is true @@ -227,7 +226,8 @@ func (s *CCVTestSuite) TestUndelegationDuringInit() { checkCCVUnbondingOp(s, s.providerCtx(), s.consumerChain.ChainID, valsetUpdateID, true, "test: "+tc.name) // get provider unbonding period - providerUnbondingPeriod := stakingKeeper.UnbondingTime(s.providerCtx()) + providerUnbondingPeriod, err := stakingKeeper.UnbondingTime(s.providerCtx()) + s.Require().NoError(err) // update init timeout timestamp tc.updateInitTimeoutTimestamp(&providerKeeper, providerUnbondingPeriod) @@ -283,7 +283,7 @@ func (s *CCVTestSuite) TestUndelegationDuringInit() { checkStakingUnbondingOps(s, valsetUpdateID, false, false, "test: "+tc.name) // - check that one quarter the delegated coins have been returned s.Require().Equal( - initBalance.Sub(bondAmt).Sub(bondAmt.Quo(sdk.NewInt(2))), + initBalance.Sub(bondAmt).Sub(bondAmt.Quo(math.NewInt(2))), getBalance(s, s.providerCtx(), delAddr), "unexpected initial balance after unbonding; test: %s", tc.name, ) @@ -312,7 +312,7 @@ func (s *CCVTestSuite) TestUnbondingNoConsumer() { } // delegate bondAmt and undelegate 1/2 of it - bondAmt := sdk.NewInt(10000000) + bondAmt := math.NewInt(10000000) delAddr := s.providerChain.SenderAccount.GetAddress() initBalance, valsetUpdateID := delegateAndUndelegate(s, delAddr, bondAmt, 2) // - check that staking unbonding op was created and onHold is FALSE @@ -323,7 +323,8 @@ func (s *CCVTestSuite) TestUnbondingNoConsumer() { // increment time so that the unbonding period ends on the provider; // cannot use incrementTimeByUnbondingPeriod() since it tries // to also update the provider's client on the consumer - providerUnbondingPeriod := providerStakingKeeper.UnbondingTime(s.providerCtx()) + providerUnbondingPeriod, err := providerStakingKeeper.UnbondingTime(s.providerCtx()) + s.Require().NoError(err) s.coordinator.IncrementTimeBy(providerUnbondingPeriod + time.Hour) // call NextBlock on the provider (which increments the height) @@ -333,7 +334,7 @@ func (s *CCVTestSuite) TestUnbondingNoConsumer() { // - check that staking unbonding op has been deleted checkStakingUnbondingOps(s, valsetUpdateID, false, false) // - check that half the coins have been returned - s.Require().True(getBalance(s, s.providerCtx(), delAddr).Equal(initBalance.Sub(bondAmt.Quo(sdk.NewInt(2))))) + s.Require().True(getBalance(s, s.providerCtx(), delAddr).Equal(initBalance.Sub(bondAmt.Quo(math.NewInt(2))))) } // TestRedelegationNoConsumer tests a redelegate transaction @@ -347,7 +348,7 @@ func (s *CCVTestSuite) TestRedelegationNoConsumer() { s.Require().NoError(err) // Setup delegator, bond amount, and src/dst validators - bondAmt := sdk.NewInt(10000000) + bondAmt := math.NewInt(10000000) delAddr := s.providerChain.SenderAccount.GetAddress() _, srcVal := s.getValByIdx(0) _, dstVal := s.getValByIdx(1) @@ -364,10 +365,12 @@ func (s *CCVTestSuite) TestRedelegationNoConsumer() { redelegations := checkRedelegations(s, delAddr, 1) // Check that the only entry has appropriate maturation time, the unbonding period from now + unbondingTime, err := stakingKeeper.UnbondingTime(s.providerCtx()) + s.Require().NoError(err) checkRedelegationEntryCompletionTime( s, redelegations[0].Entries[0], - s.providerCtx().BlockTime().Add(stakingKeeper.UnbondingTime(s.providerCtx())), + s.providerCtx().BlockTime().Add(unbondingTime), ) // required before call to incrementTimeByUnbondingPeriod or else a panic @@ -395,12 +398,13 @@ func (s *CCVTestSuite) TestRedelegationProviderFirst() { stakingKeeper := s.providerApp.GetTestStakingKeeper() // set VSC timeout period to not trigger the removal of the consumer chain - providerUnbondingPeriod := stakingKeeper.UnbondingTime(s.providerCtx()) + providerUnbondingPeriod, err := stakingKeeper.UnbondingTime(s.providerCtx()) + s.Require().NoError(err) consumerUnbondingPeriod := consumerKeeper.GetUnbondingPeriod(s.consumerCtx()) providerKeeper.SetVscTimeoutPeriod(s.providerCtx(), providerUnbondingPeriod+consumerUnbondingPeriod+24*time.Hour) // Setup delegator, bond amount, and src/dst validators - bondAmt := sdk.NewInt(10000000) + bondAmt := math.NewInt(10000000) delAddr := s.providerChain.SenderAccount.GetAddress() _, srcVal := s.getValByIdx(0) _, dstVal := s.getValByIdx(1) @@ -417,10 +421,12 @@ func (s *CCVTestSuite) TestRedelegationProviderFirst() { redelegations := checkRedelegations(s, delAddr, 1) // Check that the only entry has appropriate maturation time, the unbonding period from now + unbondingTime, err := stakingKeeper.UnbondingTime(s.providerCtx()) + s.Require().NoError(err) checkRedelegationEntryCompletionTime( s, redelegations[0].Entries[0], - s.providerCtx().BlockTime().Add(stakingKeeper.UnbondingTime(s.providerCtx())), + s.providerCtx().BlockTime().Add(unbondingTime), ) // Save the current valset update ID diff --git a/tests/integration/valset_update.go b/tests/integration/valset_update.go index dedcce2b86..4ce9a2a6a4 100644 --- a/tests/integration/valset_update.go +++ b/tests/integration/valset_update.go @@ -3,14 +3,14 @@ package integration import ( "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "cosmossdk.io/math" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" - sdk "github.com/cosmos/cosmos-sdk/types" abci "github.com/cometbft/cometbft/abci/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // TestPacketRoundtrip tests a CCV packet roundtrip when tokens are bonded on provider @@ -19,7 +19,7 @@ func (s *CCVTestSuite) TestPacketRoundtrip() { s.SetupTransferChannel() // Bond some tokens on provider to change validator powers - bondAmt := sdk.NewInt(1000000) + bondAmt := math.NewInt(1000000) delAddr := s.providerChain.SenderAccount.GetAddress() delegate(s, delAddr, bondAmt) diff --git a/tests/mbt/driver/common.go b/tests/mbt/driver/common.go index 47d82833cc..51a3af0f45 100644 --- a/tests/mbt/driver/common.go +++ b/tests/mbt/driver/common.go @@ -1,6 +1,7 @@ package main import ( + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -21,5 +22,5 @@ func getIndexOfString(s string, slice []string) int { func init() { // tokens === power - sdk.DefaultPowerReduction = sdk.NewInt(1) + sdk.DefaultPowerReduction = math.NewInt(1) } diff --git a/tests/mbt/driver/core.go b/tests/mbt/driver/core.go index b9a4293df1..ae389c50e1 100644 --- a/tests/mbt/driver/core.go +++ b/tests/mbt/driver/core.go @@ -3,31 +3,33 @@ package main import ( "fmt" "log" - "math" "strings" "testing" "time" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctesting "github.com/cosmos/ibc-go/v7/testing" + gomath "math" + + "cosmossdk.io/math" + + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + tendermint "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v8/testing" "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - abcitypes "github.com/cometbft/cometbft/abci/types" cmttypes "github.com/cometbft/cometbft/types" "github.com/cometbft/cometbft/proto/tendermint/crypto" - appConsumer "github.com/cosmos/interchain-security/v4/app/consumer" - appProvider "github.com/cosmos/interchain-security/v4/app/provider" - simibc "github.com/cosmos/interchain-security/v4/testutil/simibc" - consumerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - providerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + appConsumer "github.com/cosmos/interchain-security/v5/app/consumer" + appProvider "github.com/cosmos/interchain-security/v5/app/provider" + simibc "github.com/cosmos/interchain-security/v5/testutil/simibc" + consumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) // Define a new type for ChainIds to be more explicit @@ -124,21 +126,21 @@ func (s *Driver) consumerPower(i int64, chain ChainId) (int64, error) { return v.Power, nil } -func (s *Driver) stakingValidator(i int64) (stakingtypes.Validator, bool) { +func (s *Driver) stakingValidator(i int64) (stakingtypes.Validator, error) { return s.providerStakingKeeper().GetValidator(s.ctx(PROVIDER), s.validator(i)) } // providerPower returns the power(=number of bonded tokens) of the i-th validator on the provider. func (s *Driver) providerPower(i int64) (int64, error) { - v, found := s.stakingValidator(i) - if !found { + v, err := s.providerStakingKeeper().GetValidator(s.ctx(PROVIDER), s.validator(i)) + if err != nil { return 0, fmt.Errorf("validator with id %v not found on provider", i) } else { return v.BondedTokens().Int64(), nil } } -func (s *Driver) providerValidatorSet() []stakingtypes.Validator { +func (s *Driver) providerValidatorSet() ([]stakingtypes.Validator, error) { return s.providerStakingKeeper().GetAllValidators(s.ctx(PROVIDER)) } @@ -150,9 +152,9 @@ func (s *Driver) consumerValidatorSet(chain ChainId) []consumertypes.CrossChainV func (s *Driver) delegate(val, amt int64) { providerStaking := s.providerStakingKeeper() server := stakingkeeper.NewMsgServerImpl(&providerStaking) - coin := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(amt)) - d := s.delegator() - v := s.validator(val) + coin := sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(amt)) + d := s.delegator().String() + v := s.validator(val).String() msg := stakingtypes.NewMsgDelegate(d, v, coin) _, err := server.Delegate(sdk.WrapSDKContext(s.ctx(PROVIDER)), msg) if err != nil { @@ -164,9 +166,9 @@ func (s *Driver) delegate(val, amt int64) { func (s *Driver) undelegate(val, amt int64) { providerStaking := s.providerStakingKeeper() server := stakingkeeper.NewMsgServerImpl(&providerStaking) - coin := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(amt)) - d := s.delegator() - v := s.validator(val) + coin := sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(amt)) + d := s.delegator().String() + v := s.validator(val).String() msg := stakingtypes.NewMsgUndelegate(d, v, coin) _, err := server.Undelegate(sdk.WrapSDKContext(s.ctx(PROVIDER)), msg) if err != nil { @@ -322,7 +324,7 @@ func (s *Driver) endAndBeginBlock(chain ChainId, timeAdvancement time.Duration) testChain, found := s.coordinator.Chains[string(chain)] require.True(s.t, found, "chain %s not found", chain) - header, packets := simibc.EndBlock(testChain, func() {}) + header, packets := simibc.FinalizeBlock(testChain, timeAdvancement) s.DriverStats.numSentPackets += len(packets) s.DriverStats.numBlocks += 1 @@ -349,7 +351,6 @@ func (s *Driver) endAndBeginBlock(chain ChainId, timeAdvancement time.Duration) } } - simibc.BeginBlock(testChain, timeAdvancement) return header } @@ -372,13 +373,12 @@ func (s *Driver) setTime(chain ChainId, newTime time.Time) { require.True(s.t, found, "chain %s not found", chain) testChain.CurrentHeader.Time = newTime - testChain.App.BeginBlock(abcitypes.RequestBeginBlock{Header: testChain.CurrentHeader}) } func (s *Driver) AssignKey(chain ChainId, valIndex int64, value crypto.PublicKey) error { - stakingVal, found := s.stakingValidator(valIndex) - if !found { - return fmt.Errorf("validator with id %v not found on provider", valIndex) + stakingVal, err := s.stakingValidator(valIndex) + if err != nil { + return fmt.Errorf("error getting validator with id %v on provider", valIndex) } return s.providerKeeper().AssignConsumerKey(s.providerCtx(), string(chain), stakingVal, value) } @@ -402,8 +402,8 @@ func (s *Driver) DeliverPacketFromConsumer(sender ChainId, expectError bool) { func (s *Driver) DeliverAcks() { for _, chain := range s.runningConsumers() { path := s.path(ChainId(chain.ChainId)) - path.DeliverAcks(path.Path.EndpointA.Chain.ChainID, math.MaxInt) - path.DeliverAcks(path.Path.EndpointB.Chain.ChainID, math.MaxInt) + path.DeliverAcks(path.Path.EndpointA.Chain.ChainID, gomath.MaxInt) + path.DeliverAcks(path.Path.EndpointB.Chain.ChainID, gomath.MaxInt) } } diff --git a/tests/mbt/driver/mbt_test.go b/tests/mbt/driver/mbt_test.go index a55d870dda..a3b45abed8 100644 --- a/tests/mbt/driver/mbt_test.go +++ b/tests/mbt/driver/mbt_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibctesting "github.com/cosmos/ibc-go/v8/testing" "github.com/informalsystems/itf-go/itf" "github.com/kylelemons/godebug/pretty" "github.com/stretchr/testify/require" @@ -18,11 +18,11 @@ import ( cmttypes "github.com/cometbft/cometbft/types" tmencoding "github.com/cometbft/cometbft/crypto/encoding" - "github.com/cosmos/interchain-security/v4/testutil/integration" + "github.com/cosmos/interchain-security/v5/testutil/integration" sdktypes "github.com/cosmos/cosmos-sdk/types" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) const verbose = false @@ -453,7 +453,8 @@ func CompareValidatorSets( t.Helper() modelValSet := ValidatorSet(currentModelState, "provider") - rawActualValSet := driver.providerValidatorSet() + rawActualValSet, err := driver.providerValidatorSet() + require.NoError(t, err, "Error getting provider validator set") actualValSet := make(map[string]int64, len(rawActualValSet)) @@ -489,7 +490,8 @@ func CompareValidatorSets( } // get the validator for that address on the provider - providerVal, found := driver.providerStakingKeeper().GetValidatorByConsAddr(driver.providerCtx(), providerConsAddr.Address) + providerVal, err := driver.providerStakingKeeper().GetValidatorByConsAddr(driver.providerCtx(), providerConsAddr.Address) + require.Nil(t, err, "Error getting provider validator") require.True(t, found, "Error getting provider validator") // use the moniker of that validator @@ -642,7 +644,11 @@ func CompareSentPacketsOnProvider(driver *Driver, currentModelState map[string]i func (s *Stats) EnterStats(driver *Driver) { // highest observed voting power - for _, val := range driver.providerValidatorSet() { + valSet, err := driver.providerValidatorSet() + if err != nil { + log.Fatalf("error getting validator set on provider: %v", err) + } + for _, val := range valSet { if val.Tokens.Int64() > s.highestObservedValPower { s.highestObservedValPower = val.Tokens.Int64() } diff --git a/tests/mbt/driver/setup.go b/tests/mbt/driver/setup.go index 83fa6e0669..5124779bf6 100644 --- a/tests/mbt/driver/setup.go +++ b/tests/mbt/driver/setup.go @@ -6,11 +6,11 @@ import ( "testing" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctesting "github.com/cosmos/ibc-go/v7/testing" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v8/testing" "github.com/stretchr/testify/require" "cosmossdk.io/math" @@ -28,11 +28,11 @@ import ( cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" cmttypes "github.com/cometbft/cometbft/types" - icstestingutils "github.com/cosmos/interchain-security/v4/testutil/ibc_testing" - "github.com/cosmos/interchain-security/v4/testutil/integration" - simibc "github.com/cosmos/interchain-security/v4/testutil/simibc" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + icstestingutils "github.com/cosmos/interchain-security/v5/testutil/ibc_testing" + "github.com/cosmos/interchain-security/v5/testutil/integration" + simibc "github.com/cosmos/interchain-security/v5/testutil/simibc" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) const ( @@ -114,7 +114,7 @@ func getAppBytesAndSenders( bal := banktypes.Balance{ Address: acc.GetAddress().String(), Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, - sdk.NewIntFromUint64(INITIAL_ACCOUNT_BALANCE))), + math.NewIntFromUint64(INITIAL_ACCOUNT_BALANCE))), } accounts = append(accounts, acc) @@ -137,16 +137,16 @@ func getAppBytesAndSenders( delegations := make([]stakingtypes.Delegation, 0, len(nodes)) // Sum bonded is needed for BondedPool account - sumBonded := sdk.NewInt(0) + sumBonded := math.NewInt(0) initValPowers := []abcitypes.ValidatorUpdate{} for i, val := range nodes { _, valSetVal := initialValSet.GetByAddress(val.Address.Bytes()) var tokens math.Int if valSetVal == nil { - tokens = sdk.NewInt(0) + tokens = math.NewInt(0) } else { - tokens = sdk.NewInt(valSetVal.VotingPower) + tokens = math.NewInt(valSetVal.VotingPower) } sumBonded = sumBonded.Add(tokens) @@ -160,7 +160,7 @@ func getAppBytesAndSenders( log.Panicf("error getting pubkeyAny for val %v", val) } - delShares := sdk.NewDec(tokens.Int64()) // as many shares as tokens + delShares := math.LegacyNewDec(tokens.Int64()) // as many shares as tokens validator := stakingtypes.Validator{ OperatorAddress: sdk.ValAddress(val.Address).String(), @@ -174,14 +174,14 @@ func getAppBytesAndSenders( }, UnbondingHeight: int64(0), UnbondingTime: time.Unix(0, 0).UTC(), - Commission: stakingtypes.NewCommission(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()), - MinSelfDelegation: sdk.ZeroInt(), + Commission: stakingtypes.NewCommission(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec()), + MinSelfDelegation: math.ZeroInt(), } stakingValidators = append(stakingValidators, validator) // Store delegation from the model delegator account - delegations = append(delegations, stakingtypes.NewDelegation(senderAccounts[0].SenderAccount.GetAddress(), val.Address.Bytes(), delShares)) + delegations = append(delegations, stakingtypes.NewDelegation(senderAccounts[0].SenderAccount.GetAddress().String(), val.Address.String(), delShares)) // add initial validator powers so consumer InitGenesis runs correctly pub, _ := val.ToProto() @@ -224,7 +224,7 @@ func getAppBytesAndSenders( // add unbonded amount balances = append(balances, banktypes.Balance{ Address: authtypes.NewModuleAddress(stakingtypes.NotBondedPoolName).String(), - Coins: sdk.Coins{sdk.NewCoin(bondDenom, sdk.ZeroInt())}, + Coins: sdk.Coins{sdk.NewCoin(bondDenom, math.ZeroInt())}, }) // update total funds supply @@ -259,7 +259,7 @@ func newChain( protoConsParams := CONSENSUS_PARAMS.ToProto() app.InitChain( - abcitypes.RequestInitChain{ + &abcitypes.RequestInitChain{ ChainId: chainID, Validators: cmttypes.TM2PB.ValidatorUpdates(validators), ConsensusParams: &protoConsParams, @@ -269,20 +269,16 @@ func newChain( app.Commit() - app.BeginBlock( - abcitypes.RequestBeginBlock{ - Header: cmtproto.Header{ - ChainID: chainID, - Height: app.LastBlockHeight() + 1, - AppHash: app.LastCommitID().Hash, - ValidatorsHash: validators.Hash(), - NextValidatorsHash: validators.Hash(), - }, + app.FinalizeBlock( + &abcitypes.RequestFinalizeBlock{ + Hash: app.LastCommitID().Hash, + Height: app.LastBlockHeight() + 1, + NextValidatorsHash: validators.Hash(), }, ) chain := &ibctesting.TestChain{ - T: t, + TB: t, Coordinator: coord, ChainID: chainID, App: app, @@ -380,12 +376,8 @@ func (s *Driver) ConfigureNewPath(consumerChain, providerChain *ibctesting.TestC // Commit a block on both chains, giving us two committed headers from // the same time and height. This is the starting point for all our // data driven testing. - lastConsumerHeader, _ := simibc.EndBlock(consumerChain, func() {}) - lastProviderHeader, _ := simibc.EndBlock(providerChain, func() {}) - - // Get ready to update clients. - simibc.BeginBlock(providerChain, 5) - simibc.BeginBlock(consumerChain, 5) + lastConsumerHeader, _ := simibc.FinalizeBlock(consumerChain, 5) + lastProviderHeader, _ := simibc.FinalizeBlock(providerChain, 5) // Update clients to the latest header. err = simibc.UpdateReceiverClient(consumerEndPoint, providerEndPoint, lastConsumerHeader, false) @@ -421,8 +413,7 @@ func (s *Driver) setupProvider( s.providerKeeper().SetParams(s.ctx("provider"), providerParams) // produce a first block - simibc.EndBlock(providerChain, func() {}) - simibc.BeginBlock(providerChain, 0) + simibc.FinalizeBlock(providerChain, 0) } func (s *Driver) setupConsumer( diff --git a/testutil/crypto/crypto.go b/testutil/crypto/crypto.go index a9c5341947..88fc8c6c01 100644 --- a/testutil/crypto/crypto.go +++ b/testutil/crypto/crypto.go @@ -15,7 +15,7 @@ import ( tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" tmtypes "github.com/cometbft/cometbft/types" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) // CryptoIdentity is a test helper for generating keys and addresses of @@ -61,7 +61,7 @@ func (v *CryptoIdentity) TMValidator(power int64) *tmtypes.Validator { } func (v *CryptoIdentity) TMProtoCryptoPublicKey() tmprotocrypto.PublicKey { - ret, err := sdkcryptocodec.ToTmProtoPublicKey(v.ConsensusSDKPubKey()) + ret, err := sdkcryptocodec.ToCmtProtoPublicKey(v.ConsensusSDKPubKey()) if err != nil { panic(err) } @@ -69,7 +69,7 @@ func (v *CryptoIdentity) TMProtoCryptoPublicKey() tmprotocrypto.PublicKey { } func (v *CryptoIdentity) TMCryptoPubKey() tmcrypto.PubKey { - ret, err := sdkcryptocodec.ToTmPubKeyInterface(v.ConsensusSDKPubKey()) + ret, err := sdkcryptocodec.ToCmtPubKeyInterface(v.ConsensusSDKPubKey()) if err != nil { panic(err) } @@ -77,13 +77,17 @@ func (v *CryptoIdentity) TMCryptoPubKey() tmcrypto.PubKey { } func (v *CryptoIdentity) SDKStakingValidator() sdkstakingtypes.Validator { - ret, err := sdkstakingtypes.NewValidator(v.SDKValOpAddress(), v.ConsensusSDKPubKey(), sdkstakingtypes.Description{}) + ret, err := sdkstakingtypes.NewValidator(v.SDKValOpAddressString(), v.ConsensusSDKPubKey(), sdkstakingtypes.Description{}) if err != nil { panic(err) } return ret } +func (v *CryptoIdentity) SDKValOpAddressString() string { + return sdktypes.ValAddress(v.OperatorSDKPubKey().Address()).String() +} + func (v *CryptoIdentity) ConsensusSDKPubKey() sdkcryptotypes.PubKey { return v.consensus.PubKey() } diff --git a/testutil/crypto/evidence.go b/testutil/crypto/evidence.go index 653f20824e..786db9528a 100644 --- a/testutil/crypto/evidence.go +++ b/testutil/crypto/evidence.go @@ -1,12 +1,14 @@ package crypto import ( + "fmt" "time" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/cometbft/cometbft/crypto/tmhash" "github.com/cometbft/cometbft/libs/bytes" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" tmtypes "github.com/cometbft/cometbft/types" ) @@ -36,12 +38,20 @@ func MakeAndSignVote( signer tmtypes.PrivValidator, chainID string, ) *tmtypes.Vote { + pubKey, err := signer.GetPubKey() + if err != nil { + panic(fmt.Errorf("can't get pubkey: %w", err)) + } + addr := pubKey.Address() + idx, _ := valSet.GetByAddress(addr) vote, err := tmtypes.MakeVote( - blockHeight, - blockID, - valSet, signer, chainID, + idx, // val index + blockHeight, // height + 0, // round + tmproto.PrecommitType, // type (does not work if set to sth else) + blockID, blockTime, ) if err != nil { @@ -69,13 +79,22 @@ func MakeAndSignVoteWithForgedValAddress( valAddressSigner tmtypes.PrivValidator, chainID string, ) *tmtypes.Vote { + pubKey, err := signer.GetPubKey() + if err != nil { + panic(fmt.Errorf("can't get pubkey: %w", err)) + } + addr := pubKey.Address() + idx, _ := valSet.GetByAddress(addr) + // create the vote using a different key than the signing key vote, err := tmtypes.MakeVote( - blockHeight, - blockID, - valSet, valAddressSigner, chainID, + idx, + blockHeight, + 0, + tmproto.PrecommitType, + blockID, blockTime, ) if err != nil { diff --git a/testutil/ibc_testing/generic_setup.go b/testutil/ibc_testing/generic_setup.go index 6d17337853..92f185b80c 100644 --- a/testutil/ibc_testing/generic_setup.go +++ b/testutil/ibc_testing/generic_setup.go @@ -5,8 +5,8 @@ import ( "fmt" "testing" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - ibctesting "github.com/cosmos/ibc-go/v7/testing" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + ibctesting "github.com/cosmos/ibc-go/v8/testing" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -16,9 +16,10 @@ import ( tmencoding "github.com/cometbft/cometbft/crypto/encoding" tmtypes "github.com/cometbft/cometbft/types" - testutil "github.com/cosmos/interchain-security/v4/testutil/integration" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - consumerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" + testutil "github.com/cosmos/interchain-security/v5/testutil/integration" + consumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) type ( @@ -124,16 +125,28 @@ func AddConsumer[Tp testutil.ProviderApp, Tc testutil.ConsumerApp]( providerApp := providerChain.App.(Tp) providerKeeper := providerApp.GetProviderKeeper() - prop := testkeeper.GetTestConsumerAdditionProp() - prop.ChainId = chainID - // NOTE: the initial height passed to CreateConsumerClient - // must be the height on the consumer when InitGenesis is called - prop.InitialHeight = clienttypes.Height{RevisionNumber: 0, RevisionHeight: 3} - err := providerKeeper.CreateConsumerClient( - providerChain.GetContext(), - prop, - ) - s.Require().NoError(err) + prop := providertypes.ConsumerAdditionProposal{ + Title: fmt.Sprintf("start chain %s", chainID), + Description: "description", + ChainId: chainID, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 2}, + GenesisHash: []byte("gen_hash"), + BinaryHash: []byte("bin_hash"), + // NOTE: we cannot use the time.Now() because the coordinator chooses a hardcoded start time + // using time.Now() could set the spawn time to be too far in the past or too far in the future + SpawnTime: coordinator.CurrentTime, + UnbondingPeriod: ccvtypes.DefaultConsumerUnbondingPeriod, + CcvTimeoutPeriod: ccvtypes.DefaultBlocksPerDistributionTransmission, + TransferTimeoutPeriod: ccvtypes.DefaultCCVTimeoutPeriod, + ConsumerRedistributionFraction: ccvtypes.DefaultConsumerRedistributeFrac, + BlocksPerDistributionTransmission: ccvtypes.DefaultBlocksPerDistributionTransmission, + HistoricalEntries: ccvtypes.DefaultHistoricalEntries, + DistributionTransmissionChannel: "", + } + + providerKeeper.SetPendingConsumerAdditionProp(providerChain.GetContext(), &prop) + propsToExecute := providerKeeper.GetConsumerAdditionPropsToExecute(providerChain.GetContext()) + s.Require().Len(propsToExecute, 1, "props to execute is incorrect length") // commit the state on the provider chain coordinator.CommitBlock(providerChain) @@ -150,7 +163,7 @@ func AddConsumer[Tp testutil.ProviderApp, Tc testutil.ConsumerApp]( for _, update := range consumerGenesisState.Provider.InitialValSet { // tmPubKey update.PubKey tmPubKey, err := tmencoding.PubKeyFromProto(update.PubKey) - s.Require().NoError(err) + s.Require().NoError(err, "failed to convert tendermint pubkey") valz = append(valz, &tmtypes.Validator{ PubKey: tmPubKey, VotingPower: update.Power, diff --git a/testutil/ibc_testing/specific_setup.go b/testutil/ibc_testing/specific_setup.go index 2571346ca6..2ff06ca757 100644 --- a/testutil/ibc_testing/specific_setup.go +++ b/testutil/ibc_testing/specific_setup.go @@ -7,21 +7,21 @@ package ibc_testing import ( "encoding/json" - ibctesting "github.com/cosmos/ibc-go/v7/testing" + db "github.com/cosmos/cosmos-db" + ibctesting "github.com/cosmos/ibc-go/v8/testing" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - tmdb "github.com/cometbft/cometbft-db" + "cosmossdk.io/log" "github.com/cometbft/cometbft/abci/types" - "github.com/cometbft/cometbft/libs/log" - appConsumer "github.com/cosmos/interchain-security/v4/app/consumer" - appConsumerDemocracy "github.com/cosmos/interchain-security/v4/app/consumer-democracy" - appProvider "github.com/cosmos/interchain-security/v4/app/provider" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + appConsumer "github.com/cosmos/interchain-security/v5/app/consumer" + appConsumerDemocracy "github.com/cosmos/interchain-security/v5/app/consumer-democracy" + appProvider "github.com/cosmos/interchain-security/v5/app/provider" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) var ( @@ -33,7 +33,7 @@ var ( // ProviderAppIniter implements ibctesting.AppIniter for a provider app func ProviderAppIniter() (ibctesting.TestingApp, map[string]json.RawMessage) { encoding := appProvider.MakeTestEncodingConfig() - testApp := appProvider.New(log.NewNopLogger(), tmdb.NewMemDB(), nil, true, simtestutil.EmptyAppOptions{}) + testApp := appProvider.New(log.NewNopLogger(), db.NewMemDB(), nil, true, simtestutil.EmptyAppOptions{}) return testApp, appProvider.NewDefaultGenesisState(encoding.Codec) } @@ -41,9 +41,9 @@ func ProviderAppIniter() (ibctesting.TestingApp, map[string]json.RawMessage) { func ConsumerAppIniter(initValPowers []types.ValidatorUpdate) AppIniter { return func() (ibctesting.TestingApp, map[string]json.RawMessage) { encoding := appConsumer.MakeTestEncodingConfig() - testApp := appConsumer.New(log.NewNopLogger(), tmdb.NewMemDB(), nil, true, simtestutil.EmptyAppOptions{}) + testApp := appConsumer.New(log.NewNopLogger(), db.NewMemDB(), nil, true, simtestutil.EmptyAppOptions{}) genesisState := appConsumer.NewDefaultGenesisState(encoding.Codec) - // NOTE ibc-go/v7/testing.SetupWithGenesisValSet requires a staking module + // NOTE: starting from ibc-go/v7/testing.SetupWithGenesisValSet requires a staking module // genesisState or it panics. Feed a minimum one. genesisState[stakingtypes.ModuleName] = encoding.Codec.MustMarshalJSON( &stakingtypes.GenesisState{ @@ -65,7 +65,7 @@ func ConsumerAppIniter(initValPowers []types.ValidatorUpdate) AppIniter { func DemocracyConsumerAppIniter(initValPowers []types.ValidatorUpdate) AppIniter { return func() (ibctesting.TestingApp, map[string]json.RawMessage) { encoding := appConsumerDemocracy.MakeTestEncodingConfig() - testApp := appConsumerDemocracy.New(log.NewNopLogger(), tmdb.NewMemDB(), nil, true, simtestutil.EmptyAppOptions{}) + testApp := appConsumerDemocracy.New(log.NewNopLogger(), db.NewMemDB(), nil, true, simtestutil.EmptyAppOptions{}) genesisState := appConsumerDemocracy.NewDefaultGenesisState(encoding.Codec) // Feed consumer genesis with provider validators // TODO See if useful for democracy diff --git a/testutil/integration/debug_test.go b/testutil/integration/debug_test.go index 77d460f05f..ea6f01b7ec 100644 --- a/testutil/integration/debug_test.go +++ b/testutil/integration/debug_test.go @@ -6,11 +6,11 @@ import ( "reflect" "testing" - appConsumer "github.com/cosmos/interchain-security/v4/app/consumer" - appConsumerDemocracy "github.com/cosmos/interchain-security/v4/app/consumer-democracy" - appProvider "github.com/cosmos/interchain-security/v4/app/provider" - integr "github.com/cosmos/interchain-security/v4/tests/integration" - icstestingutils "github.com/cosmos/interchain-security/v4/testutil/ibc_testing" + appConsumer "github.com/cosmos/interchain-security/v5/app/consumer" + appConsumerDemocracy "github.com/cosmos/interchain-security/v5/app/consumer-democracy" + appProvider "github.com/cosmos/interchain-security/v5/app/provider" + integr "github.com/cosmos/interchain-security/v5/tests/integration" + icstestingutils "github.com/cosmos/interchain-security/v5/testutil/ibc_testing" ) // runCCVTestByName runs a single CCV integration test by name, using a CCVTestSuite diff --git a/testutil/integration/interfaces.go b/testutil/integration/interfaces.go index 89d59904df..3f8428f9d0 100644 --- a/testutil/integration/interfaces.go +++ b/testutil/integration/interfaces.go @@ -1,28 +1,28 @@ package integration import ( + "context" "time" - ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibctesting "github.com/cosmos/ibc-go/v8/testing" + "cosmossdk.io/core/comet" "cosmossdk.io/math" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" - govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" - minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" - "github.com/cosmos/cosmos-sdk/x/staking/types" - - abci "github.com/cometbft/cometbft/abci/types" - - consumerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" - providerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" + + evidencekeeper "cosmossdk.io/x/evidence/keeper" + govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" + mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" + consumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" ) // The interface that any provider app must implement to be compatible with ccv integration tests. @@ -46,6 +46,8 @@ type ProviderApp interface { GetTestDistributionKeeper() TestDistributionKeeper // Returns an account keeper interface with more capabilities than the expected_keepers interface GetTestAccountKeeper() TestAccountKeeper + + // GetTestGovKeeper() govkeeper.Keeper } // The interface that any consumer app must implement to be compatible with integration tests @@ -53,7 +55,7 @@ type ProviderApp interface { type ConsumerApp interface { ibctesting.TestingApp - BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock + // BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock GetConsumerKeeper() consumerkeeper.Keeper GetSubspace(moduleName string) paramstypes.Subspace @@ -68,7 +70,7 @@ type ConsumerApp interface { // Tests a slashing keeper interface with more capabilities than the expected_keepers interface GetTestSlashingKeeper() TestSlashingKeeper // Tests an evidence keeper interface with more capabilities than the expected_keepers interface - GetTestEvidenceKeeper() TestEvidenceKeeper + GetTestEvidenceKeeper() evidencekeeper.Keeper } type DemocConsumerApp interface { @@ -78,9 +80,10 @@ type DemocConsumerApp interface { // Tests a staking keeper interface with more capabilities than the expected_keepers interface GetTestStakingKeeper() TestStakingKeeper // Tests a mint keeper interface with more capabilities than the expected_keepers interface - GetTestMintKeeper() TestMintKeeper - // Tests a gov keeper interface with more capabilities than the expected_keepers interface - GetTestGovKeeper() TestGovKeeper + GetTestMintKeeper() mintkeeper.Keeper + + // @MSalopek -> on v50 we need to access the Params collection which does not have a getter + GetTestGovKeeper() govkeeper.Keeper } // @@ -90,68 +93,51 @@ type DemocConsumerApp interface { type TestStakingKeeper interface { ccvtypes.StakingKeeper - Delegate(ctx sdk.Context, delAddr sdk.AccAddress, bondAmt math.Int, tokenSrc types.BondStatus, - validator types.Validator, subtractAccount bool) (newShares sdk.Dec, err error) - Undelegate(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount sdk.Dec, - ) (time.Time, error) - BeginRedelegation(ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, - sharesAmount sdk.Dec) (completionTime time.Time, err error) - GetUnbondingDelegationByUnbondingID(ctx sdk.Context, id uint64, - ) (ubd types.UnbondingDelegation, found bool) - GetRedelegations(ctx sdk.Context, delegator sdk.AccAddress, - maxRetrieve uint16) (redelegations []types.Redelegation) - BondDenom(ctx sdk.Context) (res string) - IsValidatorJailed(ctx sdk.Context, addr sdk.ConsAddress) bool - GetUnbondingDelegation(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, - ) (ubd types.UnbondingDelegation, found bool) - GetAllValidators(ctx sdk.Context) (validators []types.Validator) - GetValidatorSet() types.ValidatorSet + Delegate( + ctx context.Context, delAddr sdk.AccAddress, bondAmt math.Int, tokenSrc stakingtypes.BondStatus, + validator stakingtypes.Validator, subtractAccount bool, + ) (newShares math.LegacyDec, err error) + Undelegate(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount math.LegacyDec, + ) (time.Time, math.Int, error) + BeginRedelegation( + ctx context.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, sharesAmount math.LegacyDec, + ) (completionTime time.Time, err error) + GetUnbondingDelegationByUnbondingID(ctx context.Context, id uint64) (ubd stakingtypes.UnbondingDelegation, err error) + GetRedelegations(ctx context.Context, delegator sdk.AccAddress, maxRetrieve uint16) (redelegations []stakingtypes.Redelegation, err error) + GetUnbondingDelegation(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (ubd stakingtypes.UnbondingDelegation, err error) + GetAllValidators(ctx context.Context) (validators []stakingtypes.Validator, err error) + GetValidatorSet() stakingtypes.ValidatorSet } type TestBankKeeper interface { ccvtypes.BankKeeper - SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, + SendCoinsFromAccountToModule(ctx context.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error - SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, + SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error } type TestAccountKeeper interface { ccvtypes.AccountKeeper - GetParams(sdk.Context) authtypes.Params + GetParams(context.Context) authtypes.Params } type TestSlashingKeeper interface { ccvtypes.SlashingKeeper - SetValidatorSigningInfo(ctx sdk.Context, address sdk.ConsAddress, - info slashingtypes.ValidatorSigningInfo) - SignedBlocksWindow(ctx sdk.Context) (res int64) - HandleValidatorSignature(ctx sdk.Context, addr cryptotypes.Address, power int64, signed bool) - MinSignedPerWindow(ctx sdk.Context) int64 - IterateValidatorMissedBlockBitArray(ctx sdk.Context, - address sdk.ConsAddress, handler func(index int64, missed bool) (stop bool)) -} - -type TestEvidenceKeeper interface { - HandleEquivocationEvidence(ctx sdk.Context, evidence *evidencetypes.Equivocation) + SetValidatorSigningInfo(ctx context.Context, address sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) error + SignedBlocksWindow(ctx context.Context) (int64, error) + HandleValidatorSignature(ctx context.Context, addr cryptotypes.Address, power int64, signed comet.BlockIDFlag) error + MinSignedPerWindow(ctx context.Context) (int64, error) + // NOTE: @MSalopek deprecated in v50 + // IterateValidatorMissedBlockBitArray(ctx sdk.Context, + // address sdk.ConsAddress, handler func(index int64, missed bool) (stop bool)) + IterateMissedBlockBitmap(ctx context.Context, addr sdk.ConsAddress, cb func(index int64, missed bool) (stop bool)) error } type TestDistributionKeeper interface { - GetFeePoolCommunityCoins(ctx sdk.Context) sdk.DecCoins - GetDistributionAccount(ctx sdk.Context) authtypes.ModuleAccountI - GetValidatorOutstandingRewards(ctx sdk.Context, - val sdk.ValAddress) (rewards distributiontypes.ValidatorOutstandingRewards) - GetCommunityTax(ctx sdk.Context) (percent sdk.Dec) -} - -type TestMintKeeper interface { - GetParams(ctx sdk.Context) (params minttypes.Params) -} - -type TestGovKeeper interface { - GetParams(ctx sdk.Context) govv1.Params - SetParams(ctx sdk.Context, params govv1.Params) error - SubmitProposal(ctx sdk.Context, messages []sdk.Msg, metadata, title, summary string, proposer sdk.AccAddress) (govv1.Proposal, error) - AddDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress, depositAmount sdk.Coins) (bool, error) - AddVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress, options govv1.WeightedVoteOptions, metadata string) error + // NOTE: @MSalopek deprecated in v50 + // GetFeePoolCommunityCoins(ctx sdk.Context) sdk.DecCoins + GetDistributionAccount(ctx context.Context) sdk.ModuleAccountI + GetValidatorOutstandingRewards(ctx context.Context, val sdk.ValAddress) (rewards distributiontypes.ValidatorOutstandingRewards, err error) + GetCommunityTax(ctx context.Context) (math.LegacyDec, error) } diff --git a/testutil/keeper/expectations.go b/testutil/keeper/expectations.go index 5a37f3a164..f6734d64f6 100644 --- a/testutil/keeper/expectations.go +++ b/testutil/keeper/expectations.go @@ -3,22 +3,22 @@ package keeper import ( time "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v7/modules/core/24-host" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + conntypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/golang/mock/gomock" extra "github.com/oxyno-zeta/gomock-extra-matcher" math "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - "github.com/cosmos/interchain-security/v4/x/ccv/types" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // @@ -53,7 +53,7 @@ func GetMocksForMakeConsumerGenesis(ctx sdk.Context, mocks *MockedKeepers, unbondingTimeToInject time.Duration, ) []*gomock.Call { return []*gomock.Call{ - mocks.MockStakingKeeper.EXPECT().UnbondingTime(gomock.Any()).Return(unbondingTimeToInject).Times(1), + mocks.MockStakingKeeper.EXPECT().UnbondingTime(gomock.Any()).Return(unbondingTimeToInject, nil).Times(1), mocks.MockClientKeeper.EXPECT().GetSelfConsensusState(gomock.Any(), clienttypes.GetSelfHeight(ctx)).Return(&ibctmtypes.ConsensusState{}, nil).Times(1), @@ -104,7 +104,7 @@ func GetMocksForHandleSlashPacket(ctx sdk.Context, mocks MockedKeepers, calls := []*gomock.Call{ mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( ctx, expectedProviderValConsAddr.ToSdkConsAddr()).Return( - valToReturn, true, + valToReturn, nil, ).Times(1), mocks.MockSlashingKeeper.EXPECT().IsTombstoned(ctx, @@ -115,12 +115,12 @@ func GetMocksForHandleSlashPacket(ctx sdk.Context, mocks MockedKeepers, calls = append(calls, mocks.MockStakingKeeper.EXPECT().Jail( gomock.Eq(ctx), gomock.Eq(expectedProviderValConsAddr.ToSdkConsAddr()), - ).Return()) + ).Return(nil)) // JailUntil is set in this code path. - calls = append(calls, mocks.MockSlashingKeeper.EXPECT().DowntimeJailDuration(ctx).Return(time.Hour).Times(1)) + calls = append(calls, mocks.MockSlashingKeeper.EXPECT().DowntimeJailDuration(ctx).Return(time.Hour, nil).Times(1)) calls = append(calls, mocks.MockSlashingKeeper.EXPECT().JailUntil(ctx, - expectedProviderValConsAddr.ToSdkConsAddr(), gomock.Any()).Times(1)) + expectedProviderValConsAddr.ToSdkConsAddr(), gomock.Any()).Return(nil).Times(1)) } return calls @@ -188,26 +188,26 @@ func GetMocksForSlashValidator( mocks.MockStakingKeeper.EXPECT(). SlashUnbondingDelegation(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). DoAndReturn( - func(_ sdk.Context, undelegation stakingtypes.UnbondingDelegation, _ int64, _ sdk.Dec) math.Int { - sum := sdk.NewInt(0) + func(_ sdk.Context, undelegation stakingtypes.UnbondingDelegation, _ int64, _ math.LegacyDec) math.Int { + sum := math.NewInt(0) for _, r := range undelegation.Entries { if r.IsMature(ctx.BlockTime()) { continue } - sum = sum.Add(sdk.NewInt(r.InitialBalance.Int64())) + sum = sum.Add(math.NewInt(r.InitialBalance.Int64())) } return sum }).AnyTimes(), mocks.MockStakingKeeper.EXPECT(). SlashRedelegation(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). DoAndReturn( - func(_ sdk.Context, _ stakingtypes.Validator, redelegation stakingtypes.Redelegation, _ int64, _ sdk.Dec) math.Int { - sum := sdk.NewInt(0) + func(_ sdk.Context, _ stakingtypes.Validator, redelegation stakingtypes.Redelegation, _ int64, _ math.LegacyDec) math.Int { + sum := math.NewInt(0) for _, r := range redelegation.Entries { if r.IsMature(ctx.BlockTime()) { continue } - sum = sum.Add(sdk.NewInt(r.InitialBalance.Int64())) + sum = sum.Add(math.NewInt(r.InitialBalance.Int64())) } return sum }).AnyTimes(), diff --git a/testutil/keeper/mocks.go b/testutil/keeper/mocks.go index 5f9d9b2694..f0cb00b07f 100644 --- a/testutil/keeper/mocks.go +++ b/testutil/keeper/mocks.go @@ -10,18 +10,17 @@ import ( time "time" math "cosmossdk.io/math" - types "github.com/cometbft/cometbft/abci/types" - types0 "github.com/cosmos/cosmos-sdk/types" - types1 "github.com/cosmos/cosmos-sdk/x/auth/types" - types2 "github.com/cosmos/cosmos-sdk/x/capability/types" - v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" - types3 "github.com/cosmos/cosmos-sdk/x/slashing/types" - types4 "github.com/cosmos/cosmos-sdk/x/staking/types" - types5 "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - types6 "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - types7 "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" - types8 "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - exported "github.com/cosmos/ibc-go/v7/modules/core/exported" + types "cosmossdk.io/store/types" + types0 "github.com/cometbft/cometbft/abci/types" + types1 "github.com/cosmos/cosmos-sdk/types" + types2 "github.com/cosmos/cosmos-sdk/x/slashing/types" + types3 "github.com/cosmos/cosmos-sdk/x/staking/types" + types4 "github.com/cosmos/ibc-go/modules/capability/types" + types5 "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + types6 "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + types7 "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + types8 "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + exported "github.com/cosmos/ibc-go/v8/modules/core/exported" gomock "github.com/golang/mock/gomock" ) @@ -49,11 +48,12 @@ func (m *MockStakingKeeper) EXPECT() *MockStakingKeeperMockRecorder { } // BondDenom mocks base method. -func (m *MockStakingKeeper) BondDenom(ctx types0.Context) string { +func (m *MockStakingKeeper) BondDenom(ctx context.Context) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BondDenom", ctx) ret0, _ := ret[0].(string) - return ret0 + ret1, _ := ret[1].(error) + return ret0, ret1 } // BondDenom indicates an expected call of BondDenom. @@ -63,11 +63,12 @@ func (mr *MockStakingKeeperMockRecorder) BondDenom(ctx interface{}) *gomock.Call } // Delegation mocks base method. -func (m *MockStakingKeeper) Delegation(ctx types0.Context, addr types0.AccAddress, valAddr types0.ValAddress) types4.DelegationI { +func (m *MockStakingKeeper) Delegation(ctx context.Context, addr types1.AccAddress, valAddr types1.ValAddress) (types3.DelegationI, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Delegation", ctx, addr, valAddr) - ret0, _ := ret[0].(types4.DelegationI) - return ret0 + ret0, _ := ret[0].(types3.DelegationI) + ret1, _ := ret[1].(error) + return ret0, ret1 } // Delegation indicates an expected call of Delegation. @@ -77,11 +78,12 @@ func (mr *MockStakingKeeperMockRecorder) Delegation(ctx, addr, valAddr interface } // GetLastTotalPower mocks base method. -func (m *MockStakingKeeper) GetLastTotalPower(ctx types0.Context) math.Int { +func (m *MockStakingKeeper) GetLastTotalPower(ctx context.Context) (math.Int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetLastTotalPower", ctx) ret0, _ := ret[0].(math.Int) - return ret0 + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetLastTotalPower indicates an expected call of GetLastTotalPower. @@ -91,11 +93,12 @@ func (mr *MockStakingKeeperMockRecorder) GetLastTotalPower(ctx interface{}) *gom } // GetLastValidatorPower mocks base method. -func (m *MockStakingKeeper) GetLastValidatorPower(ctx types0.Context, operator types0.ValAddress) int64 { +func (m *MockStakingKeeper) GetLastValidatorPower(ctx context.Context, operator types1.ValAddress) (int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetLastValidatorPower", ctx, operator) ret0, _ := ret[0].(int64) - return ret0 + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetLastValidatorPower indicates an expected call of GetLastValidatorPower. @@ -105,11 +108,12 @@ func (mr *MockStakingKeeperMockRecorder) GetLastValidatorPower(ctx, operator int } // GetLastValidators mocks base method. -func (m *MockStakingKeeper) GetLastValidators(ctx types0.Context) []types4.Validator { +func (m *MockStakingKeeper) GetLastValidators(ctx context.Context) ([]types3.Validator, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetLastValidators", ctx) - ret0, _ := ret[0].([]types4.Validator) - return ret0 + ret0, _ := ret[0].([]types3.Validator) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetLastValidators indicates an expected call of GetLastValidators. @@ -119,11 +123,12 @@ func (mr *MockStakingKeeperMockRecorder) GetLastValidators(ctx interface{}) *gom } // GetRedelegationsFromSrcValidator mocks base method. -func (m *MockStakingKeeper) GetRedelegationsFromSrcValidator(ctx types0.Context, valAddr types0.ValAddress) []types4.Redelegation { +func (m *MockStakingKeeper) GetRedelegationsFromSrcValidator(ctx context.Context, valAddr types1.ValAddress) ([]types3.Redelegation, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetRedelegationsFromSrcValidator", ctx, valAddr) - ret0, _ := ret[0].([]types4.Redelegation) - return ret0 + ret0, _ := ret[0].([]types3.Redelegation) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetRedelegationsFromSrcValidator indicates an expected call of GetRedelegationsFromSrcValidator. @@ -133,11 +138,12 @@ func (mr *MockStakingKeeperMockRecorder) GetRedelegationsFromSrcValidator(ctx, v } // GetUnbondingDelegationsFromValidator mocks base method. -func (m *MockStakingKeeper) GetUnbondingDelegationsFromValidator(ctx types0.Context, valAddr types0.ValAddress) []types4.UnbondingDelegation { +func (m *MockStakingKeeper) GetUnbondingDelegationsFromValidator(ctx context.Context, valAddr types1.ValAddress) ([]types3.UnbondingDelegation, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUnbondingDelegationsFromValidator", ctx, valAddr) - ret0, _ := ret[0].([]types4.UnbondingDelegation) - return ret0 + ret0, _ := ret[0].([]types3.UnbondingDelegation) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetUnbondingDelegationsFromValidator indicates an expected call of GetUnbondingDelegationsFromValidator. @@ -147,11 +153,11 @@ func (mr *MockStakingKeeperMockRecorder) GetUnbondingDelegationsFromValidator(ct } // GetUnbondingType mocks base method. -func (m *MockStakingKeeper) GetUnbondingType(ctx types0.Context, id uint64) (types4.UnbondingType, bool) { +func (m *MockStakingKeeper) GetUnbondingType(ctx context.Context, id uint64) (types3.UnbondingType, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUnbondingType", ctx, id) - ret0, _ := ret[0].(types4.UnbondingType) - ret1, _ := ret[1].(bool) + ret0, _ := ret[0].(types3.UnbondingType) + ret1, _ := ret[1].(error) return ret0, ret1 } @@ -162,11 +168,11 @@ func (mr *MockStakingKeeperMockRecorder) GetUnbondingType(ctx, id interface{}) * } // GetValidator mocks base method. -func (m *MockStakingKeeper) GetValidator(ctx types0.Context, addr types0.ValAddress) (types4.Validator, bool) { +func (m *MockStakingKeeper) GetValidator(ctx context.Context, addr types1.ValAddress) (types3.Validator, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetValidator", ctx, addr) - ret0, _ := ret[0].(types4.Validator) - ret1, _ := ret[1].(bool) + ret0, _ := ret[0].(types3.Validator) + ret1, _ := ret[1].(error) return ret0, ret1 } @@ -177,11 +183,11 @@ func (mr *MockStakingKeeperMockRecorder) GetValidator(ctx, addr interface{}) *go } // GetValidatorByConsAddr mocks base method. -func (m *MockStakingKeeper) GetValidatorByConsAddr(ctx types0.Context, consAddr types0.ConsAddress) (types4.Validator, bool) { +func (m *MockStakingKeeper) GetValidatorByConsAddr(ctx context.Context, consAddr types1.ConsAddress) (types3.Validator, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetValidatorByConsAddr", ctx, consAddr) - ret0, _ := ret[0].(types4.Validator) - ret1, _ := ret[1].(bool) + ret0, _ := ret[0].(types3.Validator) + ret1, _ := ret[1].(error) return ret0, ret1 } @@ -192,11 +198,12 @@ func (mr *MockStakingKeeperMockRecorder) GetValidatorByConsAddr(ctx, consAddr in } // GetValidatorUpdates mocks base method. -func (m *MockStakingKeeper) GetValidatorUpdates(ctx types0.Context) []types.ValidatorUpdate { +func (m *MockStakingKeeper) GetValidatorUpdates(ctx context.Context) ([]types0.ValidatorUpdate, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetValidatorUpdates", ctx) - ret0, _ := ret[0].([]types.ValidatorUpdate) - return ret0 + ret0, _ := ret[0].([]types0.ValidatorUpdate) + ret1, _ := ret[1].(error) + return ret0, ret1 } // GetValidatorUpdates indicates an expected call of GetValidatorUpdates. @@ -206,11 +213,12 @@ func (mr *MockStakingKeeperMockRecorder) GetValidatorUpdates(ctx interface{}) *g } // IsValidatorJailed mocks base method. -func (m *MockStakingKeeper) IsValidatorJailed(ctx types0.Context, addr types0.ConsAddress) bool { +func (m *MockStakingKeeper) IsValidatorJailed(ctx context.Context, addr types1.ConsAddress) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IsValidatorJailed", ctx, addr) ret0, _ := ret[0].(bool) - return ret0 + ret1, _ := ret[1].(error) + return ret0, ret1 } // IsValidatorJailed indicates an expected call of IsValidatorJailed. @@ -220,9 +228,11 @@ func (mr *MockStakingKeeperMockRecorder) IsValidatorJailed(ctx, addr interface{} } // IterateLastValidatorPowers mocks base method. -func (m *MockStakingKeeper) IterateLastValidatorPowers(ctx types0.Context, cb func(types0.ValAddress, int64) bool) { +func (m *MockStakingKeeper) IterateLastValidatorPowers(ctx context.Context, cb func(types1.ValAddress, int64) bool) error { m.ctrl.T.Helper() - m.ctrl.Call(m, "IterateLastValidatorPowers", ctx, cb) + ret := m.ctrl.Call(m, "IterateLastValidatorPowers", ctx, cb) + ret0, _ := ret[0].(error) + return ret0 } // IterateLastValidatorPowers indicates an expected call of IterateLastValidatorPowers. @@ -232,9 +242,11 @@ func (mr *MockStakingKeeperMockRecorder) IterateLastValidatorPowers(ctx, cb inte } // IterateValidators mocks base method. -func (m *MockStakingKeeper) IterateValidators(ctx types0.Context, f func(int64, types4.ValidatorI) bool) { +func (m *MockStakingKeeper) IterateValidators(ctx context.Context, f func(int64, types3.ValidatorI) bool) error { m.ctrl.T.Helper() - m.ctrl.Call(m, "IterateValidators", ctx, f) + ret := m.ctrl.Call(m, "IterateValidators", ctx, f) + ret0, _ := ret[0].(error) + return ret0 } // IterateValidators indicates an expected call of IterateValidators. @@ -244,9 +256,11 @@ func (mr *MockStakingKeeperMockRecorder) IterateValidators(ctx, f interface{}) * } // Jail mocks base method. -func (m *MockStakingKeeper) Jail(arg0 types0.Context, arg1 types0.ConsAddress) { +func (m *MockStakingKeeper) Jail(arg0 context.Context, arg1 types1.ConsAddress) error { m.ctrl.T.Helper() - m.ctrl.Call(m, "Jail", arg0, arg1) + ret := m.ctrl.Call(m, "Jail", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 } // Jail indicates an expected call of Jail. @@ -256,11 +270,12 @@ func (mr *MockStakingKeeperMockRecorder) Jail(arg0, arg1 interface{}) *gomock.Ca } // MaxValidators mocks base method. -func (m *MockStakingKeeper) MaxValidators(ctx types0.Context) uint32 { +func (m *MockStakingKeeper) MaxValidators(ctx context.Context) (uint32, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MaxValidators", ctx) ret0, _ := ret[0].(uint32) - return ret0 + ret1, _ := ret[1].(error) + return ret0, ret1 } // MaxValidators indicates an expected call of MaxValidators. @@ -270,7 +285,7 @@ func (mr *MockStakingKeeperMockRecorder) MaxValidators(ctx interface{}) *gomock. } // PowerReduction mocks base method. -func (m *MockStakingKeeper) PowerReduction(ctx types0.Context) math.Int { +func (m *MockStakingKeeper) PowerReduction(ctx context.Context) math.Int { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PowerReduction", ctx) ret0, _ := ret[0].(math.Int) @@ -284,7 +299,7 @@ func (mr *MockStakingKeeperMockRecorder) PowerReduction(ctx interface{}) *gomock } // PutUnbondingOnHold mocks base method. -func (m *MockStakingKeeper) PutUnbondingOnHold(ctx types0.Context, id uint64) error { +func (m *MockStakingKeeper) PutUnbondingOnHold(ctx context.Context, id uint64) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PutUnbondingOnHold", ctx, id) ret0, _ := ret[0].(error) @@ -298,63 +313,67 @@ func (mr *MockStakingKeeperMockRecorder) PutUnbondingOnHold(ctx, id interface{}) } // Slash mocks base method. -func (m *MockStakingKeeper) Slash(arg0 types0.Context, arg1 types0.ConsAddress, arg2, arg3 int64, arg4 types0.Dec) math.Int { +func (m *MockStakingKeeper) Slash(ctx context.Context, consAddr types1.ConsAddress, infractionHeight, power int64, slashFactor math.LegacyDec) (math.Int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Slash", arg0, arg1, arg2, arg3, arg4) + ret := m.ctrl.Call(m, "Slash", ctx, consAddr, infractionHeight, power, slashFactor) ret0, _ := ret[0].(math.Int) - return ret0 + ret1, _ := ret[1].(error) + return ret0, ret1 } // Slash indicates an expected call of Slash. -func (mr *MockStakingKeeperMockRecorder) Slash(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockStakingKeeperMockRecorder) Slash(ctx, consAddr, infractionHeight, power, slashFactor interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Slash", reflect.TypeOf((*MockStakingKeeper)(nil).Slash), arg0, arg1, arg2, arg3, arg4) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Slash", reflect.TypeOf((*MockStakingKeeper)(nil).Slash), ctx, consAddr, infractionHeight, power, slashFactor) } // SlashRedelegation mocks base method. -func (m *MockStakingKeeper) SlashRedelegation(arg0 types0.Context, arg1 types4.Validator, arg2 types4.Redelegation, arg3 int64, arg4 types0.Dec) math.Int { +func (m *MockStakingKeeper) SlashRedelegation(ctx context.Context, srcValidator types3.Validator, redelegation types3.Redelegation, infractionHeight int64, slashFactor math.LegacyDec) (math.Int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SlashRedelegation", arg0, arg1, arg2, arg3, arg4) + ret := m.ctrl.Call(m, "SlashRedelegation", ctx, srcValidator, redelegation, infractionHeight, slashFactor) ret0, _ := ret[0].(math.Int) - return ret0 + ret1, _ := ret[1].(error) + return ret0, ret1 } // SlashRedelegation indicates an expected call of SlashRedelegation. -func (mr *MockStakingKeeperMockRecorder) SlashRedelegation(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockStakingKeeperMockRecorder) SlashRedelegation(ctx, srcValidator, redelegation, infractionHeight, slashFactor interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SlashRedelegation", reflect.TypeOf((*MockStakingKeeper)(nil).SlashRedelegation), arg0, arg1, arg2, arg3, arg4) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SlashRedelegation", reflect.TypeOf((*MockStakingKeeper)(nil).SlashRedelegation), ctx, srcValidator, redelegation, infractionHeight, slashFactor) } // SlashUnbondingDelegation mocks base method. -func (m *MockStakingKeeper) SlashUnbondingDelegation(arg0 types0.Context, arg1 types4.UnbondingDelegation, arg2 int64, arg3 types0.Dec) math.Int { +func (m *MockStakingKeeper) SlashUnbondingDelegation(ctx context.Context, unbondingDelegation types3.UnbondingDelegation, infractionHeight int64, slashFactor math.LegacyDec) (math.Int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SlashUnbondingDelegation", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "SlashUnbondingDelegation", ctx, unbondingDelegation, infractionHeight, slashFactor) ret0, _ := ret[0].(math.Int) - return ret0 + ret1, _ := ret[1].(error) + return ret0, ret1 } // SlashUnbondingDelegation indicates an expected call of SlashUnbondingDelegation. -func (mr *MockStakingKeeperMockRecorder) SlashUnbondingDelegation(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { +func (mr *MockStakingKeeperMockRecorder) SlashUnbondingDelegation(ctx, unbondingDelegation, infractionHeight, slashFactor interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SlashUnbondingDelegation", reflect.TypeOf((*MockStakingKeeper)(nil).SlashUnbondingDelegation), arg0, arg1, arg2, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SlashUnbondingDelegation", reflect.TypeOf((*MockStakingKeeper)(nil).SlashUnbondingDelegation), ctx, unbondingDelegation, infractionHeight, slashFactor) } // SlashWithInfractionReason mocks base method. -func (m *MockStakingKeeper) SlashWithInfractionReason(arg0 types0.Context, arg1 types0.ConsAddress, arg2, arg3 int64, arg4 types0.Dec, arg5 types4.Infraction) math.Int { +func (m *MockStakingKeeper) SlashWithInfractionReason(ctx context.Context, consAddr types1.ConsAddress, infractionHeight, power int64, slashFactor math.LegacyDec, infraction types3.Infraction) (math.Int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SlashWithInfractionReason", arg0, arg1, arg2, arg3, arg4, arg5) + ret := m.ctrl.Call(m, "SlashWithInfractionReason", ctx, consAddr, infractionHeight, power, slashFactor, infraction) ret0, _ := ret[0].(math.Int) - return ret0 + ret1, _ := ret[1].(error) + return ret0, ret1 } // SlashWithInfractionReason indicates an expected call of SlashWithInfractionReason. -func (mr *MockStakingKeeperMockRecorder) SlashWithInfractionReason(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { +func (mr *MockStakingKeeperMockRecorder) SlashWithInfractionReason(ctx, consAddr, infractionHeight, power, slashFactor, infraction interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SlashWithInfractionReason", reflect.TypeOf((*MockStakingKeeper)(nil).SlashWithInfractionReason), arg0, arg1, arg2, arg3, arg4, arg5) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SlashWithInfractionReason", reflect.TypeOf((*MockStakingKeeper)(nil).SlashWithInfractionReason), ctx, consAddr, infractionHeight, power, slashFactor, infraction) } // UnbondingCanComplete mocks base method. -func (m *MockStakingKeeper) UnbondingCanComplete(ctx types0.Context, id uint64) error { +func (m *MockStakingKeeper) UnbondingCanComplete(ctx context.Context, id uint64) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UnbondingCanComplete", ctx, id) ret0, _ := ret[0].(error) @@ -368,11 +387,12 @@ func (mr *MockStakingKeeperMockRecorder) UnbondingCanComplete(ctx, id interface{ } // UnbondingTime mocks base method. -func (m *MockStakingKeeper) UnbondingTime(ctx types0.Context) time.Duration { +func (m *MockStakingKeeper) UnbondingTime(ctx context.Context) (time.Duration, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UnbondingTime", ctx) ret0, _ := ret[0].(time.Duration) - return ret0 + ret1, _ := ret[1].(error) + return ret0, ret1 } // UnbondingTime indicates an expected call of UnbondingTime. @@ -382,9 +402,11 @@ func (mr *MockStakingKeeperMockRecorder) UnbondingTime(ctx interface{}) *gomock. } // Unjail mocks base method. -func (m *MockStakingKeeper) Unjail(ctx types0.Context, addr types0.ConsAddress) { +func (m *MockStakingKeeper) Unjail(ctx context.Context, addr types1.ConsAddress) error { m.ctrl.T.Helper() - m.ctrl.Call(m, "Unjail", ctx, addr) + ret := m.ctrl.Call(m, "Unjail", ctx, addr) + ret0, _ := ret[0].(error) + return ret0 } // Unjail indicates an expected call of Unjail. @@ -394,11 +416,12 @@ func (mr *MockStakingKeeperMockRecorder) Unjail(ctx, addr interface{}) *gomock.C } // Validator mocks base method. -func (m *MockStakingKeeper) Validator(ctx types0.Context, addr types0.ValAddress) types4.ValidatorI { +func (m *MockStakingKeeper) Validator(ctx context.Context, addr types1.ValAddress) (types3.ValidatorI, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Validator", ctx, addr) - ret0, _ := ret[0].(types4.ValidatorI) - return ret0 + ret0, _ := ret[0].(types3.ValidatorI) + ret1, _ := ret[1].(error) + return ret0, ret1 } // Validator indicates an expected call of Validator. @@ -408,11 +431,12 @@ func (mr *MockStakingKeeperMockRecorder) Validator(ctx, addr interface{}) *gomoc } // ValidatorByConsAddr mocks base method. -func (m *MockStakingKeeper) ValidatorByConsAddr(ctx types0.Context, consAddr types0.ConsAddress) types4.ValidatorI { +func (m *MockStakingKeeper) ValidatorByConsAddr(ctx context.Context, consAddr types1.ConsAddress) (types3.ValidatorI, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ValidatorByConsAddr", ctx, consAddr) - ret0, _ := ret[0].(types4.ValidatorI) - return ret0 + ret0, _ := ret[0].(types3.ValidatorI) + ret1, _ := ret[1].(error) + return ret0, ret1 } // ValidatorByConsAddr indicates an expected call of ValidatorByConsAddr. @@ -445,11 +469,12 @@ func (m *MockSlashingKeeper) EXPECT() *MockSlashingKeeperMockRecorder { } // DowntimeJailDuration mocks base method. -func (m *MockSlashingKeeper) DowntimeJailDuration(arg0 types0.Context) time.Duration { +func (m *MockSlashingKeeper) DowntimeJailDuration(arg0 context.Context) (time.Duration, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DowntimeJailDuration", arg0) ret0, _ := ret[0].(time.Duration) - return ret0 + ret1, _ := ret[1].(error) + return ret0, ret1 } // DowntimeJailDuration indicates an expected call of DowntimeJailDuration. @@ -459,34 +484,22 @@ func (mr *MockSlashingKeeperMockRecorder) DowntimeJailDuration(arg0 interface{}) } // GetValidatorSigningInfo mocks base method. -func (m *MockSlashingKeeper) GetValidatorSigningInfo(ctx types0.Context, address types0.ConsAddress) (types3.ValidatorSigningInfo, bool) { +func (m *MockSlashingKeeper) GetValidatorSigningInfo(arg0 context.Context, arg1 types1.ConsAddress) (types2.ValidatorSigningInfo, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetValidatorSigningInfo", ctx, address) - ret0, _ := ret[0].(types3.ValidatorSigningInfo) - ret1, _ := ret[1].(bool) + ret := m.ctrl.Call(m, "GetValidatorSigningInfo", arg0, arg1) + ret0, _ := ret[0].(types2.ValidatorSigningInfo) + ret1, _ := ret[1].(error) return ret0, ret1 } // GetValidatorSigningInfo indicates an expected call of GetValidatorSigningInfo. -func (mr *MockSlashingKeeperMockRecorder) GetValidatorSigningInfo(ctx, address interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorSigningInfo", reflect.TypeOf((*MockSlashingKeeper)(nil).GetValidatorSigningInfo), ctx, address) -} - -// SetValidatorSigningInfo mocks base method. -func (m *MockSlashingKeeper) SetValidatorSigningInfo(ctx types0.Context, address types0.ConsAddress, info types3.ValidatorSigningInfo) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetValidatorSigningInfo", ctx, address, info) -} - -// SetValidatorSigningInfo indicates an expected call of SetValidatorSigningInfo. -func (mr *MockSlashingKeeperMockRecorder) SetValidatorSigningInfo(ctx, address interface{}, info interface{}) *gomock.Call { +func (mr *MockSlashingKeeperMockRecorder) GetValidatorSigningInfo(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetValidatorSigningInfo", reflect.TypeOf((*MockSlashingKeeper)(nil).SetValidatorSigningInfo), ctx, address, info) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorSigningInfo", reflect.TypeOf((*MockSlashingKeeper)(nil).GetValidatorSigningInfo), arg0, arg1) } // IsTombstoned mocks base method. -func (m *MockSlashingKeeper) IsTombstoned(arg0 types0.Context, arg1 types0.ConsAddress) bool { +func (m *MockSlashingKeeper) IsTombstoned(arg0 context.Context, arg1 types1.ConsAddress) bool { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IsTombstoned", arg0, arg1) ret0, _ := ret[0].(bool) @@ -500,9 +513,11 @@ func (mr *MockSlashingKeeperMockRecorder) IsTombstoned(arg0, arg1 interface{}) * } // JailUntil mocks base method. -func (m *MockSlashingKeeper) JailUntil(arg0 types0.Context, arg1 types0.ConsAddress, arg2 time.Time) { +func (m *MockSlashingKeeper) JailUntil(arg0 context.Context, arg1 types1.ConsAddress, arg2 time.Time) error { m.ctrl.T.Helper() - m.ctrl.Call(m, "JailUntil", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "JailUntil", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 } // JailUntil indicates an expected call of JailUntil. @@ -511,26 +526,42 @@ func (mr *MockSlashingKeeperMockRecorder) JailUntil(arg0, arg1, arg2 interface{} return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "JailUntil", reflect.TypeOf((*MockSlashingKeeper)(nil).JailUntil), arg0, arg1, arg2) } -// SlashFractionDoubleSign mocks base method. -func (m *MockSlashingKeeper) SlashFractionDoubleSign(ctx types0.Context) types0.Dec { +// SetValidatorSigningInfo mocks base method. +func (m *MockSlashingKeeper) SetValidatorSigningInfo(arg0 context.Context, arg1 types1.ConsAddress, arg2 types2.ValidatorSigningInfo) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SlashFractionDoubleSign", ctx) - ret0, _ := ret[0].(types0.Dec) + ret := m.ctrl.Call(m, "SetValidatorSigningInfo", arg0, arg1, arg2) + ret0, _ := ret[0].(error) return ret0 } +// SetValidatorSigningInfo indicates an expected call of SetValidatorSigningInfo. +func (mr *MockSlashingKeeperMockRecorder) SetValidatorSigningInfo(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetValidatorSigningInfo", reflect.TypeOf((*MockSlashingKeeper)(nil).SetValidatorSigningInfo), arg0, arg1, arg2) +} + +// SlashFractionDoubleSign mocks base method. +func (m *MockSlashingKeeper) SlashFractionDoubleSign(arg0 context.Context) (math.LegacyDec, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SlashFractionDoubleSign", arg0) + ret0, _ := ret[0].(math.LegacyDec) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + // SlashFractionDoubleSign indicates an expected call of SlashFractionDoubleSign. -func (mr *MockSlashingKeeperMockRecorder) SlashFractionDoubleSign(ctx interface{}) *gomock.Call { +func (mr *MockSlashingKeeperMockRecorder) SlashFractionDoubleSign(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SlashFractionDoubleSign", reflect.TypeOf((*MockSlashingKeeper)(nil).SlashFractionDoubleSign), ctx) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SlashFractionDoubleSign", reflect.TypeOf((*MockSlashingKeeper)(nil).SlashFractionDoubleSign), arg0) } // SlashFractionDowntime mocks base method. -func (m *MockSlashingKeeper) SlashFractionDowntime(arg0 types0.Context) types0.Dec { +func (m *MockSlashingKeeper) SlashFractionDowntime(arg0 context.Context) (math.LegacyDec, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SlashFractionDowntime", arg0) - ret0, _ := ret[0].(types0.Dec) - return ret0 + ret0, _ := ret[0].(math.LegacyDec) + ret1, _ := ret[1].(error) + return ret0, ret1 } // SlashFractionDowntime indicates an expected call of SlashFractionDowntime. @@ -540,9 +571,11 @@ func (mr *MockSlashingKeeperMockRecorder) SlashFractionDowntime(arg0 interface{} } // Tombstone mocks base method. -func (m *MockSlashingKeeper) Tombstone(arg0 types0.Context, arg1 types0.ConsAddress) { +func (m *MockSlashingKeeper) Tombstone(arg0 context.Context, arg1 types1.ConsAddress) error { m.ctrl.T.Helper() - m.ctrl.Call(m, "Tombstone", arg0, arg1) + ret := m.ctrl.Call(m, "Tombstone", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 } // Tombstone indicates an expected call of Tombstone. @@ -575,7 +608,7 @@ func (m *MockChannelKeeper) EXPECT() *MockChannelKeeperMockRecorder { } // ChanCloseInit mocks base method. -func (m *MockChannelKeeper) ChanCloseInit(ctx types0.Context, portID, channelID string, chanCap *types2.Capability) error { +func (m *MockChannelKeeper) ChanCloseInit(ctx types1.Context, portID, channelID string, chanCap *types4.Capability) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChanCloseInit", ctx, portID, channelID, chanCap) ret0, _ := ret[0].(error) @@ -589,7 +622,7 @@ func (mr *MockChannelKeeperMockRecorder) ChanCloseInit(ctx, portID, channelID, c } // GetChannel mocks base method. -func (m *MockChannelKeeper) GetChannel(ctx types0.Context, srcPort, srcChan string) (types8.Channel, bool) { +func (m *MockChannelKeeper) GetChannel(ctx types1.Context, srcPort, srcChan string) (types8.Channel, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetChannel", ctx, srcPort, srcChan) ret0, _ := ret[0].(types8.Channel) @@ -604,7 +637,7 @@ func (mr *MockChannelKeeperMockRecorder) GetChannel(ctx, srcPort, srcChan interf } // GetChannelConnection mocks base method. -func (m *MockChannelKeeper) GetChannelConnection(ctx types0.Context, portID, channelID string) (string, exported.ConnectionI, error) { +func (m *MockChannelKeeper) GetChannelConnection(ctx types1.Context, portID, channelID string) (string, exported.ConnectionI, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetChannelConnection", ctx, portID, channelID) ret0, _ := ret[0].(string) @@ -620,7 +653,7 @@ func (mr *MockChannelKeeperMockRecorder) GetChannelConnection(ctx, portID, chann } // GetNextSequenceSend mocks base method. -func (m *MockChannelKeeper) GetNextSequenceSend(ctx types0.Context, portID, channelID string) (uint64, bool) { +func (m *MockChannelKeeper) GetNextSequenceSend(ctx types1.Context, portID, channelID string) (uint64, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetNextSequenceSend", ctx, portID, channelID) ret0, _ := ret[0].(uint64) @@ -635,7 +668,7 @@ func (mr *MockChannelKeeperMockRecorder) GetNextSequenceSend(ctx, portID, channe } // SendPacket mocks base method. -func (m *MockChannelKeeper) SendPacket(ctx types0.Context, chanCap *types2.Capability, sourcePort, sourceChannel string, timeoutHeight types6.Height, timeoutTimestamp uint64, data []byte) (uint64, error) { +func (m *MockChannelKeeper) SendPacket(ctx types1.Context, chanCap *types4.Capability, sourcePort, sourceChannel string, timeoutHeight types6.Height, timeoutTimestamp uint64, data []byte) (uint64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SendPacket", ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) ret0, _ := ret[0].(uint64) @@ -650,7 +683,7 @@ func (mr *MockChannelKeeperMockRecorder) SendPacket(ctx, chanCap, sourcePort, so } // WriteAcknowledgement mocks base method. -func (m *MockChannelKeeper) WriteAcknowledgement(ctx types0.Context, chanCap *types2.Capability, packet exported.PacketI, acknowledgement exported.Acknowledgement) error { +func (m *MockChannelKeeper) WriteAcknowledgement(ctx types1.Context, chanCap *types4.Capability, packet exported.PacketI, acknowledgement exported.Acknowledgement) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WriteAcknowledgement", ctx, chanCap, packet, acknowledgement) ret0, _ := ret[0].(error) @@ -687,10 +720,10 @@ func (m *MockPortKeeper) EXPECT() *MockPortKeeperMockRecorder { } // BindPort mocks base method. -func (m *MockPortKeeper) BindPort(ctx types0.Context, portID string) *types2.Capability { +func (m *MockPortKeeper) BindPort(ctx types1.Context, portID string) *types4.Capability { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BindPort", ctx, portID) - ret0, _ := ret[0].(*types2.Capability) + ret0, _ := ret[0].(*types4.Capability) return ret0 } @@ -724,7 +757,7 @@ func (m *MockConnectionKeeper) EXPECT() *MockConnectionKeeperMockRecorder { } // GetConnection mocks base method. -func (m *MockConnectionKeeper) GetConnection(ctx types0.Context, connectionID string) (types7.ConnectionEnd, bool) { +func (m *MockConnectionKeeper) GetConnection(ctx types1.Context, connectionID string) (types7.ConnectionEnd, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetConnection", ctx, connectionID) ret0, _ := ret[0].(types7.ConnectionEnd) @@ -762,10 +795,10 @@ func (m *MockClientKeeper) EXPECT() *MockClientKeeperMockRecorder { } // ClientStore mocks base method. -func (m *MockClientKeeper) ClientStore(ctx types0.Context, clientID string) types0.KVStore { +func (m *MockClientKeeper) ClientStore(ctx types1.Context, clientID string) types.KVStore { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClientStore", ctx, clientID) - ret0, _ := ret[0].(types0.KVStore) + ret0, _ := ret[0].(types.KVStore) return ret0 } @@ -776,7 +809,7 @@ func (mr *MockClientKeeperMockRecorder) ClientStore(ctx, clientID interface{}) * } // CreateClient mocks base method. -func (m *MockClientKeeper) CreateClient(ctx types0.Context, clientState exported.ClientState, consensusState exported.ConsensusState) (string, error) { +func (m *MockClientKeeper) CreateClient(ctx types1.Context, clientState exported.ClientState, consensusState exported.ConsensusState) (string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateClient", ctx, clientState, consensusState) ret0, _ := ret[0].(string) @@ -791,7 +824,7 @@ func (mr *MockClientKeeperMockRecorder) CreateClient(ctx, clientState, consensus } // GetClientConsensusState mocks base method. -func (m *MockClientKeeper) GetClientConsensusState(ctx types0.Context, clientID string, height exported.Height) (exported.ConsensusState, bool) { +func (m *MockClientKeeper) GetClientConsensusState(ctx types1.Context, clientID string, height exported.Height) (exported.ConsensusState, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetClientConsensusState", ctx, clientID, height) ret0, _ := ret[0].(exported.ConsensusState) @@ -806,7 +839,7 @@ func (mr *MockClientKeeperMockRecorder) GetClientConsensusState(ctx, clientID, h } // GetClientState mocks base method. -func (m *MockClientKeeper) GetClientState(ctx types0.Context, clientID string) (exported.ClientState, bool) { +func (m *MockClientKeeper) GetClientState(ctx types1.Context, clientID string) (exported.ClientState, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetClientState", ctx, clientID) ret0, _ := ret[0].(exported.ClientState) @@ -821,7 +854,7 @@ func (mr *MockClientKeeperMockRecorder) GetClientState(ctx, clientID interface{} } // GetLatestClientConsensusState mocks base method. -func (m *MockClientKeeper) GetLatestClientConsensusState(ctx types0.Context, clientID string) (exported.ConsensusState, bool) { +func (m *MockClientKeeper) GetLatestClientConsensusState(ctx types1.Context, clientID string) (exported.ConsensusState, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetLatestClientConsensusState", ctx, clientID) ret0, _ := ret[0].(exported.ConsensusState) @@ -836,7 +869,7 @@ func (mr *MockClientKeeperMockRecorder) GetLatestClientConsensusState(ctx, clien } // GetSelfConsensusState mocks base method. -func (m *MockClientKeeper) GetSelfConsensusState(ctx types0.Context, height exported.Height) (exported.ConsensusState, error) { +func (m *MockClientKeeper) GetSelfConsensusState(ctx types1.Context, height exported.Height) (exported.ConsensusState, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSelfConsensusState", ctx, height) ret0, _ := ret[0].(exported.ConsensusState) @@ -851,7 +884,7 @@ func (mr *MockClientKeeperMockRecorder) GetSelfConsensusState(ctx, height interf } // SetClientState mocks base method. -func (m *MockClientKeeper) SetClientState(ctx types0.Context, clientID string, clientState exported.ClientState) { +func (m *MockClientKeeper) SetClientState(ctx types1.Context, clientID string, clientState exported.ClientState) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetClientState", ctx, clientID, clientState) } @@ -886,7 +919,7 @@ func (m *MockDistributionKeeper) EXPECT() *MockDistributionKeeperMockRecorder { } // FundCommunityPool mocks base method. -func (m *MockDistributionKeeper) FundCommunityPool(ctx types0.Context, amount types0.Coins, sender types0.AccAddress) error { +func (m *MockDistributionKeeper) FundCommunityPool(ctx context.Context, amount types1.Coins, sender types1.AccAddress) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "FundCommunityPool", ctx, amount, sender) ret0, _ := ret[0].(error) @@ -923,7 +956,7 @@ func (m *MockConsumerHooks) EXPECT() *MockConsumerHooksMockRecorder { } // AfterValidatorBonded mocks base method. -func (m *MockConsumerHooks) AfterValidatorBonded(ctx types0.Context, consAddr types0.ConsAddress, valAddresses types0.ValAddress) error { +func (m *MockConsumerHooks) AfterValidatorBonded(ctx context.Context, consAddr types1.ConsAddress, valAddresses types1.ValAddress) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AfterValidatorBonded", ctx, consAddr, valAddresses) ret0, _ := ret[0].(error) @@ -960,10 +993,10 @@ func (m *MockBankKeeper) EXPECT() *MockBankKeeperMockRecorder { } // GetAllBalances mocks base method. -func (m *MockBankKeeper) GetAllBalances(ctx types0.Context, addr types0.AccAddress) types0.Coins { +func (m *MockBankKeeper) GetAllBalances(ctx context.Context, addr types1.AccAddress) types1.Coins { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAllBalances", ctx, addr) - ret0, _ := ret[0].(types0.Coins) + ret0, _ := ret[0].(types1.Coins) return ret0 } @@ -974,10 +1007,10 @@ func (mr *MockBankKeeperMockRecorder) GetAllBalances(ctx, addr interface{}) *gom } // GetBalance mocks base method. -func (m *MockBankKeeper) GetBalance(ctx types0.Context, addr types0.AccAddress, denom string) types0.Coin { +func (m *MockBankKeeper) GetBalance(ctx context.Context, addr types1.AccAddress, denom string) types1.Coin { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetBalance", ctx, addr, denom) - ret0, _ := ret[0].(types0.Coin) + ret0, _ := ret[0].(types1.Coin) return ret0 } @@ -988,7 +1021,7 @@ func (mr *MockBankKeeperMockRecorder) GetBalance(ctx, addr, denom interface{}) * } // SendCoinsFromModuleToModule mocks base method. -func (m *MockBankKeeper) SendCoinsFromModuleToModule(ctx types0.Context, senderModule, recipientModule string, amt types0.Coins) error { +func (m *MockBankKeeper) SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt types1.Coins) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SendCoinsFromModuleToModule", ctx, senderModule, recipientModule, amt) ret0, _ := ret[0].(error) @@ -1025,7 +1058,7 @@ func (m *MockAccountKeeper) EXPECT() *MockAccountKeeperMockRecorder { } // GetModuleAccount mocks base method. -func (m *MockAccountKeeper) GetModuleAccount(ctx types0.Context, name string) types1.ModuleAccountI { +func (m *MockAccountKeeper) GetModuleAccount(ctx context.Context, name string) types1.ModuleAccountI { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetModuleAccount", ctx, name) ret0, _ := ret[0].(types1.ModuleAccountI) @@ -1138,7 +1171,7 @@ func (m *MockScopedKeeper) EXPECT() *MockScopedKeeperMockRecorder { } // AuthenticateCapability mocks base method. -func (m *MockScopedKeeper) AuthenticateCapability(ctx types0.Context, cap *types2.Capability, name string) bool { +func (m *MockScopedKeeper) AuthenticateCapability(ctx types1.Context, cap *types4.Capability, name string) bool { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AuthenticateCapability", ctx, cap, name) ret0, _ := ret[0].(bool) @@ -1152,7 +1185,7 @@ func (mr *MockScopedKeeperMockRecorder) AuthenticateCapability(ctx, cap, name in } // ClaimCapability mocks base method. -func (m *MockScopedKeeper) ClaimCapability(ctx types0.Context, cap *types2.Capability, name string) error { +func (m *MockScopedKeeper) ClaimCapability(ctx types1.Context, cap *types4.Capability, name string) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ClaimCapability", ctx, cap, name) ret0, _ := ret[0].(error) @@ -1166,10 +1199,10 @@ func (mr *MockScopedKeeperMockRecorder) ClaimCapability(ctx, cap, name interface } // GetCapability mocks base method. -func (m *MockScopedKeeper) GetCapability(ctx types0.Context, name string) (*types2.Capability, bool) { +func (m *MockScopedKeeper) GetCapability(ctx types1.Context, name string) (*types4.Capability, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetCapability", ctx, name) - ret0, _ := ret[0].(*types2.Capability) + ret0, _ := ret[0].(*types4.Capability) ret1, _ := ret[1].(bool) return ret0, ret1 } @@ -1179,41 +1212,3 @@ func (mr *MockScopedKeeperMockRecorder) GetCapability(ctx, name interface{}) *go mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCapability", reflect.TypeOf((*MockScopedKeeper)(nil).GetCapability), ctx, name) } - -// MockGovKeeper is a mock of GovKeeper interface. -type MockGovKeeper struct { - ctrl *gomock.Controller - recorder *MockGovKeeperMockRecorder -} - -// MockGovKeeperMockRecorder is the mock recorder for MockGovKeeper. -type MockGovKeeperMockRecorder struct { - mock *MockGovKeeper -} - -// NewMockGovKeeper creates a new mock instance. -func NewMockGovKeeper(ctrl *gomock.Controller) *MockGovKeeper { - mock := &MockGovKeeper{ctrl: ctrl} - mock.recorder = &MockGovKeeperMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockGovKeeper) EXPECT() *MockGovKeeperMockRecorder { - return m.recorder -} - -// GetProposal mocks base method. -func (m *MockGovKeeper) GetProposal(ctx types0.Context, proposalID uint64) (v1.Proposal, bool) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetProposal", ctx, proposalID) - ret0, _ := ret[0].(v1.Proposal) - ret1, _ := ret[1].(bool) - return ret0, ret1 -} - -// GetProposal indicates an expected call of GetProposal. -func (mr *MockGovKeeperMockRecorder) GetProposal(ctx, proposalID interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProposal", reflect.TypeOf((*MockGovKeeper)(nil).GetProposal), ctx, proposalID) -} diff --git a/testutil/keeper/unit_test_helpers.go b/testutil/keeper/unit_test_helpers.go index dc901712ff..46d593fac4 100644 --- a/testutil/keeper/unit_test_helpers.go +++ b/testutil/keeper/unit_test_helpers.go @@ -6,32 +6,38 @@ import ( "testing" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "cosmossdk.io/store" + "cosmossdk.io/store/metrics" + storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/address" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/store" - storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - tmdb "github.com/cometbft/cometbft-db" + "cosmossdk.io/log" abci "github.com/cometbft/cometbft/abci/types" - "github.com/cometbft/cometbft/libs/log" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" - consumerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - providerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - "github.com/cosmos/interchain-security/v4/x/ccv/types" + govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" + consumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + + "github.com/cosmos/interchain-security/v5/x/ccv/types" + + dbm "github.com/cosmos/cosmos-db" ) // Parameters needed to instantiate an in-memory keeper @@ -45,11 +51,11 @@ type InMemKeeperParams struct { // NewInMemKeeperParams instantiates in-memory keeper params with default values func NewInMemKeeperParams(tb testing.TB) InMemKeeperParams { tb.Helper() - storeKey := sdk.NewKVStoreKey(types.StoreKey) + storeKey := storetypes.NewKVStoreKey(types.StoreKey) memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) - db := tmdb.NewMemDB() - stateStore := store.NewCommitMultiStore(db) + db := dbm.NewMemDB() + stateStore := store.NewCommitMultiStore(db, log.NewNopLogger(), metrics.NewNoOpMetrics()) stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) stateStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil) require.NoError(tb, stateStore.LoadLatestVersion()) @@ -88,7 +94,7 @@ type MockedKeepers struct { *MockIBCTransferKeeper *MockIBCCoreKeeper *MockDistributionKeeper - *MockGovKeeper + // *MockGovKeeper } // NewMockedKeepers instantiates a struct with pointers to properly instantiated mocked keepers. @@ -106,7 +112,6 @@ func NewMockedKeepers(ctrl *gomock.Controller) MockedKeepers { MockIBCTransferKeeper: NewMockIBCTransferKeeper(ctrl), MockIBCCoreKeeper: NewMockIBCCoreKeeper(ctrl), MockDistributionKeeper: NewMockDistributionKeeper(ctrl), - MockGovKeeper: NewMockGovKeeper(ctrl), } } @@ -126,7 +131,11 @@ func NewInMemProviderKeeper(params InMemKeeperParams, mocks MockedKeepers) provi mocks.MockAccountKeeper, mocks.MockDistributionKeeper, mocks.MockBankKeeper, - mocks.MockGovKeeper, + // mocks.MockGovKeeper, + govkeeper.Keeper{}, // HACK: to make parts of the test work + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + address.NewBech32Codec("cosmosvaloper"), + address.NewBech32Codec("cosmosvalcons"), authtypes.FeeCollectorName, ) } @@ -148,6 +157,9 @@ func NewInMemConsumerKeeper(params InMemKeeperParams, mocks MockedKeepers) consu mocks.MockIBCTransferKeeper, mocks.MockIBCCoreKeeper, authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + address.NewBech32Codec("cosmosvaloper"), + address.NewBech32Codec("cosmosvalcons"), ) } diff --git a/testutil/simibc/chain_util.go b/testutil/simibc/chain_util.go index ffcc318ac0..3a304d6621 100644 --- a/testutil/simibc/chain_util.go +++ b/testutil/simibc/chain_util.go @@ -3,9 +3,10 @@ package simibc import ( "time" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctesting "github.com/cosmos/ibc-go/v7/testing" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v8/testing" + "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" @@ -13,12 +14,32 @@ import ( tmproto "github.com/cometbft/cometbft/proto/tendermint/types" ) -// BeginBlock updates the current header and calls the app.BeginBlock method. -// The new block height is the previous block height + 1. -// The new block time is the previous block time + dt. +// FinalizeBlock calls app.FinalizeBlock and app.Commit. +// It sets the next block time to currentBlockTime + dt. +// This function returns the TMHeader of the block that was just ended, // // NOTE: this method may be used independently of the rest of simibc. -func BeginBlock(c *ibctesting.TestChain, dt time.Duration) { +func FinalizeBlock(c *ibctesting.TestChain, dt time.Duration) (*ibctmtypes.Header, []channeltypes.Packet) { + res, err := c.App.FinalizeBlock(&abci.RequestFinalizeBlock{ + Height: c.CurrentHeader.Height, + Time: c.CurrentHeader.GetTime(), + NextValidatorsHash: c.NextVals.Hash(), + }) + require.NoError(c.TB, err) + + _, err = c.App.Commit() + require.NoError(c.TB, err) + + // set the last header to the current header + // use nil trusted fields + c.LastHeader = c.CurrentTMClientHeader() + + // val set changes returned from previous block get applied to the next validators + // of this block. See tendermint spec for details. + c.Vals = c.NextVals + c.NextVals = ibctesting.ApplyValSetChanges(c, c.Vals, res.ValidatorUpdates) + + // increment the current header c.CurrentHeader = tmproto.Header{ ChainID: c.ChainID, Height: c.App.LastBlockHeight() + 1, @@ -26,46 +47,16 @@ func BeginBlock(c *ibctesting.TestChain, dt time.Duration) { Time: c.CurrentHeader.Time.Add(dt), ValidatorsHash: c.Vals.Hash(), NextValidatorsHash: c.NextVals.Hash(), + ProposerAddress: c.CurrentHeader.ProposerAddress, } - _ = c.App.BeginBlock(abci.RequestBeginBlock{Header: c.CurrentHeader}) -} - -// EndBlock calls app.EndBlock and executes preCommitCallback BEFORE calling app.Commit -// The callback is useful for testing purposes to execute arbitrary code before the -// chain sdk context is cleared in .Commit(). -// For example, app.EndBlock may lead to a new state, which you would like to query -// to check that it is correct. However, the sdk context is cleared after .Commit(), -// so you can query the state inside the callback. -// -// NOTE: this method may be used independently of the rest of simibc. -func EndBlock( - c *ibctesting.TestChain, - preCommitCallback func(), -) (*ibctmtypes.Header, []channeltypes.Packet) { - ebRes := c.App.EndBlock(abci.RequestEndBlock{Height: c.CurrentHeader.Height}) - - /* - It is useful to call arbitrary code after ending the block but before - committing the block because the sdk.Context is cleared after committing. - */ - - c.App.Commit() - - c.Vals = c.NextVals - - c.NextVals = ibctesting.ApplyValSetChanges(c.T, c.Vals, ebRes.ValidatorUpdates) - - c.LastHeader = c.CurrentTMClientHeader() - - sdkEvts := ABCIToSDKEvents(ebRes.Events) - packets := ParsePacketsFromEvents(sdkEvts) - + // handle packets + packets := ParsePacketsFromEvents(res.Events) return c.LastHeader, packets } // ParsePacketsFromEvents returns all packets found in events. -func ParsePacketsFromEvents(events []sdk.Event) (packets []channeltypes.Packet) { +func ParsePacketsFromEvents(events []abci.Event) (packets []channeltypes.Packet) { for i, ev := range events { if ev.Type == channeltypes.EventTypeSendPacket { packet, err := ibctesting.ParsePacketFromEvents(events[i:]) diff --git a/testutil/simibc/ordered_outbox.go b/testutil/simibc/ordered_outbox.go index fdeb449962..9b0f008281 100644 --- a/testutil/simibc/ordered_outbox.go +++ b/testutil/simibc/ordered_outbox.go @@ -1,6 +1,6 @@ package simibc -import channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" +import channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" // The number of blocks to wait before a packet or ack is available for delivery // after it has been committed on the chain. diff --git a/testutil/simibc/relay_util.go b/testutil/simibc/relay_util.go index e113c02fef..fcddad74b0 100644 --- a/testutil/simibc/relay_util.go +++ b/testutil/simibc/relay_util.go @@ -1,12 +1,12 @@ package simibc import ( - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v7/modules/core/24-host" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctesting "github.com/cosmos/ibc-go/v7/testing" - simapp "github.com/cosmos/ibc-go/v7/testing/simapp" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v8/testing" + simapp "github.com/cosmos/ibc-go/v8/testing/simapp" errorsmod "cosmossdk.io/errors" @@ -37,16 +37,18 @@ func UpdateReceiverClient(sender, receiver *ibctesting.Endpoint, header *ibctmty return err } - _, _, err = simapp.SignAndDeliver( - receiver.Chain.T, + _, err = simapp.SignAndDeliver( + receiver.Chain.TB, receiver.Chain.TxConfig, receiver.Chain.App.GetBaseApp(), - receiver.Chain.GetContext().BlockHeader(), []sdk.Msg{msg}, receiver.Chain.ChainID, []uint64{receiver.Chain.SenderAccount.GetAccountNumber()}, []uint64{receiver.Chain.SenderAccount.GetSequence()}, - true, !expectExpiration, receiver.Chain.SenderPrivKey, + !expectExpiration, + receiver.Chain.GetContext().BlockHeader().Time, + receiver.Chain.GetContext().BlockHeader().NextValidatorsHash, + receiver.Chain.SenderPrivKey, ) setSequenceErr := receiver.Chain.SenderAccount.SetSequence(receiver.Chain.SenderAccount.GetSequence() + 1) @@ -73,17 +75,20 @@ func TryRecvPacket(sender, receiver *ibctesting.Endpoint, packet channeltypes.Pa RPmsg := channeltypes.NewMsgRecvPacket(packet, proof, proofHeight, receiver.Chain.SenderAccount.GetAddress().String()) - _, resWithAck, err := simapp.SignAndDeliver( - receiver.Chain.T, + resWithAck, err := simapp.SignAndDeliver( + receiver.Chain.TB, receiver.Chain.TxConfig, receiver.Chain.App.GetBaseApp(), - receiver.Chain.GetContext().BlockHeader(), []sdk.Msg{RPmsg}, receiver.Chain.ChainID, []uint64{receiver.Chain.SenderAccount.GetAccountNumber()}, []uint64{receiver.Chain.SenderAccount.GetSequence()}, - true, !expectError, receiver.Chain.SenderPrivKey, + !expectError, + receiver.Chain.GetContext().BlockHeader().Time, + receiver.Chain.GetContext().BlockHeader().NextValidatorsHash, + receiver.Chain.SenderPrivKey, ) + // need to set the sequence even if there was an error in delivery setSequenceErr := receiver.Chain.SenderAccount.SetSequence(receiver.Chain.SenderAccount.GetSequence() + 1) if err != nil { @@ -116,16 +121,18 @@ func TryRecvAck(sender, receiver *ibctesting.Endpoint, packet channeltypes.Packe ackMsg := channeltypes.NewMsgAcknowledgement(p, ack, proof, proofHeight, receiver.Chain.SenderAccount.GetAddress().String()) - _, _, err = simapp.SignAndDeliver( - receiver.Chain.T, + _, err = simapp.SignAndDeliver( + receiver.Chain.TB, receiver.Chain.TxConfig, receiver.Chain.App.GetBaseApp(), - receiver.Chain.GetContext().BlockHeader(), []sdk.Msg{ackMsg}, receiver.Chain.ChainID, []uint64{receiver.Chain.SenderAccount.GetAccountNumber()}, []uint64{receiver.Chain.SenderAccount.GetSequence()}, - true, true, receiver.Chain.SenderPrivKey, + true, + receiver.Chain.GetContext().BlockHeader().Time, + receiver.Chain.GetContext().BlockHeader().NextValidatorsHash, + receiver.Chain.SenderPrivKey, ) setSequenceErr := receiver.Chain.SenderAccount.SetSequence(receiver.Chain.SenderAccount.GetSequence() + 1) diff --git a/testutil/simibc/relayed_path.go b/testutil/simibc/relayed_path.go index 4967c02f37..ca64987bcf 100644 --- a/testutil/simibc/relayed_path.go +++ b/testutil/simibc/relayed_path.go @@ -3,9 +3,9 @@ package simibc import ( "testing" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - ibctesting "github.com/cosmos/ibc-go/v7/testing" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + ibctesting "github.com/cosmos/ibc-go/v8/testing" ) // RelayedPath is a wrapper around ibctesting.Path gives fine-grained diff --git a/x/ccv/consumer/client/cli/query.go b/x/ccv/consumer/client/cli/query.go index 806b91d2cf..3630b3ed3f 100644 --- a/x/ccv/consumer/client/cli/query.go +++ b/x/ccv/consumer/client/cli/query.go @@ -6,7 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" ) // NewQueryCmd returns a root CLI command handler for all x/ccv/provider query commands. diff --git a/x/ccv/consumer/ibc_module.go b/x/ccv/consumer/ibc_module.go index f0e2a3e6c6..d3f5e860e6 100644 --- a/x/ccv/consumer/ibc_module.go +++ b/x/ccv/consumer/ibc_module.go @@ -5,21 +5,21 @@ import ( "strconv" "strings" - transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" - host "github.com/cosmos/ibc-go/v7/modules/core/24-host" - ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" + ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // OnChanOpenInit implements the IBCModule interface diff --git a/x/ccv/consumer/ibc_module_test.go b/x/ccv/consumer/ibc_module_test.go index 51fd910902..029a4accd5 100644 --- a/x/ccv/consumer/ibc_module_test.go +++ b/x/ccv/consumer/ibc_module_test.go @@ -3,20 +3,20 @@ package consumer_test import ( "testing" - transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + conntypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer" - consumerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer" + consumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // TestOnChanOpenInit validates the consumer's OnChanOpenInit implementation against the spec. diff --git a/x/ccv/consumer/keeper/changeover.go b/x/ccv/consumer/keeper/changeover.go index 74276d1253..7f7ba4ad5b 100644 --- a/x/ccv/consumer/keeper/changeover.go +++ b/x/ccv/consumer/keeper/changeover.go @@ -38,7 +38,12 @@ func (k Keeper) ChangeoverToConsumer(ctx sdk.Context) (initialValUpdates []abci. for _, val := range initialValUpdates { initialUpdatesFlag[val.PubKey.String()] = true } - for _, val := range k.GetLastStandaloneValidators(ctx) { + + standaloneValset, err := k.GetLastStandaloneValidators(ctx) + if err != nil { + panic(err) + } + for _, val := range standaloneValset { zeroPowerUpdate := val.ABCIValidatorUpdateZero() if !initialUpdatesFlag[zeroPowerUpdate.PubKey.String()] { initialValUpdates = append(initialValUpdates, zeroPowerUpdate) diff --git a/x/ccv/consumer/keeper/changeover_test.go b/x/ccv/consumer/keeper/changeover_test.go index c431f43477..c2d7cda190 100644 --- a/x/ccv/consumer/keeper/changeover_test.go +++ b/x/ccv/consumer/keeper/changeover_test.go @@ -11,8 +11,8 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/cosmos/interchain-security/v4/testutil/crypto" - uthelpers "github.com/cosmos/interchain-security/v4/testutil/keeper" + "github.com/cosmos/interchain-security/v5/testutil/crypto" + uthelpers "github.com/cosmos/interchain-security/v5/testutil/keeper" ) func TestChangeoverToConsumer(t *testing.T) { @@ -102,7 +102,7 @@ func TestChangeoverToConsumer(t *testing.T) { // Setup mocked return value for stakingKeeper.GetLastValidators() gomock.InOrder( - mocks.MockStakingKeeper.EXPECT().GetLastValidators(ctx).Return(tc.lastSovVals), + mocks.MockStakingKeeper.EXPECT().GetLastValidators(ctx).Return(tc.lastSovVals, nil), ) // Add ref to standalone staking keeper diff --git a/x/ccv/consumer/keeper/distribution.go b/x/ccv/consumer/keeper/distribution.go index 1b98638498..5c9bbe4a24 100644 --- a/x/ccv/consumer/keeper/distribution.go +++ b/x/ccv/consumer/keeper/distribution.go @@ -4,16 +4,17 @@ import ( "fmt" "strconv" - transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" errorsmod "cosmossdk.io/errors" + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // EndBlockRD executes EndBlock logic for the Reward Distribution sub-protocol. @@ -56,7 +57,7 @@ func (k Keeper) DistributeRewardsInternally(ctx sdk.Context) { fpTokens := k.bankKeeper.GetAllBalances(ctx, consumerFeePoolAddr) // split the fee pool, send the consumer's fraction to the consumer redistribution address - frac, err := sdk.NewDecFromStr(k.GetConsumerRedistributionFrac(ctx)) + frac, err := math.LegacyNewDecFromStr(k.GetConsumerRedistributionFrac(ctx)) if err != nil { // ConsumerRedistributionFrac was already validated when set as a param panic(fmt.Errorf("ConsumerRedistributionFrac is invalid: %w", err)) @@ -253,7 +254,7 @@ func (k Keeper) GetEstimatedNextFeeDistribution(ctx sdk.Context) types.NextFeeDi total := k.bankKeeper.GetAllBalances(ctx, consumerFeePoolAddr) fracParam := k.GetConsumerRedistributionFrac(ctx) - frac, err := sdk.NewDecFromStr(fracParam) + frac, err := math.LegacyNewDecFromStr(fracParam) if err != nil { // ConsumerRedistributionFrac was already validated when set as a param panic(fmt.Errorf("ConsumerRedistributionFrac is invalid: %w", err)) diff --git a/x/ccv/consumer/keeper/distribution_test.go b/x/ccv/consumer/keeper/distribution_test.go index 189842a90e..5713361918 100644 --- a/x/ccv/consumer/keeper/distribution_test.go +++ b/x/ccv/consumer/keeper/distribution_test.go @@ -4,15 +4,16 @@ import ( "strings" "testing" + "cosmossdk.io/math" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" authTypes "github.com/cosmos/cosmos-sdk/x/auth/types" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // TestGetEstimatedNextFeeDistribution tests next fee distribution parameters. @@ -30,11 +31,11 @@ func TestGetEstimatedNextFeeDistribution(t *testing.T) { // Setup mock account balance fracParam := consumerKeeper.GetConsumerRedistributionFrac(ctx) - fracDec, err := sdk.NewDecFromStr(fracParam) + fracDec, err := math.LegacyNewDecFromStr(fracParam) require.NoError(t, err) feeAmount := sdk.Coin{ Denom: "MOCK", - Amount: sdk.NewInt(100), + Amount: math.NewInt(100), } feeAmountCoins := sdk.Coins([]sdk.Coin{feeAmount}) feeAmountDec := sdk.NewDecCoinsFromCoins(feeAmountCoins...) diff --git a/x/ccv/consumer/keeper/genesis.go b/x/ccv/consumer/keeper/genesis.go index 1b9afb2a4e..bdb8e35418 100644 --- a/x/ccv/consumer/keeper/genesis.go +++ b/x/ccv/consumer/keeper/genesis.go @@ -7,8 +7,8 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // InitGenesis initializes the CCV consumer state and binds to PortID. diff --git a/x/ccv/consumer/keeper/genesis_test.go b/x/ccv/consumer/keeper/genesis_test.go index b9fc1b6f3a..dc555554fb 100644 --- a/x/ccv/consumer/keeper/genesis_test.go +++ b/x/ccv/consumer/keeper/genesis_test.go @@ -4,9 +4,9 @@ import ( "testing" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" @@ -18,11 +18,11 @@ import ( abci "github.com/cometbft/cometbft/abci/types" tmtypes "github.com/cometbft/cometbft/types" - "github.com/cosmos/interchain-security/v4/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - consumerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + consumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // TestInitGenesis tests that a consumer chain is correctly initialised from genesis. diff --git a/x/ccv/consumer/keeper/grpc_query.go b/x/ccv/consumer/keeper/grpc_query.go index 5ac5116a28..2f1543071b 100644 --- a/x/ccv/consumer/keeper/grpc_query.go +++ b/x/ccv/consumer/keeper/grpc_query.go @@ -8,8 +8,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) var _ types.QueryServer = Keeper{} //nolint:golint diff --git a/x/ccv/consumer/keeper/hooks.go b/x/ccv/consumer/keeper/hooks.go index c730bf266c..5e90129ed7 100644 --- a/x/ccv/consumer/keeper/hooks.go +++ b/x/ccv/consumer/keeper/hooks.go @@ -1,9 +1,11 @@ package keeper import ( + "context" + sdk "github.com/cosmos/cosmos-sdk/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) var _ ccv.ConsumerHooks = Keeper{} @@ -18,7 +20,7 @@ func (k Keeper) Hooks() Hooks { return Hooks{k} } -func (k Keeper) AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { +func (k Keeper) AfterValidatorBonded(ctx context.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { if k.hooks != nil { err := k.hooks.AfterValidatorBonded(ctx, consAddr, nil) return err diff --git a/x/ccv/consumer/keeper/keeper.go b/x/ccv/consumer/keeper/keeper.go index b8751344b8..1f1756a82a 100644 --- a/x/ccv/consumer/keeper/keeper.go +++ b/x/ccv/consumer/keeper/keeper.go @@ -6,32 +6,38 @@ import ( "reflect" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + addresscodec "cosmossdk.io/core/address" + "cosmossdk.io/core/store" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + conntypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" errorsmod "cosmossdk.io/errors" + storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" - storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" + "cosmossdk.io/log" tmtypes "github.com/cometbft/cometbft/abci/types" - "github.com/cometbft/cometbft/libs/log" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // Keeper defines the Cross-Chain Validation Consumer Keeper type Keeper struct { - storeKey storetypes.StoreKey + // the address capable of executing a MsgUpdateParams message. Typically, this + // should be the x/gov module account. + authority string + + storeKey storetypes.StoreKey // TODO: maybe needs to be removed? + storeService store.KVStoreService cdc codec.BinaryCodec - paramStore paramtypes.Subspace scopedKeeper ccv.ScopedKeeper channelKeeper ccv.ChannelKeeper portKeeper ccv.PortKeeper @@ -48,6 +54,9 @@ type Keeper struct { ibcTransferKeeper ccv.IBCTransferKeeper ibcCoreKeeper ccv.IBCCoreKeeper feeCollectorName string + + validatorAddressCodec addresscodec.Codec + consensusAddressCodec addresscodec.Codec } // NewKeeper creates a new Consumer Keeper instance @@ -60,7 +69,8 @@ func NewKeeper( connectionKeeper ccv.ConnectionKeeper, clientKeeper ccv.ClientKeeper, slashingKeeper ccv.SlashingKeeper, bankKeeper ccv.BankKeeper, accountKeeper ccv.AccountKeeper, ibcTransferKeeper ccv.IBCTransferKeeper, ibcCoreKeeper ccv.IBCCoreKeeper, - feeCollectorName string, + feeCollectorName, authority string, validatorAddressCodec, + consensusAddressCodec addresscodec.Codec, ) Keeper { // set KeyTable if it has not already been set if !paramSpace.HasKeyTable() { @@ -68,9 +78,9 @@ func NewKeeper( } k := Keeper{ + authority: authority, storeKey: key, cdc: cdc, - paramStore: paramSpace, scopedKeeper: scopedKeeper, channelKeeper: channelKeeper, portKeeper: portKeeper, @@ -83,6 +93,8 @@ func NewKeeper( ibcCoreKeeper: ibcCoreKeeper, feeCollectorName: feeCollectorName, standaloneStakingKeeper: nil, + validatorAddressCodec: validatorAddressCodec, + consensusAddressCodec: consensusAddressCodec, } k.mustValidateFields() @@ -93,9 +105,8 @@ func NewKeeper( // Used only in testing. func NewNonZeroKeeper(cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace) Keeper { return Keeper{ - storeKey: key, - cdc: cdc, - paramStore: paramSpace, + storeKey: key, + cdc: cdc, } } @@ -105,38 +116,44 @@ func (k *Keeper) SetStandaloneStakingKeeper(sk ccv.StakingKeeper) { k.standaloneStakingKeeper = sk } -// SetParamSpace sets the param space for the consumer keeper. -// Note: this is only used for testing! -func (k *Keeper) SetParamSpace(ctx sdk.Context, ps paramtypes.Subspace) { - k.paramStore = ps -} - // Validates that the consumer keeper is initialized with non-zero and // non-nil values for all its fields. Otherwise this method will panic. func (k Keeper) mustValidateFields() { // Ensures no fields are missed in this validation - if reflect.ValueOf(k).NumField() != 16 { + if reflect.ValueOf(k).NumField() != 19 { panic("number of fields in consumer keeper is not 16") } - // Note 14 / 16 fields will be validated, + // Note 116 / 16 fields will be validated, // hooks are explicitly set after the constructor, // stakingKeeper is optionally set after the constructor, - ccv.PanicIfZeroOrNil(k.storeKey, "storeKey") // 1 - ccv.PanicIfZeroOrNil(k.cdc, "cdc") // 2 - ccv.PanicIfZeroOrNil(k.paramStore, "paramStore") // 3 - ccv.PanicIfZeroOrNil(k.scopedKeeper, "scopedKeeper") // 4 - ccv.PanicIfZeroOrNil(k.channelKeeper, "channelKeeper") // 5 - ccv.PanicIfZeroOrNil(k.portKeeper, "portKeeper") // 6 - ccv.PanicIfZeroOrNil(k.connectionKeeper, "connectionKeeper") // 7 - ccv.PanicIfZeroOrNil(k.clientKeeper, "clientKeeper") // 8 - ccv.PanicIfZeroOrNil(k.slashingKeeper, "slashingKeeper") // 9 - ccv.PanicIfZeroOrNil(k.bankKeeper, "bankKeeper") // 10 - ccv.PanicIfZeroOrNil(k.authKeeper, "authKeeper") // 11 - ccv.PanicIfZeroOrNil(k.ibcTransferKeeper, "ibcTransferKeeper") // 12 - ccv.PanicIfZeroOrNil(k.ibcCoreKeeper, "ibcCoreKeeper") // 13 - ccv.PanicIfZeroOrNil(k.feeCollectorName, "feeCollectorName") // 14 + ccv.PanicIfZeroOrNil(k.storeKey, "storeKey") // 1 + ccv.PanicIfZeroOrNil(k.cdc, "cdc") // 2 + ccv.PanicIfZeroOrNil(k.scopedKeeper, "scopedKeeper") // 3 + ccv.PanicIfZeroOrNil(k.channelKeeper, "channelKeeper") // 4 + ccv.PanicIfZeroOrNil(k.portKeeper, "portKeeper") // 5 + ccv.PanicIfZeroOrNil(k.connectionKeeper, "connectionKeeper") // 6 + ccv.PanicIfZeroOrNil(k.clientKeeper, "clientKeeper") // 7 + ccv.PanicIfZeroOrNil(k.slashingKeeper, "slashingKeeper") // 8 + ccv.PanicIfZeroOrNil(k.bankKeeper, "bankKeeper") // 9 + ccv.PanicIfZeroOrNil(k.authKeeper, "authKeeper") // 10 + ccv.PanicIfZeroOrNil(k.ibcTransferKeeper, "ibcTransferKeeper") // 11 + ccv.PanicIfZeroOrNil(k.ibcCoreKeeper, "ibcCoreKeeper") // 12 + ccv.PanicIfZeroOrNil(k.feeCollectorName, "feeCollectorName") // 13 + ccv.PanicIfZeroOrNil(k.authority, "authority") // 14 + ccv.PanicIfZeroOrNil(k.validatorAddressCodec, "validatorAddressCodec") // 15 + ccv.PanicIfZeroOrNil(k.consensusAddressCodec, "consensusAddressCodec") // 16 +} + +// ValidatorAddressCodec returns the app validator address codec. +func (k Keeper) ValidatorAddressCodec() addresscodec.Codec { + return k.validatorAddressCodec +} + +// ConsensusAddressCodec returns the app consensus address codec. +func (k Keeper) ConsensusAddressCodec() addresscodec.Codec { + return k.consensusAddressCodec } // Logger returns a module-specific logger. @@ -327,7 +344,7 @@ func (k Keeper) GetInitialValSet(ctx sdk.Context) []tmtypes.ValidatorUpdate { return []tmtypes.ValidatorUpdate{} } -func (k Keeper) GetLastStandaloneValidators(ctx sdk.Context) []stakingtypes.Validator { +func (k Keeper) GetLastStandaloneValidators(ctx sdk.Context) ([]stakingtypes.Validator, error) { if !k.IsPreCCV(ctx) || k.standaloneStakingKeeper == nil { panic("cannot get last standalone validators if not in pre-ccv state, or if standalone staking keeper is nil") } @@ -338,7 +355,7 @@ func (k Keeper) GetLastStandaloneValidators(ctx sdk.Context) []stakingtypes.Vali // i.e., the slice contains the IDs of the matured VSCPackets. func (k Keeper) GetElapsedPacketMaturityTimes(ctx sdk.Context) (maturingVSCPackets []types.MaturingVSCPacket) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.PacketMaturityTimeBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.PacketMaturityTimeBytePrefix}) defer iterator.Close() @@ -370,7 +387,7 @@ func (k Keeper) GetElapsedPacketMaturityTimes(ctx sdk.Context) (maturingVSCPacke // If two entries have the same maturityTime, then they are ordered by vscID. func (k Keeper) GetAllPacketMaturityTimes(ctx sdk.Context) (maturingVSCPackets []types.MaturingVSCPacket) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.PacketMaturityTimeBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.PacketMaturityTimeBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -471,7 +488,7 @@ func (k Keeper) DeleteHeightValsetUpdateID(ctx sdk.Context, height uint64) { // Thus, the returned array is in ascending order of heights. func (k Keeper) GetAllHeightToValsetUpdateIDs(ctx sdk.Context) (heightToValsetUpdateIDs []types.HeightToValsetUpdateID) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.HeightValsetUpdateIDBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.HeightValsetUpdateIDBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -513,7 +530,7 @@ func (k Keeper) DeleteOutstandingDowntime(ctx sdk.Context, address sdk.ConsAddre // Thus, the returned array is in ascending order of consAddresses. func (k Keeper) GetAllOutstandingDowntimes(ctx sdk.Context) (downtimes []types.OutstandingDowntime) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.OutstandingDowntimeBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.OutstandingDowntimeBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -562,7 +579,7 @@ func (k Keeper) DeleteCCValidator(ctx sdk.Context, addr []byte) { // Thus, the returned array is in ascending order of addresses. func (k Keeper) GetAllCCValidator(ctx sdk.Context) (validators []types.CrossChainValidator) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.CrossChainValidatorBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.CrossChainValidatorBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -590,7 +607,7 @@ func (k Keeper) getAndIncrementPendingPacketsIdx(ctx sdk.Context) (toReturn uint // DeleteHeadOfPendingPackets deletes the head of the pending packets queue. func (k Keeper) DeleteHeadOfPendingPackets(ctx sdk.Context) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.PendingDataPacketsBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.PendingDataPacketsBytePrefix}) defer iterator.Close() if !iterator.Valid() { return @@ -624,7 +641,7 @@ func (k Keeper) GetAllPendingPacketsWithIdx(ctx sdk.Context) []ConsumerPacketDat store := ctx.KVStore(k.storeKey) // Note: PendingDataPacketsBytePrefix is the correct prefix, NOT PendingDataPacketsByteKey. // See consistency with PendingDataPacketsKey(). - iterator := sdk.KVStorePrefixIterator(store, []byte{types.PendingDataPacketsBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.PendingDataPacketsBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { var packet ccv.ConsumerPacketData @@ -656,7 +673,7 @@ func (k Keeper) DeleteAllPendingDataPackets(ctx sdk.Context) { store := ctx.KVStore(k.storeKey) // Note: PendingDataPacketsBytePrefix is the correct prefix, NOT PendingDataPacketsByteKey. // See consistency with PendingDataPacketsKey(). - iterator := sdk.KVStorePrefixIterator(store, []byte{types.PendingDataPacketsBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.PendingDataPacketsBytePrefix}) keysToDel := [][]byte{} defer iterator.Close() for ; iterator.Valid(); iterator.Next() { diff --git a/x/ccv/consumer/keeper/keeper_test.go b/x/ccv/consumer/keeper/keeper_test.go index 19856211b5..51117c9683 100644 --- a/x/ccv/consumer/keeper/keeper_test.go +++ b/x/ccv/consumer/keeper/keeper_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" + conntypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" @@ -17,10 +17,10 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/cosmos/interchain-security/v4/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // TestProviderClientID tests getter and setter functionality for the client ID stored on consumer keeper @@ -187,9 +187,10 @@ func TestGetLastSovereignValidators(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetLastValidators(ctx).Return([]stakingtypes.Validator{ val, - }), + }, nil), ) - lastSovVals := ck.GetLastStandaloneValidators(ctx) + lastSovVals, err := ck.GetLastStandaloneValidators(ctx) + require.NoError(t, err) require.Equal(t, []stakingtypes.Validator{val}, lastSovVals) require.Equal(t, "sanity check this is the correctly serialized val", lastSovVals[0].Description.Moniker) diff --git a/x/ccv/consumer/keeper/legacy_params.go b/x/ccv/consumer/keeper/legacy_params.go new file mode 100644 index 0000000000..9bf1618dcc --- /dev/null +++ b/x/ccv/consumer/keeper/legacy_params.go @@ -0,0 +1,118 @@ +package keeper + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" +) + +// Legacy: used for migration only! +// GetConsumerParamsLegacy returns the params for the consumer ccv module from x/param subspace +// which will be deprecated soon +func GetConsumerParamsLegacy(ctx sdk.Context, keeper Keeper, paramSpace paramtypes.Subspace) ccvtypes.ConsumerParams { + return ccvtypes.NewParams( + getEnabled(ctx, paramSpace), + getBlocksPerDistributionTransmission(ctx, paramSpace), + getDistributionTransmissionChannel(ctx, paramSpace), + getProviderFeePoolAddrStr(ctx, paramSpace), + getCCVTimeoutPeriod(ctx, paramSpace), + getTransferTimeoutPeriod(ctx, paramSpace), + getConsumerRedistributionFrac(ctx, paramSpace), + getHistoricalEntries(ctx, paramSpace), + getUnbondingPeriod(ctx, paramSpace), + getSoftOptOutThreshold(ctx, paramSpace), + getRewardDenoms(ctx, paramSpace), + getProviderRewardDenoms(ctx, paramSpace), + getRetryDelayPeriod(ctx, paramSpace), + ) +} + +// getEnabled returns the enabled flag for the consumer module +func getEnabled(ctx sdk.Context, paramStore paramtypes.Subspace) bool { + var enabled bool + paramStore.Get(ctx, ccvtypes.KeyEnabled, &enabled) + return enabled +} + +func getBlocksPerDistributionTransmission(ctx sdk.Context, paramStore paramtypes.Subspace) int64 { + var bpdt int64 + paramStore.Get(ctx, ccvtypes.KeyBlocksPerDistributionTransmission, &bpdt) + return bpdt +} + +func getDistributionTransmissionChannel(ctx sdk.Context, paramStore paramtypes.Subspace) string { + var s string + paramStore.Get(ctx, ccvtypes.KeyDistributionTransmissionChannel, &s) + return s +} + +func getProviderFeePoolAddrStr(ctx sdk.Context, paramStore paramtypes.Subspace) string { + var s string + paramStore.Get(ctx, ccvtypes.KeyProviderFeePoolAddrStr, &s) + return s +} + +// getCCVTimeoutPeriod returns the timeout period for sent ccv related ibc packets +func getCCVTimeoutPeriod(ctx sdk.Context, paramStore paramtypes.Subspace) time.Duration { + var p time.Duration + paramStore.Get(ctx, ccvtypes.KeyCCVTimeoutPeriod, &p) + return p +} + +// getTransferTimeoutPeriod returns the timeout period for sent transfer related ibc packets +func getTransferTimeoutPeriod(ctx sdk.Context, paramStore paramtypes.Subspace) time.Duration { + var p time.Duration + paramStore.Get(ctx, ccvtypes.KeyTransferTimeoutPeriod, &p) + return p +} + +// getConsumerRedistributionFrac returns the fraction of tokens allocated to the consumer redistribution +// address during distribution events. The fraction is a string representing a +// decimal number. For example "0.75" would represent 75%. +func getConsumerRedistributionFrac(ctx sdk.Context, paramStore paramtypes.Subspace) string { + var str string + paramStore.Get(ctx, ccvtypes.KeyConsumerRedistributionFrac, &str) + return str +} + +// getHistoricalEntries returns the number of historical info entries to persist in store +func getHistoricalEntries(ctx sdk.Context, paramStore paramtypes.Subspace) int64 { + var n int64 + paramStore.Get(ctx, ccvtypes.KeyHistoricalEntries, &n) + return n +} + +func getUnbondingPeriod(ctx sdk.Context, paramStore paramtypes.Subspace) time.Duration { + var period time.Duration + paramStore.Get(ctx, ccvtypes.KeyConsumerUnbondingPeriod, &period) + return period +} + +// getSoftOptOutThreshold returns the percentage of validators at the bottom of the set +// that can opt out of running the consumer chain +func getSoftOptOutThreshold(ctx sdk.Context, paramStore paramtypes.Subspace) string { + var str string + paramStore.Get(ctx, ccvtypes.KeySoftOptOutThreshold, &str) + return str +} + +func getRewardDenoms(ctx sdk.Context, paramStore paramtypes.Subspace) []string { + var denoms []string + paramStore.Get(ctx, ccvtypes.KeyRewardDenoms, &denoms) + return denoms +} + +func getProviderRewardDenoms(ctx sdk.Context, paramStore paramtypes.Subspace) []string { + var denoms []string + paramStore.Get(ctx, ccvtypes.KeyProviderRewardDenoms, &denoms) + return denoms +} + +func getRetryDelayPeriod(ctx sdk.Context, paramStore paramtypes.Subspace) time.Duration { + var period time.Duration + paramStore.Get(ctx, ccvtypes.KeyRetryDelayPeriod, &period) + return period +} diff --git a/x/ccv/consumer/keeper/migrations.go b/x/ccv/consumer/keeper/migrations.go index a1e826e61e..ba4746b3d4 100644 --- a/x/ccv/consumer/keeper/migrations.go +++ b/x/ccv/consumer/keeper/migrations.go @@ -4,7 +4,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - v2 "github.com/cosmos/interchain-security/v4/x/ccv/consumer/migrations/v2" + v2 "github.com/cosmos/interchain-security/v5/x/ccv/consumer/migrations/v2" ) // Migrator is a struct for handling in-place store migrations. @@ -23,3 +23,9 @@ func (m Migrator) Migrate1to2(ctx sdk.Context) error { store := ctx.KVStore(m.keeper.storeKey) return v2.MigrateConsumerPacketData(ctx, store) } + +// Migrate2to3 migrates x/ccvconsumer state from consensus version 2 to 3. +func (m Migrator) Migrate2to3(ctx sdk.Context) error { + store := ctx.KVStore(m.keeper.storeKey) + return v2.MigrateConsumerPacketData(ctx, store) +} diff --git a/x/ccv/consumer/keeper/params.go b/x/ccv/consumer/keeper/params.go index 4d96ddf604..f72b627322 100644 --- a/x/ccv/consumer/keeper/params.go +++ b/x/ccv/consumer/keeper/params.go @@ -1,147 +1,136 @@ package keeper import ( + "context" "time" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // GetParams returns the params for the consumer ccv module // NOTE: it is different from the GetParams method which is required to implement StakingKeeper interface func (k Keeper) GetConsumerParams(ctx sdk.Context) ccvtypes.ConsumerParams { - return ccvtypes.NewParams( - k.GetEnabled(ctx), - k.GetBlocksPerDistributionTransmission(ctx), - k.GetDistributionTransmissionChannel(ctx), - k.GetProviderFeePoolAddrStr(ctx), - k.GetCCVTimeoutPeriod(ctx), - k.GetTransferTimeoutPeriod(ctx), - k.GetConsumerRedistributionFrac(ctx), - k.GetHistoricalEntries(ctx), - k.GetUnbondingPeriod(ctx), - k.GetSoftOptOutThreshold(ctx), - k.GetRewardDenoms(ctx), - k.GetProviderRewardDenoms(ctx), - k.GetRetryDelayPeriod(ctx), - ) + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.ParametersKey()) + var params ccvtypes.ConsumerParams + k.cdc.MustUnmarshal(bz, ¶ms) + return params } // SetParams sets the paramset for the consumer module func (k Keeper) SetParams(ctx sdk.Context, params ccvtypes.ConsumerParams) { - k.paramStore.SetParamSet(ctx, ¶ms) + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(¶ms) + store.Set(types.ParametersKey(), bz) } // GetParams implements StakingKeeper GetParams interface method // it returns an a empty stakingtypes.Params struct // NOTE: this method must be implemented on the consumer keeper because the evidence module keeper -// in cosmos-sdk v0.47 requires this exact method with this exact signature to be available on the StakingKeepr -func (k Keeper) GetParams(ctx sdk.Context) stakingtypes.Params { - return stakingtypes.Params{} +// in cosmos-sdk v0.50 requires this exact method with this exact signature to be available on the StakingKeepr +func (k Keeper) GetParams(context.Context) (stakingtypes.Params, error) { + return stakingtypes.Params{}, nil } // GetEnabled returns the enabled flag for the consumer module func (k Keeper) GetEnabled(ctx sdk.Context) bool { - var enabled bool - k.paramStore.Get(ctx, ccvtypes.KeyEnabled, &enabled) - return enabled + params := k.GetConsumerParams(ctx) + return params.Enabled } func (k Keeper) GetBlocksPerDistributionTransmission(ctx sdk.Context) int64 { - var bpdt int64 - k.paramStore.Get(ctx, ccvtypes.KeyBlocksPerDistributionTransmission, &bpdt) - return bpdt + params := k.GetConsumerParams(ctx) + return params.BlocksPerDistributionTransmission } func (k Keeper) SetBlocksPerDistributionTransmission(ctx sdk.Context, bpdt int64) { - k.paramStore.Set(ctx, ccvtypes.KeyBlocksPerDistributionTransmission, bpdt) + params := k.GetConsumerParams(ctx) + params.BlocksPerDistributionTransmission = bpdt + k.SetParams(ctx, params) } func (k Keeper) GetDistributionTransmissionChannel(ctx sdk.Context) string { - var s string - k.paramStore.Get(ctx, ccvtypes.KeyDistributionTransmissionChannel, &s) - return s + params := k.GetConsumerParams(ctx) + return params.DistributionTransmissionChannel } func (k Keeper) SetDistributionTransmissionChannel(ctx sdk.Context, channel string) { - k.paramStore.Set(ctx, ccvtypes.KeyDistributionTransmissionChannel, channel) + params := k.GetConsumerParams(ctx) + params.DistributionTransmissionChannel = channel + k.SetParams(ctx, params) } func (k Keeper) GetProviderFeePoolAddrStr(ctx sdk.Context) string { - var s string - k.paramStore.Get(ctx, ccvtypes.KeyProviderFeePoolAddrStr, &s) - return s + params := k.GetConsumerParams(ctx) + return params.ProviderFeePoolAddrStr } func (k Keeper) SetProviderFeePoolAddrStr(ctx sdk.Context, addr string) { - k.paramStore.Set(ctx, ccvtypes.KeyProviderFeePoolAddrStr, addr) + params := k.GetConsumerParams(ctx) + params.ProviderFeePoolAddrStr = addr + k.SetParams(ctx, params) } // GetCCVTimeoutPeriod returns the timeout period for sent ccv related ibc packets func (k Keeper) GetCCVTimeoutPeriod(ctx sdk.Context) time.Duration { - var p time.Duration - k.paramStore.Get(ctx, ccvtypes.KeyCCVTimeoutPeriod, &p) - return p + params := k.GetConsumerParams(ctx) + return params.CcvTimeoutPeriod } // GetTransferTimeoutPeriod returns the timeout period for sent transfer related ibc packets func (k Keeper) GetTransferTimeoutPeriod(ctx sdk.Context) time.Duration { - var p time.Duration - k.paramStore.Get(ctx, ccvtypes.KeyTransferTimeoutPeriod, &p) - return p + params := k.GetConsumerParams(ctx) + return params.TransferTimeoutPeriod } // GetConsumerRedistributionFrac returns the fraction of tokens allocated to the consumer redistribution // address during distribution events. The fraction is a string representing a // decimal number. For example "0.75" would represent 75%. func (k Keeper) GetConsumerRedistributionFrac(ctx sdk.Context) string { - var str string - k.paramStore.Get(ctx, ccvtypes.KeyConsumerRedistributionFrac, &str) - return str + params := k.GetConsumerParams(ctx) + return params.ConsumerRedistributionFraction } // GetHistoricalEntries returns the number of historical info entries to persist in store func (k Keeper) GetHistoricalEntries(ctx sdk.Context) int64 { - var n int64 - k.paramStore.Get(ctx, ccvtypes.KeyHistoricalEntries, &n) - return n + params := k.GetConsumerParams(ctx) + return params.HistoricalEntries } // Only used to set an unbonding period in diff tests func (k Keeper) SetUnbondingPeriod(ctx sdk.Context, period time.Duration) { - k.paramStore.Set(ctx, ccvtypes.KeyConsumerUnbondingPeriod, period) + params := k.GetConsumerParams(ctx) + params.UnbondingPeriod = period + k.SetParams(ctx, params) } func (k Keeper) GetUnbondingPeriod(ctx sdk.Context) time.Duration { - var period time.Duration - k.paramStore.Get(ctx, ccvtypes.KeyConsumerUnbondingPeriod, &period) - return period + params := k.GetConsumerParams(ctx) + return params.UnbondingPeriod } // GetSoftOptOutThreshold returns the percentage of validators at the bottom of the set // that can opt out of running the consumer chain func (k Keeper) GetSoftOptOutThreshold(ctx sdk.Context) string { - var str string - k.paramStore.Get(ctx, ccvtypes.KeySoftOptOutThreshold, &str) - return str + params := k.GetConsumerParams(ctx) + return params.SoftOptOutThreshold } func (k Keeper) GetRewardDenoms(ctx sdk.Context) []string { - var denoms []string - k.paramStore.Get(ctx, ccvtypes.KeyRewardDenoms, &denoms) - return denoms + params := k.GetConsumerParams(ctx) + return params.RewardDenoms } func (k Keeper) GetProviderRewardDenoms(ctx sdk.Context) []string { - var denoms []string - k.paramStore.Get(ctx, ccvtypes.KeyProviderRewardDenoms, &denoms) - return denoms + params := k.GetConsumerParams(ctx) + return params.ProviderRewardDenoms } func (k Keeper) GetRetryDelayPeriod(ctx sdk.Context) time.Duration { - var period time.Duration - k.paramStore.Get(ctx, ccvtypes.KeyRetryDelayPeriod, &period) - return period + params := k.GetConsumerParams(ctx) + return params.RetryDelayPeriod } diff --git a/x/ccv/consumer/keeper/params_test.go b/x/ccv/consumer/keeper/params_test.go index e2975a0b31..18d3f5a2b2 100644 --- a/x/ccv/consumer/keeper/params_test.go +++ b/x/ccv/consumer/keeper/params_test.go @@ -6,8 +6,8 @@ import ( "github.com/stretchr/testify/require" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // TestParams tests getters/setters for consumer params diff --git a/x/ccv/consumer/keeper/provider_info.go b/x/ccv/consumer/keeper/provider_info.go index e5fbaf6540..8dc5c0448d 100644 --- a/x/ccv/consumer/keeper/provider_info.go +++ b/x/ccv/consumer/keeper/provider_info.go @@ -1,12 +1,12 @@ package keeper import ( - ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" //nolint:golint + ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" //nolint:golint sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) func (k Keeper) GetProviderInfo(ctx sdk.Context) (*types.QueryProviderInfoResponse, error) { //nolint:golint diff --git a/x/ccv/consumer/keeper/relay.go b/x/ccv/consumer/keeper/relay.go index 2d4e16510a..e20a481cd6 100644 --- a/x/ccv/consumer/keeper/relay.go +++ b/x/ccv/consumer/keeper/relay.go @@ -1,11 +1,12 @@ package keeper import ( + "errors" "fmt" "strconv" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" errorsmod "cosmossdk.io/errors" @@ -14,8 +15,8 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // OnRecvVSCPacket sets the pending validator set changes that will be flushed to ABCI on Endblock @@ -217,7 +218,7 @@ func (k Keeper) SendPackets(ctx sdk.Context) { k.GetCCVTimeoutPeriod(ctx), ) if err != nil { - if clienttypes.ErrClientNotActive.Is(err) { + if errors.Is(err, clienttypes.ErrClientNotActive) { // IBC client is expired! // leave the packet data stored to be sent once the client is upgraded k.Logger(ctx).Info("IBC client is expired, cannot send IBC packet; leaving packet data stored:", "type", p.Type.String()) diff --git a/x/ccv/consumer/keeper/relay_test.go b/x/ccv/consumer/keeper/relay_test.go index 46a805a85a..e26a53a645 100644 --- a/x/ccv/consumer/keeper/relay_test.go +++ b/x/ccv/consumer/keeper/relay_test.go @@ -6,26 +6,26 @@ import ( "testing" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/libs/bytes" - "github.com/cosmos/interchain-security/v4/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - consumerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + consumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // TestOnRecvVSCPacket tests the behavior of OnRecvVSCPacket over various packet scenarios diff --git a/x/ccv/consumer/keeper/soft_opt_out.go b/x/ccv/consumer/keeper/soft_opt_out.go index 25747feb51..1de2345cbc 100644 --- a/x/ccv/consumer/keeper/soft_opt_out.go +++ b/x/ccv/consumer/keeper/soft_opt_out.go @@ -2,11 +2,15 @@ package keeper import ( "encoding/binary" + "errors" + "fmt" "sort" + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" ) // BeginBlockSoftOptOut executes BeginBlock logic for the Soft Opt-Out sub-protocol @@ -29,7 +33,7 @@ func (k Keeper) SetSmallestNonOptOutPower(ctx sdk.Context, power uint64) { // is less than [SoftOptOutThreshold] of the total power of all validators. func (k Keeper) UpdateSmallestNonOptOutPower(ctx sdk.Context) { // get soft opt-out threshold - optOutThreshold := sdk.MustNewDecFromStr(k.GetSoftOptOutThreshold(ctx)) + optOutThreshold := math.LegacyMustNewDecFromStr(k.GetSoftOptOutThreshold(ctx)) if optOutThreshold.IsZero() { // If the SoftOptOutThreshold is zero, then soft opt-out is disable. // Setting the smallest non-opt-out power to zero, fixes the diff-testing @@ -53,15 +57,15 @@ func (k Keeper) UpdateSmallestNonOptOutPower(ctx sdk.Context) { }) // get total power in set - totalPower := sdk.ZeroDec() + totalPower := math.LegacyZeroDec() for _, val := range valset { - totalPower = totalPower.Add(sdk.NewDecFromInt(sdk.NewInt(val.Power))) + totalPower = totalPower.Add(math.LegacyNewDecFromInt(math.NewInt(val.Power))) } // get power of the smallest validator that cannot soft opt out - powerSum := sdk.ZeroDec() + powerSum := math.LegacyZeroDec() for _, val := range valset { - powerSum = powerSum.Add(sdk.NewDecFromInt(sdk.NewInt(val.Power))) + powerSum = powerSum.Add(math.LegacyNewDecFromInt(math.NewInt(val.Power))) // if powerSum / totalPower > SoftOptOutThreshold if powerSum.Quo(totalPower).GT(optOutThreshold) { // set smallest non opt out power @@ -93,26 +97,30 @@ func (k Keeper) UpdateSlashingSigningInfo(ctx sdk.Context) { // a certain prefix in ascending order for _, val := range valset { consAddr := sdk.ConsAddress(val.Address) - signingInfo, found := k.slashingKeeper.GetValidatorSigningInfo(ctx, consAddr) - if !found { + signingInfo, err := k.slashingKeeper.GetValidatorSigningInfo(ctx, consAddr) + if errors.Is(err, slashingtypes.ErrNoSigningInfoFound) { continue + } else if err != nil { + panic(fmt.Errorf("failed to get validator signing info for validator %s", consAddr)) } if val.Power < smallestNonOptOutPower { // validator CAN opt-out from validating on consumer chains - if val.OptedOut == false { + if !val.OptedOut { // previously the validator couldn't opt-out val.OptedOut = true } } else { // validator CANNOT opt-out from validating on consumer chains - if val.OptedOut == true { + if val.OptedOut { // previously the validator could opt-out signingInfo.StartHeight = ctx.BlockHeight() val.OptedOut = false } } - k.slashingKeeper.SetValidatorSigningInfo(ctx, consAddr, signingInfo) + if err := k.slashingKeeper.SetValidatorSigningInfo(ctx, consAddr, signingInfo); err != nil { + panic(fmt.Errorf("failed to update validator signing info for validator %s", consAddr)) + } k.SetCCValidator(ctx, val) } } diff --git a/x/ccv/consumer/keeper/soft_opt_out_test.go b/x/ccv/consumer/keeper/soft_opt_out_test.go index 1a726d1767..5c21133832 100644 --- a/x/ccv/consumer/keeper/soft_opt_out_test.go +++ b/x/ccv/consumer/keeper/soft_opt_out_test.go @@ -7,9 +7,9 @@ import ( tmtypes "github.com/cometbft/cometbft/types" - "github.com/cosmos/interchain-security/v4/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // Tests that UpdateSmallestNonOptOutPower updates the smallest validator power that cannot soft opt out. diff --git a/x/ccv/consumer/keeper/throttle_retry.go b/x/ccv/consumer/keeper/throttle_retry.go index 22e48f9175..4b6df3cc04 100644 --- a/x/ccv/consumer/keeper/throttle_retry.go +++ b/x/ccv/consumer/keeper/throttle_retry.go @@ -5,7 +5,7 @@ import ( sdktypes "github.com/cosmos/cosmos-sdk/types" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" ) // diff --git a/x/ccv/consumer/keeper/throttle_retry_test.go b/x/ccv/consumer/keeper/throttle_retry_test.go index 4a222fde90..b979ebb51d 100644 --- a/x/ccv/consumer/keeper/throttle_retry_test.go +++ b/x/ccv/consumer/keeper/throttle_retry_test.go @@ -6,9 +6,9 @@ import ( "github.com/stretchr/testify/require" - testutil "github.com/cosmos/interchain-security/v4/testutil/keeper" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + testutil "github.com/cosmos/interchain-security/v5/testutil/keeper" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) func TestPacketSendingPermitted(t *testing.T) { diff --git a/x/ccv/consumer/keeper/validators.go b/x/ccv/consumer/keeper/validators.go index 24a1c5a57c..7bc86ded38 100644 --- a/x/ccv/consumer/keeper/validators.go +++ b/x/ccv/consumer/keeper/validators.go @@ -1,6 +1,8 @@ package keeper import ( + "context" + "errors" "time" "cosmossdk.io/math" @@ -11,7 +13,7 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" ) // @@ -25,7 +27,7 @@ func (k Keeper) ApplyCCValidatorChanges(ctx sdk.Context, changes []abci.Validato ret := []abci.ValidatorUpdate{} for _, change := range changes { // convert TM pubkey to SDK pubkey - pubkey, err := cryptocodec.FromTmProtoPublicKey(change.GetPubKey()) + pubkey, err := cryptocodec.FromCmtProtoPublicKey(change.GetPubKey()) if err != nil { // An error here would indicate that the validator updates // received from the provider are invalid. @@ -78,27 +80,30 @@ func (k Keeper) ApplyCCValidatorChanges(ctx sdk.Context, changes []abci.Validato // IterateValidators - unimplemented on CCV keeper but perform a no-op in order to pass the slashing module InitGenesis. // It is allowed since the condition verifying validator public keys in HandleValidatorSignature (x/slashing/keeper/infractions.go) is removed // therefore it isn't required to store any validator public keys to the slashing states during genesis. -func (k Keeper) IterateValidators(sdk.Context, func(index int64, validator stakingtypes.ValidatorI) (stop bool)) { +func (k Keeper) IterateValidators(context.Context, func(index int64, validator stakingtypes.ValidatorI) (stop bool)) error { + return nil } // Validator - unimplemented on CCV keeper -func (k Keeper) Validator(ctx sdk.Context, addr sdk.ValAddress) stakingtypes.ValidatorI { +func (k Keeper) Validator(ctx context.Context, addr sdk.ValAddress) (stakingtypes.ValidatorI, error) { panic("unimplemented on CCV keeper") } // IsJailed returns the outstanding slashing flag for the given validator address -func (k Keeper) IsValidatorJailed(ctx sdk.Context, addr sdk.ConsAddress) bool { +func (k Keeper) IsValidatorJailed(goCtx context.Context, addr sdk.ConsAddress) (bool, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + // if the changeover is not complete for prev standalone chain, // return the standalone staking keeper's jailed status if k.IsPrevStandaloneChain(ctx) && !k.ChangeoverIsComplete(ctx) { return k.standaloneStakingKeeper.IsValidatorJailed(ctx, addr) } // Otherwise, return the ccv consumer keeper's notion of a validator being jailed - return k.OutstandingDowntime(ctx, addr) + return k.OutstandingDowntime(ctx, addr), nil } // ValidatorByConsAddr returns an empty validator -func (k Keeper) ValidatorByConsAddr(sdk.Context, sdk.ConsAddress) stakingtypes.ValidatorI { +func (k Keeper) ValidatorByConsAddr(context.Context, sdk.ConsAddress) (stakingtypes.ValidatorI, error) { /* NOTE: @@ -109,22 +114,24 @@ func (k Keeper) ValidatorByConsAddr(sdk.Context, sdk.ConsAddress) stakingtypes.V Also, the slashing module will cal lthis function when it observes downtime. In that case the only requirement on the returned value is that it isn't null. */ - return stakingtypes.Validator{} + return stakingtypes.Validator{}, nil } // Calls SlashWithInfractionReason with Infraction_INFRACTION_UNSPECIFIED. // ConsumerKeeper must implement StakingKeeper interface. // This function should not be called anywhere -func (k Keeper) Slash(ctx sdk.Context, addr sdk.ConsAddress, infractionHeight, power int64, slashFactor sdk.Dec) math.Int { +func (k Keeper) Slash(ctx context.Context, addr sdk.ConsAddress, infractionHeight, power int64, slashFactor math.LegacyDec) (math.Int, error) { return k.SlashWithInfractionReason(ctx, addr, infractionHeight, power, slashFactor, stakingtypes.Infraction_INFRACTION_UNSPECIFIED) } // Slash queues a slashing request for the the provider chain // All queued slashing requests will be cleared in EndBlock // Called by Slashing keeper in SlashWithInfractionReason -func (k Keeper) SlashWithInfractionReason(ctx sdk.Context, addr sdk.ConsAddress, infractionHeight, power int64, slashFactor sdk.Dec, infraction stakingtypes.Infraction) math.Int { +func (k Keeper) SlashWithInfractionReason(goCtx context.Context, addr sdk.ConsAddress, infractionHeight, power int64, slashFactor math.LegacyDec, infraction stakingtypes.Infraction) (math.Int, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + if infraction == stakingtypes.Infraction_INFRACTION_UNSPECIFIED { - return math.NewInt(0) + return math.ZeroInt(), nil } // If this is a previously standalone chain and infraction happened before the changeover was completed, @@ -145,7 +152,7 @@ func (k Keeper) SlashWithInfractionReason(ctx sdk.Context, addr sdk.ConsAddress, "validator", addr, "power", power, ) - return math.NewInt(0) + return math.ZeroInt(), nil } } // get VSC ID for infraction height @@ -170,7 +177,7 @@ func (k Keeper) SlashWithInfractionReason(ctx sdk.Context, addr sdk.ConsAddress, ) // Only return to comply with the interface restriction - return math.ZeroInt() + return math.ZeroInt(), nil } // Jail - unimplemented on CCV keeper @@ -178,45 +185,50 @@ func (k Keeper) SlashWithInfractionReason(ctx sdk.Context, addr sdk.ConsAddress, // This method should be a no-op even during a standalone to consumer changeover. // Once the upgrade has happened as a part of the changeover, // the provider validator set will soon be in effect, and jailing is n/a. -func (k Keeper) Jail(ctx sdk.Context, addr sdk.ConsAddress) {} +func (k Keeper) Jail(context.Context, sdk.ConsAddress) error { return nil } // Unjail - unimplemented on CCV keeper // // This method should be a no-op even during a standalone to consumer changeover. // Once the upgrade has happened as a part of the changeover, // the provider validator set will soon be in effect, and jailing is n/a. -func (k Keeper) Unjail(sdk.Context, sdk.ConsAddress) {} +func (k Keeper) Unjail(context.Context, sdk.ConsAddress) error { return nil } // Delegation - unimplemented on CCV keeper -func (k Keeper) Delegation(sdk.Context, sdk.AccAddress, sdk.ValAddress) stakingtypes.DelegationI { +func (k Keeper) Delegation(ctx context.Context, addr sdk.AccAddress, valAddr sdk.ValAddress) (stakingtypes.DelegationI, error) { panic("unimplemented on CCV keeper") } // MaxValidators - unimplemented on CCV keeper -func (k Keeper) MaxValidators(sdk.Context) uint32 { +func (k Keeper) MaxValidators(context.Context) (uint32, error) { panic("unimplemented on CCV keeper") } // UnbondingTime returns consumer unbonding period, satisfying the staking keeper interface -func (k Keeper) UnbondingTime(ctx sdk.Context) time.Duration { - return k.GetUnbondingPeriod(ctx) +func (k Keeper) UnbondingTime(goCtx context.Context) (time.Duration, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + return k.GetUnbondingPeriod(ctx), nil } // GetHistoricalInfo gets the historical info at a given height -func (k Keeper) GetHistoricalInfo(ctx sdk.Context, height int64) (stakingtypes.HistoricalInfo, bool) { +func (k Keeper) GetHistoricalInfo(goCtx context.Context, height int64) (stakingtypes.HistoricalInfo, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + store := ctx.KVStore(k.storeKey) key := types.HistoricalInfoKey(height) value := store.Get(key) if value == nil { - return stakingtypes.HistoricalInfo{}, false + return stakingtypes.HistoricalInfo{}, stakingtypes.ErrNoHistoricalInfo } - return stakingtypes.MustUnmarshalHistoricalInfo(k.cdc, value), true + return stakingtypes.UnmarshalHistoricalInfo(k.cdc, value) } // SetHistoricalInfo sets the historical info at a given height -func (k Keeper) SetHistoricalInfo(ctx sdk.Context, height int64, hi *stakingtypes.HistoricalInfo) { +func (k Keeper) SetHistoricalInfo(goCtx context.Context, height int64, hi *stakingtypes.HistoricalInfo) { + ctx := sdk.UnwrapSDKContext(goCtx) + store := ctx.KVStore(k.storeKey) key := types.HistoricalInfoKey(height) value := k.cdc.MustMarshal(hi) @@ -225,16 +237,21 @@ func (k Keeper) SetHistoricalInfo(ctx sdk.Context, height int64, hi *stakingtype } // DeleteHistoricalInfo deletes the historical info at a given height -func (k Keeper) DeleteHistoricalInfo(ctx sdk.Context, height int64) { +func (k Keeper) DeleteHistoricalInfo(goCtx context.Context, height int64) error { + ctx := sdk.UnwrapSDKContext(goCtx) + store := ctx.KVStore(k.storeKey) key := types.HistoricalInfoKey(height) store.Delete(key) + return nil } // TrackHistoricalInfo saves the latest historical-info and deletes the oldest // heights that are below pruning height -func (k Keeper) TrackHistoricalInfo(ctx sdk.Context) { +func (k Keeper) TrackHistoricalInfo(goCtx context.Context) error { + ctx := sdk.UnwrapSDKContext(goCtx) + numHistoricalEntries := k.GetHistoricalEntries(ctx) // Prune store to ensure we only have parameter-defined historical entries. @@ -245,17 +262,21 @@ func (k Keeper) TrackHistoricalInfo(ctx sdk.Context) { // over the historical entries starting from the most recent version to be pruned // and then return at the first empty entry. for i := ctx.BlockHeight() - numHistoricalEntries; i >= 0; i-- { - _, found := k.GetHistoricalInfo(ctx, i) - if found { - k.DeleteHistoricalInfo(ctx, i) - } else { - break + _, err := k.GetHistoricalInfo(ctx, i) + if err != nil { + if errors.Is(err, stakingtypes.ErrNoHistoricalInfo) { + break + } + return err + } + if err = k.DeleteHistoricalInfo(ctx, i); err != nil { + return err } } // if there is no need to persist historicalInfo, return if numHistoricalEntries == 0 { - return + return nil } // Create HistoricalInfo struct @@ -267,7 +288,8 @@ func (k Keeper) TrackHistoricalInfo(ctx sdk.Context) { // to be stored correctly in ApplyCCValidatorChanges. panic(err) } - val, err := stakingtypes.NewValidator(nil, pk, stakingtypes.Description{}) + // NOTE: @MSalopek -> double check pk.Address().String() + val, err := stakingtypes.NewValidator(pk.Address().String(), pk, stakingtypes.Description{}) if err != nil { // This should never happen as the pubkey is assumed // to be stored correctly in ApplyCCValidatorChanges. @@ -282,10 +304,11 @@ func (k Keeper) TrackHistoricalInfo(ctx sdk.Context) { } // Create historical info entry which sorts the validator set by voting power - historicalEntry := stakingtypes.NewHistoricalInfo(ctx.BlockHeader(), lastVals, sdk.DefaultPowerReduction) + historicalEntry := stakingtypes.NewHistoricalInfo(ctx.BlockHeader(), stakingtypes.Validators{Validators: lastVals, ValidatorCodec: k.validatorAddressCodec}, sdk.DefaultPowerReduction) // Set latest HistoricalInfo at current height k.SetHistoricalInfo(ctx, ctx.BlockHeight(), &historicalEntry) + return nil } // MustGetCurrentValidatorsAsABCIUpdates gets all cross-chain validators converted @@ -313,12 +336,12 @@ func (k Keeper) MustGetCurrentValidatorsAsABCIUpdates(ctx sdk.Context) []abci.Va // implement interface method needed for x/genutil in sdk v47 // returns empty updates and err -func (k Keeper) ApplyAndReturnValidatorSetUpdates(sdk.Context) (updates []abci.ValidatorUpdate, err error) { +func (k Keeper) ApplyAndReturnValidatorSetUpdates(context.Context) (updates []abci.ValidatorUpdate, err error) { return } // GetAllValidators is needed to implement StakingKeeper as expected by the Slashing module since cosmos-sdk/v0.47.x. // Use GetAllCCValidator in places where access to all cross-chain validators is needed. -func (k Keeper) GetAllValidators(ctx sdk.Context) []stakingtypes.Validator { - return []stakingtypes.Validator{} +func (k Keeper) GetAllValidators(ctx context.Context) ([]stakingtypes.Validator, error) { + return []stakingtypes.Validator{}, nil } diff --git a/x/ccv/consumer/keeper/validators_test.go b/x/ccv/consumer/keeper/validators_test.go index 1d4dcb2c86..0ab47eb21f 100644 --- a/x/ccv/consumer/keeper/validators_test.go +++ b/x/ccv/consumer/keeper/validators_test.go @@ -15,10 +15,10 @@ import ( tmrand "github.com/cometbft/cometbft/libs/rand" tmtypes "github.com/cometbft/cometbft/types" - "github.com/cosmos/interchain-security/v4/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v5/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" ) // TestApplyCCValidatorChanges tests the ApplyCCValidatorChanges method for a consumer keeper @@ -120,13 +120,17 @@ func TestIsValidatorJailed(t *testing.T) { // IsValidatorJailed should return false for an arbitrary consensus address consAddr := []byte{0x01, 0x02, 0x03} - require.False(t, consumerKeeper.IsValidatorJailed(ctx, consAddr)) + isJailed1, err := consumerKeeper.IsValidatorJailed(ctx, consAddr) + require.NoError(t, err) + require.False(t, isJailed1) // Set outstanding downtime for that addr consumerKeeper.SetOutstandingDowntime(ctx, consAddr) // Now confirm IsValidatorJailed returns true - require.True(t, consumerKeeper.IsValidatorJailed(ctx, consAddr)) + isJailed2, err := consumerKeeper.IsValidatorJailed(ctx, consAddr) + require.NoError(t, err) + require.True(t, isJailed2) // Next, we set a value for the standalone staking keeper, // and mark the consumer keeper as being from a previous standalone chain @@ -141,10 +145,12 @@ func TestIsValidatorJailed(t *testing.T) { // At this point, the state of the consumer keeper is s.t. IsValidatorJailed() queries the standalone staking keeper // Now mock that a validator is jailed from the standalone staking keeper - mocks.MockStakingKeeper.EXPECT().IsValidatorJailed(ctx, consAddr).Return(true).Times(1) + mocks.MockStakingKeeper.EXPECT().IsValidatorJailed(ctx, consAddr).Return(true, nil).Times(1) // Confirm IsValidatorJailed returns true - require.True(t, consumerKeeper.IsValidatorJailed(ctx, consAddr)) + isJailed3, err := consumerKeeper.IsValidatorJailed(ctx, consAddr) + require.NoError(t, err) + require.True(t, isJailed3) } func TestSlash(t *testing.T) { @@ -152,7 +158,7 @@ func TestSlash(t *testing.T) { defer ctrl.Finish() // If we call slash with infraction type empty, no slash packet will be queued - consumerKeeper.SlashWithInfractionReason(ctx, []byte{0x01, 0x02, 0x03}, 5, 6, sdk.NewDec(9.0), stakingtypes.Infraction_INFRACTION_UNSPECIFIED) + consumerKeeper.SlashWithInfractionReason(ctx, []byte{0x01, 0x02, 0x03}, 5, 6, math.LegacyNewDec(9.0), stakingtypes.Infraction_INFRACTION_UNSPECIFIED) pendingPackets := consumerKeeper.GetPendingPackets(ctx) require.Len(t, pendingPackets, 0) @@ -163,7 +169,7 @@ func TestSlash(t *testing.T) { consumerKeeper.SetHeightValsetUpdateID(ctx, 5, 6) // Call slash with valid infraction type and confirm 1 slash packet is queued - consumerKeeper.SlashWithInfractionReason(ctx, []byte{0x01, 0x02, 0x03}, 5, 6, sdk.NewDec(9.0), stakingtypes.Infraction_INFRACTION_DOWNTIME) + consumerKeeper.SlashWithInfractionReason(ctx, []byte{0x01, 0x02, 0x03}, 5, 6, math.LegacyNewDec(9.0), stakingtypes.Infraction_INFRACTION_DOWNTIME) pendingPackets = consumerKeeper.GetPendingPackets(ctx) require.Len(t, pendingPackets, 1) @@ -178,21 +184,21 @@ func TestSlash(t *testing.T) { // If we call slash with infraction type empty, standalone staking keeper's slash will not be called // (if it was called, test would panic without mocking the call) - consumerKeeper.SlashWithInfractionReason(ctx, []byte{0x01, 0x02, 0x03}, 5, 6, sdk.NewDec(9.0), stakingtypes.Infraction_INFRACTION_UNSPECIFIED) + consumerKeeper.SlashWithInfractionReason(ctx, []byte{0x01, 0x02, 0x03}, 5, 6, math.LegacyNewDec(9.0), stakingtypes.Infraction_INFRACTION_UNSPECIFIED) // Now setup a mock for Slash, and confirm that it is called against // standalone staking keeper with valid infraction type infractionHeight := int64(5) mocks.MockStakingKeeper.EXPECT().SlashWithInfractionReason( ctx, []byte{0x01, 0x02, 0x03}, infractionHeight, int64(6), - sdk.MustNewDecFromStr("0.05"), stakingtypes.Infraction_INFRACTION_UNSPECIFIED).Times(1) // We pass empty infraction to standalone staking keeper since it's not used + math.LegacyMustNewDecFromStr("0.05"), stakingtypes.Infraction_INFRACTION_UNSPECIFIED).Times(1) // We pass empty infraction to standalone staking keeper since it's not used // Also setup init genesis height s.t. infraction height is before first consumer height consumerKeeper.SetInitGenesisHeight(ctx, 4) require.Equal(t, consumerKeeper.FirstConsumerHeight(ctx), int64(6)) consumerKeeper.SlashWithInfractionReason(ctx, []byte{0x01, 0x02, 0x03}, infractionHeight, 6, - sdk.MustNewDecFromStr("0.05"), stakingtypes.Infraction_INFRACTION_DOWNTIME) + math.LegacyMustNewDecFromStr("0.05"), stakingtypes.Infraction_INFRACTION_DOWNTIME) } // Tests the getter and setter behavior for historical info @@ -214,7 +220,7 @@ func TestHistoricalInfo(t *testing.T) { pk, err := v.ConsPubKey() require.NoError(t, err) - val, err := stakingtypes.NewValidator(nil, pk, stakingtypes.Description{}) + val, err := stakingtypes.NewValidator("", pk, stakingtypes.Description{}) require.NoError(t, err) // set voting power to random value @@ -224,13 +230,17 @@ func TestHistoricalInfo(t *testing.T) { currentHeight := ctx.BlockHeight() + validatorsWithCodec := stakingtypes.Validators{ + Validators: sVals, + ValidatorCodec: consumerKeeper.ValidatorAddressCodec(), + } // create and store historical info - hi := stakingtypes.NewHistoricalInfo(ctx.BlockHeader(), sVals, sdk.DefaultPowerReduction) + hi := stakingtypes.NewHistoricalInfo(ctx.BlockHeader(), validatorsWithCodec, sdk.DefaultPowerReduction) consumerKeeper.SetHistoricalInfo(ctx, currentHeight, &hi) // expect to get historical info - recv, found := consumerKeeper.GetHistoricalInfo(ctx, currentHeight) - require.True(t, found, "HistoricalInfo not found after set") + recv, err := consumerKeeper.GetHistoricalInfo(ctx, currentHeight) + require.NoError(t, err, "HistoricalInfo not found after set") require.Equal(t, hi, recv, "HistoricalInfo not equal") // verify that historical info valset has validators sorted in order diff --git a/x/ccv/consumer/migrations/v2/migration.go b/x/ccv/consumer/migrations/v2/migration.go index 80f06d4d71..a0b401188d 100644 --- a/x/ccv/consumer/migrations/v2/migration.go +++ b/x/ccv/consumer/migrations/v2/migration.go @@ -3,11 +3,11 @@ package v2 import ( "fmt" - storetypes "github.com/cosmos/cosmos-sdk/store/types" + storetypes "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // MigrateConsumerPacketData migrates consumer packet data according to diff --git a/x/ccv/consumer/migrations/v2/migration_test.go b/x/ccv/consumer/migrations/v2/migration_test.go index 5df453d7cf..0b3f24ec75 100644 --- a/x/ccv/consumer/migrations/v2/migration_test.go +++ b/x/ccv/consumer/migrations/v2/migration_test.go @@ -6,12 +6,12 @@ import ( "github.com/stretchr/testify/require" - storetypes "github.com/cosmos/cosmos-sdk/store/types" + storetypes "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - testutil "github.com/cosmos/interchain-security/v4/testutil/keeper" - v2 "github.com/cosmos/interchain-security/v4/x/ccv/consumer/migrations/v2" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + testutil "github.com/cosmos/interchain-security/v5/testutil/keeper" + v2 "github.com/cosmos/interchain-security/v5/x/ccv/consumer/migrations/v2" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) func TestMigrateConsumerPacketData(t *testing.T) { diff --git a/x/ccv/consumer/migrations/v3/migration.go b/x/ccv/consumer/migrations/v3/migration.go new file mode 100644 index 0000000000..aa2bd21b3a --- /dev/null +++ b/x/ccv/consumer/migrations/v3/migration.go @@ -0,0 +1,22 @@ +package v3 + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + + consumerKeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" +) + +// MigrateParams migrates the consumers module's parameters from the x/params subspace to the +// consumer modules store. +func MigrateParams(ctx sdk.Context, keeper consumerKeeper.Keeper, legacyParamspace paramtypes.Subspace) error { + params := consumerKeeper.GetConsumerParamsLegacy(ctx, keeper, legacyParamspace) + err := params.Validate() + if err != nil { + return err + } + keeper.SetParams(ctx, params) + keeper.Logger(ctx).Info("successfully migrated provider parameters") + return nil +} diff --git a/x/ccv/consumer/module.go b/x/ccv/consumer/module.go index 4b5d9c053b..1f384d39a3 100644 --- a/x/ccv/consumer/module.go +++ b/x/ccv/consumer/module.go @@ -5,7 +5,7 @@ import ( "encoding/json" "fmt" - porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + "cosmossdk.io/core/appmodule" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" @@ -19,16 +19,24 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/client/cli" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/client/cli" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) var ( - _ module.AppModule = AppModule{} - _ porttypes.IBCModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} + _ module.AppModule = (*AppModule)(nil) + _ module.AppModuleBasic = (*AppModuleBasic)(nil) + _ module.AppModuleSimulation = (*AppModule)(nil) + _ module.HasABCIGenesis = (*AppModule)(nil) + _ module.HasABCIEndBlock = (*AppModule)(nil) + _ module.HasName = (*AppModule)(nil) + _ module.HasConsensusVersion = (*AppModule)(nil) + _ module.HasInvariants = (*AppModule)(nil) + _ module.HasServices = (*AppModule)(nil) + _ appmodule.AppModule = (*AppModule)(nil) + _ appmodule.HasBeginBlocker = (*AppModule)(nil) ) // AppModuleBasic is the IBC Consumer AppModuleBasic @@ -49,6 +57,12 @@ func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) // ccv.RegisterInterfaces(registry) } +// IsAppModule implements the appmodule.AppModule interface. +func (AppModule) IsAppModule() {} + +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (AppModule) IsOnePerModuleType() {} + // DefaultGenesis returns default genesis state as raw bytes for the ibc // consumer module. func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { @@ -137,7 +151,9 @@ func (AppModule) ConsensusVersion() uint64 { // BeginBlock implements the AppModule interface // Set the VSC ID for the subsequent block to the same value as the current block // Panic if the provider's channel was established and then closed -func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { +func (am AppModule) BeginBlock(goCtx context.Context) error { + ctx := sdk.UnwrapSDKContext(goCtx) + // Execute BeginBlock logic for the Soft Opt-Out sub-protocol am.keeper.BeginBlockSoftOptOut(ctx) @@ -156,18 +172,21 @@ func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { am.keeper.Logger(ctx).Debug("block height was mapped to vscID", "height", blockHeight+1, "vscID", vID) am.keeper.TrackHistoricalInfo(ctx) + return nil } // EndBlock implements the AppModule interface // Flush PendingChanges to ABCI, send pending packets, write acknowledgements for packets that have finished unbonding. // // TODO: e2e tests confirming behavior with and without standalone -> consumer changeover -func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { +func (am AppModule) EndBlock(goCtx context.Context) ([]abci.ValidatorUpdate, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + // If PreCCV state is active, consumer is a previously standalone chain // that was just upgraded to include the consumer ccv module, execute changeover logic. if am.keeper.IsPreCCV(ctx) { initialValUpdates := am.keeper.ChangeoverToConsumer(ctx) - return initialValUpdates + return initialValUpdates, nil } // Execute EndBlock logic for the Reward Distribution sub-protocol @@ -182,7 +201,7 @@ func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.V data, ok := am.keeper.GetPendingChanges(ctx) if !ok { - return []abci.ValidatorUpdate{} + return []abci.ValidatorUpdate{}, nil } // apply changes to cross-chain validator set tendermintUpdates := am.keeper.ApplyCCValidatorChanges(ctx, data.ValidatorUpdates) @@ -190,7 +209,7 @@ func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.V am.keeper.Logger(ctx).Debug("sending validator updates to consensus engine", "len updates", len(tendermintUpdates)) - return tendermintUpdates + return tendermintUpdates, nil } // AppModuleSimulation functions @@ -202,7 +221,7 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) { // RegisterStoreDecoder registers a decoder for consumer module's types // TODO -func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { +func (am AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) { } // WeightedOperations returns the all the consumer module operations with their respective weights. diff --git a/x/ccv/consumer/types/consumer.pb.go b/x/ccv/consumer/types/consumer.pb.go index ab52b3a8a7..6df35dd174 100644 --- a/x/ccv/consumer/types/consumer.pb.go +++ b/x/ccv/consumer/types/consumer.pb.go @@ -173,31 +173,31 @@ var fileDescriptor_5b27a82b276e7f93 = []byte{ // 434 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0xcd, 0x6e, 0xd3, 0x40, 0x10, 0xce, 0x52, 0x28, 0xee, 0x06, 0x21, 0x64, 0x22, 0xe1, 0x06, 0xc9, 0x89, 0xcc, 0xc5, 0x97, - 0xda, 0x6a, 0xca, 0x09, 0x89, 0x43, 0xd3, 0x23, 0x87, 0x22, 0x83, 0x40, 0xe2, 0x62, 0xad, 0xd7, - 0x8b, 0x63, 0x61, 0xef, 0xac, 0xf6, 0xc7, 0x65, 0x79, 0x8a, 0x3e, 0x0c, 0xaf, 0x80, 0x54, 0x71, - 0xea, 0x91, 0x53, 0x41, 0xc9, 0x1b, 0xf0, 0x04, 0xc8, 0x3f, 0x09, 0xe2, 0xe7, 0x36, 0xf3, 0xcd, - 0x7e, 0x33, 0xdf, 0xcc, 0x7e, 0x78, 0x51, 0x72, 0xcd, 0x24, 0x5d, 0x91, 0x92, 0xa7, 0x8a, 0x51, - 0x23, 0x4b, 0x6d, 0x63, 0x4a, 0x9b, 0x98, 0x02, 0x57, 0xa6, 0x66, 0x32, 0x6e, 0x8e, 0x77, 0x71, - 0x24, 0x24, 0x68, 0x70, 0x9f, 0xfc, 0x87, 0x13, 0x51, 0xda, 0x44, 0xbb, 0x77, 0xcd, 0xf1, 0xf4, - 0xb0, 0x00, 0x28, 0x2a, 0x16, 0x77, 0x94, 0xcc, 0xbc, 0x8f, 0x09, 0xb7, 0x3d, 0x7f, 0x3a, 0x29, - 0xa0, 0x80, 0x2e, 0x8c, 0xdb, 0x68, 0x40, 0x0f, 0x29, 0xa8, 0x1a, 0x54, 0xda, 0x17, 0xfa, 0x64, - 0x28, 0xcd, 0xfe, 0xee, 0xa5, 0xcb, 0x9a, 0x29, 0x4d, 0x6a, 0xd1, 0x3f, 0x08, 0xbe, 0x20, 0xfc, - 0xf0, 0x4c, 0x82, 0x52, 0x67, 0xad, 0xa8, 0x37, 0xa4, 0x2a, 0x73, 0xa2, 0x41, 0xba, 0x1e, 0xbe, - 0x4b, 0xf2, 0x5c, 0x32, 0xa5, 0x3c, 0x34, 0x47, 0xe1, 0xbd, 0x64, 0x9b, 0xba, 0x13, 0x7c, 0x47, - 0xc0, 0x05, 0x93, 0xde, 0xad, 0x39, 0x0a, 0xf7, 0x92, 0x3e, 0x71, 0x09, 0xde, 0x17, 0x26, 0xfb, - 0xc0, 0xac, 0xb7, 0x37, 0x47, 0xe1, 0x78, 0x31, 0x89, 0xfa, 0xc9, 0xd1, 0x76, 0x72, 0x74, 0xca, - 0xed, 0xf2, 0xe4, 0xe7, 0xcd, 0xec, 0x91, 0x25, 0x75, 0xf5, 0x2c, 0x68, 0x37, 0x66, 0x5c, 0x19, - 0x95, 0xf6, 0xbc, 0xe0, 0xeb, 0xe7, 0xa3, 0xc9, 0xa0, 0x9d, 0x4a, 0x2b, 0x34, 0x44, 0x2f, 0x4d, - 0xf6, 0x82, 0xd9, 0x64, 0x68, 0xec, 0x3e, 0xc6, 0x07, 0x20, 0x34, 0xcb, 0x53, 0x30, 0xda, 0xbb, - 0x3d, 0x47, 0xa1, 0x93, 0x38, 0x1d, 0x70, 0x6e, 0x74, 0xf0, 0x09, 0x8f, 0x5f, 0x55, 0x44, 0xad, - 0x12, 0x46, 0x41, 0xe6, 0x6e, 0x88, 0x1f, 0x5c, 0x90, 0x52, 0x97, 0xbc, 0x48, 0x81, 0xa7, 0x92, - 0x89, 0xca, 0x76, 0x7b, 0x38, 0xc9, 0xfd, 0x01, 0x3f, 0xe7, 0x49, 0x8b, 0xba, 0xa7, 0xf8, 0x40, - 0x31, 0x9e, 0xa7, 0xed, 0x61, 0xba, 0x95, 0xc6, 0x8b, 0xe9, 0x3f, 0xda, 0x5f, 0x6f, 0xaf, 0xb6, - 0x74, 0xae, 0x6e, 0x66, 0xa3, 0xcb, 0xef, 0x33, 0x94, 0x38, 0x2d, 0xad, 0x2d, 0x2c, 0xdf, 0x5e, - 0xad, 0x7d, 0x74, 0xbd, 0xf6, 0xd1, 0x8f, 0xb5, 0x8f, 0x2e, 0x37, 0xfe, 0xe8, 0x7a, 0xe3, 0x8f, - 0xbe, 0x6d, 0xfc, 0xd1, 0xbb, 0xe7, 0x45, 0xa9, 0x57, 0x26, 0x8b, 0x28, 0xd4, 0xc3, 0xbf, 0xc4, - 0xbf, 0x1d, 0x70, 0xb4, 0x73, 0x4d, 0xf3, 0x34, 0xfe, 0xf8, 0xa7, 0x75, 0xb4, 0x15, 0x4c, 0x65, - 0xfb, 0x9d, 0x80, 0x93, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x20, 0xf1, 0xa5, 0x1e, 0x6b, 0x02, + 0xda, 0x6a, 0x2a, 0x2e, 0x48, 0x1c, 0x9a, 0x1e, 0x39, 0x14, 0x19, 0x04, 0x12, 0x17, 0x6b, 0xbd, + 0x5e, 0x1c, 0x0b, 0x7b, 0x67, 0xb5, 0x3f, 0x2e, 0xcb, 0x53, 0xf4, 0x61, 0x78, 0x05, 0xa4, 0x8a, + 0x53, 0x8f, 0x9c, 0x0a, 0x4a, 0xde, 0x80, 0x27, 0x40, 0xfe, 0x49, 0x10, 0x3f, 0xb7, 0x99, 0x6f, + 0xf6, 0x9b, 0xf9, 0x66, 0xf6, 0xc3, 0x8b, 0x92, 0x6b, 0x26, 0xe9, 0x8a, 0x94, 0x3c, 0x55, 0x8c, + 0x1a, 0x59, 0x6a, 0x1b, 0x53, 0xda, 0xc4, 0x14, 0xb8, 0x32, 0x35, 0x93, 0x71, 0x73, 0xbc, 0x8b, + 0x23, 0x21, 0x41, 0x83, 0xfb, 0xe4, 0x3f, 0x9c, 0x88, 0xd2, 0x26, 0xda, 0xbd, 0x6b, 0x8e, 0xa7, + 0x87, 0x05, 0x40, 0x51, 0xb1, 0xb8, 0xa3, 0x64, 0xe6, 0x7d, 0x4c, 0xb8, 0xed, 0xf9, 0xd3, 0x49, + 0x01, 0x05, 0x74, 0x61, 0xdc, 0x46, 0x03, 0x7a, 0x48, 0x41, 0xd5, 0xa0, 0xd2, 0xbe, 0xd0, 0x27, + 0x43, 0x69, 0xf6, 0x77, 0x2f, 0x5d, 0xd6, 0x4c, 0x69, 0x52, 0x8b, 0xfe, 0x41, 0xf0, 0x05, 0xe1, + 0x87, 0x67, 0x12, 0x94, 0x3a, 0x6b, 0x45, 0xbd, 0x21, 0x55, 0x99, 0x13, 0x0d, 0xd2, 0xf5, 0xf0, + 0x5d, 0x92, 0xe7, 0x92, 0x29, 0xe5, 0xa1, 0x39, 0x0a, 0xef, 0x25, 0xdb, 0xd4, 0x9d, 0xe0, 0x3b, + 0x02, 0x2e, 0x98, 0xf4, 0x6e, 0xcd, 0x51, 0xb8, 0x97, 0xf4, 0x89, 0x4b, 0xf0, 0xbe, 0x30, 0xd9, + 0x07, 0x66, 0xbd, 0xbd, 0x39, 0x0a, 0xc7, 0x8b, 0x49, 0xd4, 0x4f, 0x8e, 0xb6, 0x93, 0xa3, 0x53, + 0x6e, 0x97, 0x27, 0x3f, 0x6f, 0x66, 0x8f, 0x2c, 0xa9, 0xab, 0x67, 0x41, 0xbb, 0x31, 0xe3, 0xca, + 0xa8, 0xb4, 0xe7, 0x05, 0x5f, 0x3f, 0x1f, 0x4d, 0x06, 0xed, 0x54, 0x5a, 0xa1, 0x21, 0x7a, 0x69, + 0xb2, 0x17, 0xcc, 0x26, 0x43, 0x63, 0xf7, 0x31, 0x3e, 0x00, 0xa1, 0x59, 0x9e, 0x82, 0xd1, 0xde, + 0xed, 0x39, 0x0a, 0x9d, 0xc4, 0xe9, 0x80, 0x73, 0xa3, 0x83, 0x4f, 0x78, 0xfc, 0xaa, 0x22, 0x6a, + 0x95, 0x30, 0x0a, 0x32, 0x77, 0x43, 0xfc, 0xe0, 0x82, 0x94, 0xba, 0xe4, 0x45, 0x0a, 0x3c, 0x95, + 0x4c, 0x54, 0xb6, 0xdb, 0xc3, 0x49, 0xee, 0x0f, 0xf8, 0x39, 0x4f, 0x5a, 0xd4, 0x3d, 0xc5, 0x07, + 0x8a, 0xf1, 0x3c, 0x6d, 0x0f, 0xd3, 0xad, 0x34, 0x5e, 0x4c, 0xff, 0xd1, 0xfe, 0x7a, 0x7b, 0xb5, + 0xa5, 0x73, 0x75, 0x33, 0x1b, 0x5d, 0x7e, 0x9f, 0xa1, 0xc4, 0x69, 0x69, 0x6d, 0x61, 0xf9, 0xf6, + 0x6a, 0xed, 0xa3, 0xeb, 0xb5, 0x8f, 0x7e, 0xac, 0x7d, 0x74, 0xb9, 0xf1, 0x47, 0xd7, 0x1b, 0x7f, + 0xf4, 0x6d, 0xe3, 0x8f, 0xde, 0x3d, 0x2f, 0x4a, 0xbd, 0x32, 0x59, 0x44, 0xa1, 0x1e, 0xfe, 0x25, + 0xfe, 0xed, 0x80, 0xa3, 0x9d, 0x6b, 0x9a, 0xa7, 0xf1, 0xc7, 0x3f, 0xad, 0xa3, 0xad, 0x60, 0x2a, + 0xdb, 0xef, 0x04, 0x9c, 0xfc, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x28, 0x12, 0xc5, 0x22, 0x6b, 0x02, 0x00, 0x00, } diff --git a/x/ccv/consumer/types/genesis.go b/x/ccv/consumer/types/genesis.go index cb9cb61f40..b75de5d46d 100644 --- a/x/ccv/consumer/types/genesis.go +++ b/x/ccv/consumer/types/genesis.go @@ -1,13 +1,13 @@ package types import ( - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" errorsmod "cosmossdk.io/errors" abci "github.com/cometbft/cometbft/abci/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // NewRestartGenesisState returns a consumer GenesisState that has already been established. diff --git a/x/ccv/consumer/types/genesis.pb.go b/x/ccv/consumer/types/genesis.pb.go index dbb7c51981..8b86b0b34c 100644 --- a/x/ccv/consumer/types/genesis.pb.go +++ b/x/ccv/consumer/types/genesis.pb.go @@ -9,8 +9,8 @@ import ( _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" - _07_tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - types "github.com/cosmos/interchain-security/v4/x/ccv/types" + _07_tendermint "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + types "github.com/cosmos/interchain-security/v5/x/ccv/types" _ "google.golang.org/protobuf/types/known/timestamppb" io "io" math "math" @@ -466,61 +466,61 @@ var fileDescriptor_2db73a6057a27482 = []byte{ // 912 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcf, 0x6f, 0x23, 0x35, 0x14, 0xee, 0xb4, 0xdd, 0x90, 0xb8, 0xed, 0x6e, 0xd7, 0x5d, 0xa2, 0xa1, 0x11, 0x69, 0x14, 0x84, - 0x14, 0xf1, 0xc3, 0x43, 0xca, 0x0f, 0x21, 0x21, 0x10, 0x24, 0x95, 0x68, 0x50, 0x11, 0x55, 0xda, + 0x14, 0xf1, 0xc3, 0x43, 0x8a, 0x16, 0x21, 0x21, 0x10, 0x24, 0x95, 0x68, 0x50, 0x11, 0x55, 0xda, 0x0d, 0xd2, 0x5e, 0x46, 0x8e, 0xc7, 0x3b, 0xb1, 0x76, 0xc6, 0x1e, 0x8d, 0x9d, 0x09, 0x15, 0xe2, 0xc2, 0x95, 0xcb, 0xfe, 0x59, 0x7b, 0xdc, 0x03, 0x07, 0x4e, 0x80, 0xda, 0x7f, 0x04, 0xd9, 0xe3, 0x99, 0x24, 0x34, 0xed, 0xe6, 0x16, 0xcf, 0x7b, 0xef, 0xfb, 0xde, 0xfb, 0xde, 0x7b, 0x76, 0x40, 0x97, 0x71, 0x45, 0x53, 0x32, 0xc1, 0x8c, 0xfb, 0x92, 0x92, 0x69, 0xca, 0xd4, 0x95, 0x47, 0x48, 0xe6, 0x11, 0xc1, 0xe5, 0x34, 0xa6, 0xa9, 0x97, 0x75, 0xbd, 0x90, 0x72, 0x2a, 0x99, 0x44, 0x49, - 0x2a, 0x94, 0x80, 0xef, 0xad, 0x08, 0x41, 0x84, 0x64, 0xa8, 0x08, 0x41, 0x59, 0xf7, 0xf0, 0x93, + 0x2a, 0x94, 0x80, 0x1f, 0xac, 0x08, 0x41, 0x84, 0x64, 0xa8, 0x08, 0x41, 0x59, 0xf7, 0xf0, 0xb3, 0xbb, 0x70, 0xb3, 0xae, 0x27, 0x27, 0x38, 0xa5, 0x81, 0x5f, 0xba, 0x1b, 0xd8, 0x43, 0x8f, 0x8d, 0x89, 0x17, 0xb1, 0x70, 0xa2, 0x48, 0xc4, 0x28, 0x57, 0xd2, 0x53, 0x94, 0x07, 0x34, 0x8d, 0x19, 0x57, 0x3a, 0x6a, 0x7e, 0xb2, 0x01, 0x4f, 0x42, 0x11, 0x0a, 0xf3, 0xd3, 0xd3, 0xbf, 0xec, 0xd7, - 0xf7, 0xef, 0x21, 0x9e, 0xb1, 0x94, 0x5a, 0xb7, 0xa3, 0x50, 0x88, 0x30, 0xa2, 0x9e, 0x39, 0x8d, - 0xa7, 0xcf, 0x3d, 0xc5, 0x62, 0x2a, 0x15, 0x8e, 0x13, 0xeb, 0xd0, 0x58, 0x60, 0xc7, 0x63, 0xc2, + 0x0f, 0xef, 0x21, 0x9e, 0xb1, 0x94, 0x5a, 0xb7, 0xa3, 0x50, 0x88, 0x30, 0xa2, 0x9e, 0x39, 0x8d, + 0xa7, 0x2f, 0x3c, 0xc5, 0x62, 0x2a, 0x15, 0x8e, 0x13, 0xeb, 0xd0, 0x58, 0x60, 0xc7, 0x63, 0xc2, 0x3c, 0x75, 0x95, 0x50, 0x2b, 0x41, 0xfb, 0xcf, 0x1a, 0xd8, 0xfd, 0x3e, 0x17, 0xe5, 0x42, 0x61, - 0x45, 0xe1, 0x29, 0xa8, 0x24, 0x38, 0xc5, 0xb1, 0x74, 0x9d, 0x96, 0xd3, 0xd9, 0x39, 0xfe, 0x00, - 0xdd, 0x25, 0x52, 0xd6, 0x45, 0x7d, 0x5b, 0xf8, 0xb9, 0x89, 0xe8, 0x6d, 0xbf, 0xfa, 0xfb, 0x68, - 0x63, 0x68, 0xe3, 0xe1, 0x47, 0x00, 0x26, 0xa9, 0xc8, 0x58, 0x40, 0x53, 0x3f, 0x17, 0xc2, 0x67, + 0x45, 0xe1, 0x29, 0xa8, 0x24, 0x38, 0xc5, 0xb1, 0x74, 0x9d, 0x96, 0xd3, 0xd9, 0x39, 0xfe, 0x08, + 0xdd, 0x25, 0x52, 0xd6, 0x45, 0x7d, 0x5b, 0xf8, 0xb9, 0x89, 0xe8, 0x6d, 0xbf, 0xfe, 0xfb, 0x68, + 0x63, 0x68, 0xe3, 0xe1, 0x27, 0x00, 0x26, 0xa9, 0xc8, 0x58, 0x40, 0x53, 0x3f, 0x17, 0xc2, 0x67, 0x81, 0xbb, 0xd9, 0x72, 0x3a, 0xb5, 0xe1, 0x7e, 0x61, 0xe9, 0x1b, 0xc3, 0x20, 0x80, 0x08, 0x1c, 0xcc, 0xbd, 0x27, 0x98, 0x73, 0x1a, 0x69, 0xf7, 0x2d, 0xe3, 0xfe, 0xb8, 0x74, 0xcf, 0x2d, 0x83, 0x00, 0x36, 0x40, 0x8d, 0xd3, 0x99, 0x6f, 0xf2, 0x72, 0xb7, 0x5b, 0x4e, 0xa7, 0x3a, 0xac, 0x72, - 0x3a, 0xeb, 0xeb, 0x33, 0x24, 0xe0, 0xed, 0xff, 0x53, 0x4b, 0x5d, 0x9d, 0xfb, 0xc0, 0xd4, 0xf4, - 0x21, 0x62, 0x63, 0x82, 0x16, 0x3b, 0x84, 0x16, 0x7a, 0xa2, 0xeb, 0x32, 0x5f, 0x8d, 0x20, 0xbd, + 0x3a, 0xeb, 0xeb, 0x33, 0x24, 0xe0, 0xdd, 0xff, 0x53, 0x4b, 0x5d, 0x9d, 0xfb, 0xc0, 0xd4, 0xf4, + 0x31, 0x62, 0x63, 0x82, 0x16, 0x3b, 0x84, 0x16, 0x7a, 0xa2, 0xeb, 0x32, 0x5f, 0x8d, 0x20, 0xbd, 0x4d, 0xd7, 0x19, 0x1e, 0x2c, 0xa7, 0x9b, 0x2b, 0x15, 0x01, 0x77, 0x4e, 0x22, 0xb8, 0xa4, 0x5c, - 0x4e, 0xa5, 0xe5, 0xa9, 0x18, 0x1e, 0xf4, 0x46, 0x9e, 0x22, 0x6c, 0x4e, 0x55, 0x2f, 0xa9, 0x96, - 0x6c, 0x30, 0x04, 0xfb, 0x31, 0x56, 0xd3, 0x94, 0xf1, 0xd0, 0x4f, 0x30, 0x79, 0x41, 0x95, 0x74, - 0xdf, 0x6a, 0x6d, 0x75, 0x76, 0x8e, 0xbf, 0x40, 0x6b, 0x8c, 0x31, 0xfa, 0xd1, 0x06, 0x8f, 0x2e, + 0x4e, 0xa5, 0xe5, 0xa9, 0x18, 0x1e, 0xf4, 0x56, 0x9e, 0x22, 0x6c, 0x4e, 0x55, 0x2f, 0xa9, 0x96, + 0x6c, 0x30, 0x04, 0xfb, 0x31, 0x56, 0xd3, 0x94, 0xf1, 0xd0, 0x4f, 0x30, 0x79, 0x49, 0x95, 0x74, + 0xdf, 0x69, 0x6d, 0x75, 0x76, 0x8e, 0xbf, 0x40, 0x6b, 0x8c, 0x31, 0xfa, 0xd1, 0x06, 0x8f, 0x2e, 0xfa, 0xe7, 0x26, 0xdc, 0x76, 0xeb, 0x51, 0x81, 0x9a, 0x7f, 0x95, 0xf0, 0x1c, 0x3c, 0x62, 0x9c, 0x29, 0x86, 0x23, 0x3f, 0xc3, 0x91, 0x2f, 0xa9, 0x72, 0xab, 0x86, 0xa7, 0xb5, 0x98, 0xbc, 0x1e, - 0x24, 0x34, 0xc2, 0x11, 0x0b, 0xb0, 0x12, 0xe9, 0xd3, 0x24, 0xd0, 0xf9, 0x57, 0x34, 0xa2, 0xeb, + 0x24, 0x34, 0xc2, 0x11, 0x0b, 0xb0, 0x12, 0xe9, 0xb3, 0x24, 0xd0, 0xf9, 0x57, 0x34, 0xa2, 0xeb, 0x0c, 0xf7, 0x2c, 0xc0, 0x08, 0x47, 0x17, 0x54, 0xc1, 0xdf, 0xc0, 0xe1, 0x84, 0x6a, 0x11, 0x7c, 0x25, 0x34, 0xa6, 0xa4, 0xca, 0x9f, 0x9a, 0x08, 0xdd, 0xe1, 0x9a, 0x01, 0xff, 0x6a, 0xad, 0x22, 0x4e, 0x0d, 0xcc, 0xa5, 0x18, 0x19, 0x90, 0x9c, 0x75, 0x70, 0x62, 0x2b, 0xa9, 0x4f, 0x56, 0x59, - 0x03, 0xf8, 0xbb, 0x03, 0xde, 0x15, 0x53, 0x25, 0x15, 0xe6, 0x81, 0x56, 0x2f, 0x10, 0x33, 0xae, + 0x03, 0xf8, 0xbb, 0x03, 0xde, 0x17, 0x53, 0x25, 0x15, 0xe6, 0x81, 0x56, 0x2f, 0x10, 0x33, 0xae, 0x77, 0xc4, 0x97, 0x11, 0x96, 0x13, 0xc6, 0x43, 0x17, 0x98, 0x14, 0xbe, 0x5c, 0x2b, 0x85, 0x9f, 0xe6, 0x48, 0x27, 0x16, 0xc8, 0xf2, 0x37, 0xc4, 0x6d, 0xd3, 0x85, 0xa5, 0x80, 0xbf, 0x02, 0x37, 0xa1, 0x39, 0x7f, 0x81, 0x56, 0xb6, 0x71, 0xc7, 0x0c, 0xcb, 0x7a, 0x0a, 0xcc, 0x37, 0x4e, 0xc7, 0x9e, 0x60, 0x85, 0xcf, 0x98, 0x2c, 0x7a, 0x59, 0xb7, 0x14, 0xcb, 0x4e, 0x12, 0xfe, 0xe1, 0x80, 0x66, 0x84, 0xa5, 0xf2, 0x55, 0x8a, 0xb9, 0x8c, 0x99, 0x94, 0x4c, 0x70, 0x7f, 0x1c, 0x09, 0xf2, - 0xc2, 0xcf, 0x45, 0x73, 0x77, 0x4d, 0x0e, 0xdf, 0xae, 0x95, 0xc3, 0x19, 0x96, 0xea, 0x72, 0x01, + 0xd2, 0xcf, 0x45, 0x73, 0x77, 0x4d, 0x0e, 0xdf, 0xae, 0x95, 0xc3, 0x19, 0x96, 0xea, 0x72, 0x01, 0xa9, 0xa7, 0x81, 0xf2, 0xd6, 0x14, 0x52, 0x44, 0x77, 0xbb, 0xc0, 0x3a, 0xa8, 0x24, 0x29, 0xed, 0xf7, 0x47, 0xee, 0x9e, 0x59, 0x5b, 0x7b, 0x82, 0x3f, 0x80, 0x6a, 0x31, 0xfb, 0xee, 0x43, 0x93, - 0x4e, 0xe7, 0xbe, 0xbb, 0xe7, 0xdc, 0xfa, 0x0e, 0xf8, 0x73, 0x61, 0x69, 0xcb, 0xf8, 0xf6, 0x33, + 0x4e, 0xe7, 0xbe, 0xbb, 0xe7, 0xdc, 0xfa, 0x0e, 0xf8, 0x0b, 0x61, 0x69, 0xcb, 0xf8, 0xf6, 0x73, 0x50, 0x5f, 0x3d, 0x2b, 0x9a, 0xdd, 0x96, 0xac, 0xef, 0xb7, 0xed, 0xa1, 0x3d, 0xc1, 0x0e, 0xd8, - 0xbf, 0x35, 0x9a, 0x9b, 0xc6, 0xe3, 0x61, 0xb6, 0x34, 0x4f, 0xed, 0xa7, 0xe0, 0x60, 0xc5, 0x10, + 0xbf, 0x35, 0x9a, 0x9b, 0xc6, 0xe3, 0x61, 0xb6, 0x34, 0x4f, 0xed, 0x67, 0xe0, 0x60, 0xc5, 0x10, 0xc0, 0x6f, 0x40, 0x23, 0x2b, 0xf6, 0x61, 0xe1, 0x3e, 0xc0, 0x41, 0x90, 0x52, 0x99, 0xdf, 0xa6, - 0xb5, 0xe1, 0x3b, 0xa5, 0x4b, 0xb9, 0xde, 0xdf, 0xe5, 0x0e, 0xed, 0xcf, 0x41, 0xe3, 0xec, 0x7e, - 0xd5, 0x16, 0xf2, 0xde, 0x2a, 0xf2, 0x6e, 0x2b, 0xf0, 0xf8, 0xd6, 0x6a, 0xc3, 0x27, 0xe0, 0x41, - 0x26, 0xc9, 0x20, 0xb0, 0x35, 0xe6, 0x07, 0x38, 0x00, 0x7b, 0xf9, 0xb2, 0xab, 0x2b, 0x5f, 0xa7, - 0x6c, 0xea, 0xdb, 0x39, 0x3e, 0x44, 0xf9, 0x0b, 0x82, 0x8a, 0x17, 0x04, 0x5d, 0x16, 0x2f, 0x48, - 0xaf, 0xaa, 0x75, 0x7d, 0xf9, 0xcf, 0x91, 0x33, 0xdc, 0x2d, 0x42, 0xb5, 0xb1, 0x3d, 0x06, 0xf5, - 0xd5, 0x93, 0x08, 0x4f, 0xc1, 0x76, 0xc4, 0xa4, 0xce, 0x72, 0x2b, 0xbf, 0x01, 0xd7, 0x79, 0x3d, - 0x0a, 0x04, 0xdb, 0x47, 0x83, 0xd0, 0xfb, 0xf9, 0xd5, 0x75, 0xd3, 0x79, 0x7d, 0xdd, 0x74, 0xfe, - 0xbd, 0x6e, 0x3a, 0x2f, 0x6f, 0x9a, 0x1b, 0xaf, 0x6f, 0x9a, 0x1b, 0x7f, 0xdd, 0x34, 0x37, 0x9e, - 0x7d, 0x1d, 0x32, 0x35, 0x99, 0x8e, 0x11, 0x11, 0xb1, 0x47, 0x84, 0x8c, 0x85, 0xf4, 0xe6, 0x34, - 0x1f, 0x97, 0x6f, 0x65, 0xf6, 0x99, 0xf7, 0xcb, 0xf2, 0x3f, 0x00, 0xf3, 0xf2, 0x8d, 0x2b, 0xa6, - 0xd0, 0x4f, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xf1, 0xa1, 0x41, 0x38, 0x32, 0x08, 0x00, 0x00, + 0xb5, 0xe1, 0x7b, 0xa5, 0x4b, 0xb9, 0xde, 0xdf, 0xe5, 0x0e, 0xed, 0xa7, 0xa0, 0x71, 0x76, 0xbf, + 0x6a, 0x0b, 0x79, 0x6f, 0x15, 0x79, 0xb7, 0x15, 0x78, 0x7c, 0x6b, 0xb5, 0xe1, 0x13, 0xf0, 0x20, + 0x93, 0x64, 0x10, 0xd8, 0x1a, 0xf3, 0x03, 0x1c, 0x80, 0xbd, 0x7c, 0xd9, 0xd5, 0x95, 0xaf, 0x53, + 0x36, 0xf5, 0xed, 0x1c, 0x1f, 0xa2, 0xfc, 0x05, 0x41, 0xc5, 0x0b, 0x82, 0x2e, 0x8b, 0x17, 0xa4, + 0x57, 0xd5, 0xba, 0xbe, 0xfa, 0xe7, 0xc8, 0x19, 0xee, 0x16, 0xa1, 0xda, 0xd8, 0x1e, 0x83, 0xfa, + 0xea, 0x49, 0x84, 0xa7, 0x60, 0x3b, 0x62, 0x52, 0x67, 0xb9, 0x95, 0xdf, 0x80, 0xeb, 0xbc, 0x1e, + 0x05, 0x82, 0xed, 0xa3, 0x41, 0xe8, 0xfd, 0xfc, 0xfa, 0xba, 0xe9, 0xbc, 0xb9, 0x6e, 0x3a, 0xff, + 0x5e, 0x37, 0x9d, 0x57, 0x37, 0xcd, 0x8d, 0x37, 0x37, 0xcd, 0x8d, 0xbf, 0x6e, 0x9a, 0x1b, 0xcf, + 0xbf, 0x0e, 0x99, 0x9a, 0x4c, 0xc7, 0x88, 0x88, 0xd8, 0x23, 0x42, 0xc6, 0x42, 0x7a, 0x73, 0x9a, + 0x4f, 0xcb, 0xb7, 0x32, 0x7b, 0xea, 0xfd, 0xb2, 0xfc, 0x0f, 0xc0, 0xbc, 0x7c, 0xe3, 0x8a, 0x29, + 0xf4, 0xf3, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xf9, 0x42, 0x21, 0x04, 0x32, 0x08, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/x/ccv/consumer/types/genesis_test.go b/x/ccv/consumer/types/genesis_test.go index dcd30b642c..1efa8339c7 100644 --- a/x/ccv/consumer/types/genesis_test.go +++ b/x/ccv/consumer/types/genesis_test.go @@ -4,9 +4,9 @@ import ( "testing" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" @@ -15,9 +15,9 @@ import ( abci "github.com/cometbft/cometbft/abci/types" tmtypes "github.com/cometbft/cometbft/types" - "github.com/cosmos/interchain-security/v4/testutil/crypto" - "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/testutil/crypto" + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) const ( diff --git a/x/ccv/consumer/types/keys.go b/x/ccv/consumer/types/keys.go index 0292ca84c5..224b0beed1 100644 --- a/x/ccv/consumer/types/keys.go +++ b/x/ccv/consumer/types/keys.go @@ -6,7 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) const ( @@ -106,6 +106,9 @@ const ( // SlashRecordByteKey is the single byte key storing the consumer's slash record. SlashRecordByteKey + // ParametersKey is the single byte key for storing consumer's parameters. + ParametersByteKey + // NOTE: DO NOT ADD NEW BYTE PREFIXES HERE WITHOUT ADDING THEM TO getAllKeyPrefixes() IN keys_test.go ) @@ -113,6 +116,11 @@ const ( // Fully defined key func section // +// ParametersKey returns the key for the consumer parameters in the store +func ParametersKey() []byte { + return []byte{ParametersByteKey} +} + // PortKey returns the key to the port ID in the store func PortKey() []byte { return []byte{PortByteKey} diff --git a/x/ccv/consumer/types/keys_test.go b/x/ccv/consumer/types/keys_test.go index a8cebee284..e1fcbcf733 100644 --- a/x/ccv/consumer/types/keys_test.go +++ b/x/ccv/consumer/types/keys_test.go @@ -43,6 +43,7 @@ func getAllKeyPrefixes() []byte { PrevStandaloneChainByteKey, PendingPacketsIndexByteKey, SlashRecordByteKey, + ParametersByteKey, } } diff --git a/x/ccv/consumer/types/params_test.go b/x/ccv/consumer/types/params_test.go index 5b11b52d43..caff4db0b1 100644 --- a/x/ccv/consumer/types/params_test.go +++ b/x/ccv/consumer/types/params_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/require" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // Tests the validation of consumer params that happens at genesis diff --git a/x/ccv/consumer/types/query.pb.go b/x/ccv/consumer/types/query.pb.go index fe62a4217f..3276f98197 100644 --- a/x/ccv/consumer/types/query.pb.go +++ b/x/ccv/consumer/types/query.pb.go @@ -9,7 +9,7 @@ import ( _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" - types "github.com/cosmos/interchain-security/v4/x/ccv/types" + types "github.com/cosmos/interchain-security/v5/x/ccv/types" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -561,7 +561,7 @@ var fileDescriptor_f627751d3cc10225 = []byte{ // 826 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x6f, 0xe3, 0x44, 0x14, 0x8f, 0xd3, 0x36, 0xbb, 0x99, 0x2e, 0x42, 0x3b, 0x04, 0xc9, 0x78, 0x57, 0xa1, 0x32, 0x20, - 0xc2, 0x4a, 0xb1, 0x93, 0x2c, 0x52, 0x97, 0xc3, 0xb2, 0xa8, 0x0d, 0x55, 0x23, 0x01, 0x6a, 0xdd, + 0xc2, 0x4a, 0xb1, 0x93, 0xac, 0x50, 0x97, 0xc3, 0xb2, 0xa8, 0x0d, 0x55, 0x23, 0x01, 0x6a, 0xdd, 0x4a, 0x08, 0x2e, 0x66, 0x3a, 0x99, 0x26, 0x16, 0x89, 0xc7, 0x9d, 0x19, 0x9b, 0xf6, 0x86, 0xe0, 0x8e, 0x90, 0xf8, 0x26, 0x7c, 0x01, 0xae, 0x95, 0x38, 0x50, 0x89, 0x03, 0x70, 0x41, 0xa8, 0xe5, 0x43, 0x70, 0x44, 0x33, 0x1e, 0xa7, 0x4e, 0x9b, 0x26, 0x6e, 0xe1, 0xe6, 0x79, 0x7f, 0x7e, 0xef, @@ -610,7 +610,7 @@ var fileDescriptor_f627751d3cc10225 = []byte{ 0x7a, 0xe9, 0xec, 0xa2, 0x5e, 0xfa, 0xfd, 0xa2, 0x5e, 0xfa, 0xfc, 0xf9, 0x20, 0x10, 0xc3, 0xf8, 0xc0, 0xc1, 0x74, 0xec, 0x62, 0xca, 0xc7, 0x94, 0xe7, 0xc0, 0x9b, 0x13, 0xf0, 0xe4, 0x5d, 0xf7, 0xf8, 0x4a, 0x85, 0x93, 0x88, 0xf0, 0x83, 0x8a, 0xfa, 0x33, 0xf1, 0xf4, 0xdf, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x36, 0xbd, 0x78, 0x1c, 0x65, 0x09, 0x00, 0x00, + 0xff, 0xff, 0x3e, 0x5e, 0x18, 0x20, 0x65, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/ccv/democracy/distribution/module.go b/x/ccv/democracy/distribution/module.go index af35c86846..9e0bdacbb6 100644 --- a/x/ccv/democracy/distribution/module.go +++ b/x/ccv/democracy/distribution/module.go @@ -1,8 +1,11 @@ package distribution import ( + "context" "time" + "cosmossdk.io/core/appmodule" + "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" @@ -14,15 +17,16 @@ import ( stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - abci "github.com/cometbft/cometbft/abci/types" - - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" ) var ( _ module.AppModule = AppModule{} _ module.AppModuleBasic = AppModuleBasic{} _ module.AppModuleSimulation = AppModule{} + + _ appmodule.AppModule = AppModule{} + _ appmodule.HasBeginBlocker = AppModule{} ) // AppModule embeds the Cosmos SDK's x/distribution AppModuleBasic. @@ -60,22 +64,27 @@ func NewAppModule( } } -// BeginBlocker mirror functionality of cosmos-sdk/distribution BeginBlocker -// however it allocates no proposer reward -func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { +// BeginBlock implements HasBeginBlocker interface +// The cosmos-sdk/distribution BeginBlocker functionality is replicated here, +// however it no proposer awards are allocated. +func (am AppModule) BeginBlock(goCtx context.Context) error { + ctx := sdk.UnwrapSDKContext(goCtx) defer telemetry.ModuleMeasureSince(distrtypes.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker) // TODO this is Tendermint-dependent // ref https://github.com/cosmos/cosmos-sdk/issues/3095 if ctx.BlockHeight() > 1 { - am.AllocateTokens(ctx) + return am.AllocateTokens(ctx) } + + return nil } // AllocateTokens handles distribution of the collected fees +// NOTE: refactored to use collections (FeePool.Get instead of GetFeePool) for v47 -> v50 migration func (am AppModule) AllocateTokens( ctx sdk.Context, -) { +) error { // fetch and clear the collected fees for distribution, since this is // called in BeginBlock, collected fees will be from the previous block // (and distributed to the current representatives) @@ -86,31 +95,41 @@ func (am AppModule) AllocateTokens( // transfer collected fees to the distribution module account err := am.bankKeeper.SendCoinsFromModuleToModule(ctx, consumertypes.ConsumerRedistributeName, distrtypes.ModuleName, feesCollectedInt) if err != nil { - // same behavior as in the original x/distribution module of cosmos-sdk - panic(err) + return err } // temporary workaround to keep CanWithdrawInvariant happy // general discussions here: https://github.com/cosmos/cosmos-sdk/issues/2906#issuecomment-441867634 - feePool := am.keeper.GetFeePool(ctx) + feePool, err := am.keeper.FeePool.Get(ctx) + if err != nil { + return err + } vs := am.stakingKeeper.GetValidatorSet() - totalBondedTokens := vs.TotalBondedTokens(ctx) + totalBondedTokens, err := vs.TotalBondedTokens(ctx) + if err != nil { + return err + } if totalBondedTokens.IsZero() { feePool.CommunityPool = feePool.CommunityPool.Add(feesCollected...) - am.keeper.SetFeePool(ctx, feePool) - return + if err := am.keeper.FeePool.Set(ctx, feePool); err != nil { + return err + } + return nil } // calculate the fraction allocated to representatives by subtracting the community tax. // e.g. if community tax is 0.02, representatives fraction will be 0.98 (2% goes to the community pool and the rest to the representatives) remaining := feesCollected - communityTax := am.keeper.GetCommunityTax(ctx) - representativesFraction := sdk.OneDec().Sub(communityTax) + communityTax, err := am.keeper.GetCommunityTax(ctx) + if err != nil { + return err + } + representativesFraction := math.LegacyOneDec().Sub(communityTax) // allocate tokens proportionally to representatives voting power vs.IterateBondedValidatorsByPower(ctx, func(_ int64, validator stakingtypes.ValidatorI) bool { // we get this validator's percentage of the total power by dividing their tokens by the total bonded tokens - powerFraction := sdk.NewDecFromInt(validator.GetTokens()).QuoTruncate(sdk.NewDecFromInt(totalBondedTokens)) + powerFraction := math.LegacyNewDecFromInt(validator.GetTokens()).QuoTruncate(math.LegacyNewDecFromInt(totalBondedTokens)) // we truncate here again, which means that the reward will be slightly lower than it should be reward := feesCollected.MulDecTruncate(representativesFraction).MulDecTruncate(powerFraction) am.keeper.AllocateTokensToValidator(ctx, validator, reward) @@ -122,5 +141,9 @@ func (am AppModule) AllocateTokens( // allocate community funding // due to the 3 truncations above, remaining sent to the community pool will be slightly more than it should be. This is OK feePool.CommunityPool = feePool.CommunityPool.Add(remaining...) - am.keeper.SetFeePool(ctx, feePool) + if err := am.keeper.FeePool.Set(ctx, feePool); err != nil { + return err + } + + return nil } diff --git a/x/ccv/democracy/governance/module.go b/x/ccv/democracy/governance/module.go index 3922607766..c4bf930066 100644 --- a/x/ccv/democracy/governance/module.go +++ b/x/ccv/democracy/governance/module.go @@ -1,8 +1,12 @@ package governance import ( + "context" "fmt" + "time" + "cosmossdk.io/collections" + "cosmossdk.io/core/appmodule" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" @@ -11,8 +15,6 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - - abci "github.com/cometbft/cometbft/abci/types" ) const ( @@ -22,6 +24,8 @@ const ( var ( _ module.AppModule = AppModule{} _ module.AppModuleSimulation = AppModule{} + + _ appmodule.HasEndBlocker = AppModule{} ) // AppModule embeds the Cosmos SDK's x/governance AppModule @@ -56,15 +60,25 @@ func NewAppModule(cdc codec.Codec, } } -func (am AppModule) EndBlock(ctx sdk.Context, request abci.RequestEndBlock) []abci.ValidatorUpdate { - am.keeper.IterateActiveProposalsQueue(ctx, ctx.BlockHeader().Time, func(proposal govv1.Proposal) bool { - // if there are forbidden proposals in active proposals queue, refund deposit, delete votes for that proposal - // and delete proposal from all storages +func (am AppModule) EndBlock(c context.Context) error { + ctx := sdk.UnwrapSDKContext(c) + rng := collections.NewPrefixUntilPairRange[time.Time, uint64](ctx.BlockTime()) + keeper := am.keeper + // if there are forbidden proposals in active proposals queue, refund deposit, delete votes for that proposal + // and delete proposal from all storages + err := am.keeper.ActiveProposalsQueue.Walk(ctx, rng, func(key collections.Pair[time.Time, uint64], _ uint64) (bool, error) { + proposal, err := keeper.Proposals.Get(ctx, key.K2()) + if err != nil { + return false, err + } deleteForbiddenProposal(ctx, am, proposal) - return false + return false, nil }) - return am.AppModule.EndBlock(ctx, request) + if err != nil { + return err + } + return am.AppModule.EndBlock(ctx) } // isProposalWhitelisted checks whether a proposal is whitelisted diff --git a/x/ccv/democracy/staking/module.go b/x/ccv/democracy/staking/module.go index 3e176aaa2c..324320923b 100644 --- a/x/ccv/democracy/staking/module.go +++ b/x/ccv/democracy/staking/module.go @@ -1,6 +1,7 @@ package staking import ( + "context" "encoding/json" "github.com/cosmos/cosmos-sdk/codec" @@ -21,6 +22,9 @@ var ( _ module.AppModule = AppModule{} _ module.AppModuleBasic = AppModuleBasic{} _ module.AppModuleSimulation = AppModule{} + + _ module.HasABCIGenesis = AppModule{} + _ module.HasABCIEndBlock = AppModule{} ) // AppModule embeds the Cosmos SDK's x/staking AppModuleBasic. @@ -41,11 +45,11 @@ type AppModule struct { // NewAppModule creates a new AppModule object using the native x/staking module // AppModule constructor. -func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, ak types.AccountKeeper, bk types.BankKeeper, subspace exported.Subspace) AppModule { - stakingAppMod := staking.NewAppModule(cdc, &keeper, ak, bk, subspace) +func NewAppModule(cdc codec.Codec, keeper *keeper.Keeper, ak types.AccountKeeper, bk types.BankKeeper, subspace exported.Subspace) AppModule { + stakingAppMod := staking.NewAppModule(cdc, keeper, ak, bk, subspace) return AppModule{ AppModule: stakingAppMod, - keeper: keeper, + keeper: *keeper, accKeeper: ak, bankKeeper: bk, } @@ -78,7 +82,7 @@ func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json. // The ccv consumer Endblocker is ordered to run before the staking Endblocker, // so if PreCCV is true during one block, the ccv consumer Enblocker will return the proper validator updates, // the PreCCV flag will be toggled to false, and no validator updates should be returned by this method. -func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - _ = am.keeper.BlockValidatorUpdates(ctx) - return []abci.ValidatorUpdate{} +func (am AppModule) EndBlock(ctx context.Context) ([]abci.ValidatorUpdate, error) { + _, _ = am.keeper.BlockValidatorUpdates(ctx) + return []abci.ValidatorUpdate{}, nil } diff --git a/x/ccv/provider/client/cli/query.go b/x/ccv/provider/client/cli/query.go index f554ed6a8e..6779d2c00e 100644 --- a/x/ccv/provider/client/cli/query.go +++ b/x/ccv/provider/client/cli/query.go @@ -11,7 +11,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) // NewQueryCmd returns a root CLI command handler for all x/ccv/provider query commands. diff --git a/x/ccv/provider/client/cli/tx.go b/x/ccv/provider/client/cli/tx.go index 379e55a792..536145267b 100644 --- a/x/ccv/provider/client/cli/tx.go +++ b/x/ccv/provider/client/cli/tx.go @@ -6,7 +6,7 @@ import ( "os" "strings" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" @@ -18,7 +18,7 @@ import ( tmproto "github.com/cometbft/cometbft/proto/tendermint/types" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) // GetTxCmd returns the transaction commands for this module @@ -49,6 +49,7 @@ func NewAssignConsumerKeyCmd() *cobra.Command { return err } + signer := clientCtx.GetFromAddress().String() txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) if err != nil { return err @@ -57,7 +58,7 @@ func NewAssignConsumerKeyCmd() *cobra.Command { providerValAddr := clientCtx.GetFromAddress() - msg, err := types.NewMsgAssignConsumerKey(args[0], sdk.ValAddress(providerValAddr), args[1]) + msg, err := types.NewMsgAssignConsumerKey(args[0], sdk.ValAddress(providerValAddr), args[1], signer) if err != nil { return err } diff --git a/x/ccv/provider/client/legacy_proposal_handler.go b/x/ccv/provider/client/legacy_proposal_handler.go new file mode 100644 index 0000000000..7ac9198be2 --- /dev/null +++ b/x/ccv/provider/client/legacy_proposal_handler.go @@ -0,0 +1,215 @@ +package client + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govclient "github.com/cosmos/cosmos-sdk/x/gov/client" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" +) + +var ( + ConsumerAdditionProposalHandler = govclient.NewProposalHandler(SubmitConsumerAdditionPropTxCmd) + ConsumerRemovalProposalHandler = govclient.NewProposalHandler(SubmitConsumerRemovalProposalTxCmd) + ChangeRewardDenomsProposalHandler = govclient.NewProposalHandler(SubmitChangeRewardDenomsProposalTxCmd) +) + +// SubmitConsumerAdditionPropTxCmd returns a CLI command handler for submitting +// a consumer addition proposal via a transaction. +func SubmitConsumerAdditionPropTxCmd() *cobra.Command { + return &cobra.Command{ + Use: "consumer-addition [proposal-file]", + Args: cobra.ExactArgs(1), + Short: "Submit a consumer addition proposal", + Long: ` +Submit a consumer addition proposal along with an initial deposit. +The proposal details must be supplied via a JSON file. +Unbonding period, transfer timeout period and ccv timeout period should be provided as nanosecond time periods. + +Example: +$ tx gov submit-legacy-proposal consumer-addition --from= + +Where proposal.json contains: + +{ + "title": "Create the FooChain", + "summary": "Gonna be a great chain", + "chain_id": "foochain", + "initial_height": { + "revision_number": 2, + "revision_height": 3 + }, + "genesis_hash": "Z2VuZXNpcyBoYXNo", + "binary_hash": "YmluYXJ5IGhhc2g=", + "spawn_time": "2022-01-27T15:59:50.121607-08:00", + "blocks_per_distribution_transmission": 1000, + "consumer_redistribution_fraction": "0.75", + "distribution_transmission_channel": "", + "historical_entries": 10000, + "transfer_timeout_period": 3600000000000, + "ccv_timeout_period": 2419200000000000, + "unbonding_period": 1728000000000000, + "deposit": "10000stake" +} + `, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + proposal, err := ParseConsumerAdditionProposalJSON(args[0]) + if err != nil { + return err + } + + // do not fail for errors regarding the unbonding period, but just log a warning + CheckPropUnbondingPeriod(clientCtx, proposal.UnbondingPeriod) + + content := types.NewConsumerAdditionProposal( + proposal.Title, proposal.Summary, proposal.ChainId, proposal.InitialHeight, + proposal.GenesisHash, proposal.BinaryHash, proposal.SpawnTime, + proposal.ConsumerRedistributionFraction, proposal.BlocksPerDistributionTransmission, + proposal.DistributionTransmissionChannel, proposal.HistoricalEntries, + proposal.CcvTimeoutPeriod, proposal.TransferTimeoutPeriod, proposal.UnbondingPeriod) + + from := clientCtx.GetFromAddress() + + deposit, err := sdk.ParseCoinsNormalized(proposal.Deposit) + if err != nil { + return err + } + + msgContent, err := govv1.NewLegacyContent(content, authtypes.NewModuleAddress(govtypes.ModuleName).String()) + if err != nil { + return err + } + + msg, err := govv1.NewMsgSubmitProposal([]sdk.Msg{msgContent}, deposit, from.String(), "", content.GetTitle(), proposal.Summary, false) + if err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } +} + +// SubmitConsumerRemovalPropTxCmd returns a CLI command handler for submitting +// a consumer addition proposal via a transaction. +func SubmitConsumerRemovalProposalTxCmd() *cobra.Command { + return &cobra.Command{ + Use: "consumer-removal [proposal-file]", + Args: cobra.ExactArgs(1), + Short: "Submit a consumer chain removal proposal", + Long: ` +Submit a consumer chain removal proposal along with an initial deposit. +The proposal details must be supplied via a JSON file. + +Example: +$ tx gov submit-legacy-proposal consumer-removal --from= + +Where proposal.json contains: +{ + "title": "Stop the FooChain", + "summary": "It was a great chain", + "chain_id": "foochain", + "stop_time": "2022-01-27T15:59:50.121607-08:00", + "deposit": "10000stake" +} + `, RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + proposal, err := ParseConsumerRemovalProposalJSON(args[0]) + if err != nil { + return err + } + + content := types.NewConsumerRemovalProposal(proposal.Title, proposal.Summary, proposal.ChainId, proposal.StopTime) + from := clientCtx.GetFromAddress() + + msgContent, err := govv1.NewLegacyContent(content, authtypes.NewModuleAddress(govtypes.ModuleName).String()) + if err != nil { + return err + } + + deposit, err := sdk.ParseCoinsNormalized(proposal.Deposit) + if err != nil { + return err + } + + msg, err := govv1.NewMsgSubmitProposal([]sdk.Msg{msgContent}, deposit, from.String(), "", content.GetTitle(), proposal.Summary, false) + if err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } +} + +// SubmitChangeRewardDenomsProposalTxCmd returns a CLI command handler for submitting +// a change reward denoms proposal via a transaction. +func SubmitChangeRewardDenomsProposalTxCmd() *cobra.Command { + return &cobra.Command{ + Use: "change-reward-denoms [proposal-file]", + Args: cobra.ExactArgs(1), + Short: "Submit a change reward denoms proposal", + Long: `Submit an change reward denoms proposal with an initial deposit. + The proposal details must be supplied via a JSON file. + + Example: + $ tx gov submit-legacy-proposal change-reward-denoms --from= + + Where proposal.json contains: + { + "title": "Change reward denoms", + "summary": "Change reward denoms", + "denoms_to_add": ["untrn"], + "denoms_to_remove": ["stake"], + "deposit": "10000stake" + } + `, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + proposal, err := ParseChangeRewardDenomsProposalJSON(args[0]) + if err != nil { + return err + } + + content := types.NewChangeRewardDenomsProposal(proposal.Title, proposal.Summary, proposal.DenomsToAdd, proposal.DenomsToRemove) + + from := clientCtx.GetFromAddress() + + msgContent, err := govv1.NewLegacyContent(content, authtypes.NewModuleAddress(govtypes.ModuleName).String()) + if err != nil { + return err + } + + deposit, err := sdk.ParseCoinsNormalized(proposal.Deposit) + if err != nil { + return err + } + + msg, err := govv1.NewMsgSubmitProposal([]sdk.Msg{msgContent}, deposit, from.String(), "", content.GetTitle(), proposal.Summary, false) + if err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } +} diff --git a/x/ccv/provider/client/legacy_proposals.go b/x/ccv/provider/client/legacy_proposals.go new file mode 100644 index 0000000000..9493c0d8c6 --- /dev/null +++ b/x/ccv/provider/client/legacy_proposals.go @@ -0,0 +1,156 @@ +package client + +import ( + "context" + "encoding/json" + "fmt" + "os" + "path/filepath" + "time" + + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + + "github.com/cosmos/cosmos-sdk/client" + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" +) + +type ConsumerAdditionProposalJSON struct { + Title string `json:"title"` + Summary string `json:"summary"` + ChainId string `json:"chain_id"` + InitialHeight clienttypes.Height `json:"initial_height"` + GenesisHash []byte `json:"genesis_hash"` + BinaryHash []byte `json:"binary_hash"` + SpawnTime time.Time `json:"spawn_time"` + + ConsumerRedistributionFraction string `json:"consumer_redistribution_fraction"` + BlocksPerDistributionTransmission int64 `json:"blocks_per_distribution_transmission"` + DistributionTransmissionChannel string `json:"distribution_transmission_channel"` + HistoricalEntries int64 `json:"historical_entries"` + CcvTimeoutPeriod time.Duration `json:"ccv_timeout_period"` + TransferTimeoutPeriod time.Duration `json:"transfer_timeout_period"` + UnbondingPeriod time.Duration `json:"unbonding_period"` + + Deposit string `json:"deposit"` +} + +type ConsumerAdditionProposalReq struct { + Proposer sdk.AccAddress `json:"proposer"` + + Title string `json:"title"` + Description string `json:"description"` + ChainId string `json:"chainId"` + InitialHeight clienttypes.Height `json:"initialHeight"` + GenesisHash []byte `json:"genesisHash"` + BinaryHash []byte `json:"binaryHash"` + SpawnTime time.Time `json:"spawnTime"` + + ConsumerRedistributionFraction string `json:"consumer_redistribution_fraction"` + BlocksPerDistributionTransmission int64 `json:"blocks_per_distribution_transmission"` + DistributionTransmissionChannel string `json:"distribution_transmission_channel"` + HistoricalEntries int64 `json:"historical_entries"` + CcvTimeoutPeriod time.Duration `json:"ccv_timeout_period"` + TransferTimeoutPeriod time.Duration `json:"transfer_timeout_period"` + UnbondingPeriod time.Duration `json:"unbonding_period"` + + Deposit sdk.Coins `json:"deposit"` +} + +func ParseConsumerAdditionProposalJSON(proposalFile string) (ConsumerAdditionProposalJSON, error) { + proposal := ConsumerAdditionProposalJSON{} + + contents, err := os.ReadFile(filepath.Clean(proposalFile)) + if err != nil { + return proposal, err + } + + if err := json.Unmarshal(contents, &proposal); err != nil { + return proposal, err + } + + return proposal, nil +} + +type ConsumerRemovalProposalJSON struct { + Title string `json:"title"` + Summary string `json:"summary"` + ChainId string `json:"chain_id"` + StopTime time.Time `json:"stop_time"` + Deposit string `json:"deposit"` +} + +type ConsumerRemovalProposalReq struct { + Proposer sdk.AccAddress `json:"proposer"` + + Title string `json:"title"` + Description string `json:"description"` + ChainId string `json:"chainId"` + + StopTime time.Time `json:"stopTime"` + Deposit sdk.Coins `json:"deposit"` +} + +func ParseConsumerRemovalProposalJSON(proposalFile string) (ConsumerRemovalProposalJSON, error) { + proposal := ConsumerRemovalProposalJSON{} + + contents, err := os.ReadFile(filepath.Clean(proposalFile)) + if err != nil { + return proposal, err + } + + if err := json.Unmarshal(contents, &proposal); err != nil { + return proposal, err + } + + return proposal, nil +} + +type ChangeRewardDenomsProposalJSON struct { + Summary string `json:"summary"` + types.ChangeRewardDenomsProposal + Deposit string `json:"deposit"` +} + +type ChangeRewardDenomsProposalReq struct { + Proposer sdk.AccAddress `json:"proposer"` + types.ChangeRewardDenomsProposal + Deposit sdk.Coins `json:"deposit"` +} + +func ParseChangeRewardDenomsProposalJSON(proposalFile string) (ChangeRewardDenomsProposalJSON, error) { + proposal := ChangeRewardDenomsProposalJSON{} + + contents, err := os.ReadFile(filepath.Clean(proposalFile)) + if err != nil { + return proposal, err + } + if err := json.Unmarshal(contents, &proposal); err != nil { + return proposal, err + } + return proposal, nil +} + +func CheckPropUnbondingPeriod(clientCtx client.Context, propUnbondingPeriod time.Duration) { + queryClient := stakingtypes.NewQueryClient(clientCtx) + + res, err := queryClient.Params(context.Background(), &stakingtypes.QueryParamsRequest{}) + if err != nil { + fmt.Println(err.Error()) + return + } + + providerUnbondingTime := res.Params.UnbondingTime + + if providerUnbondingTime < propUnbondingPeriod { + fmt.Printf( + `consumer unbonding period is advised to be smaller than provider unbonding period, but is longer. +This is not a security risk, but will effectively lengthen the unbonding period on the provider. +consumer unbonding: %s +provider unbonding: %s`, + propUnbondingPeriod, + providerUnbondingTime) + } +} diff --git a/x/ccv/provider/client/proposal_handler.go b/x/ccv/provider/client/proposal_handler.go deleted file mode 100644 index fa74bb953e..0000000000 --- a/x/ccv/provider/client/proposal_handler.go +++ /dev/null @@ -1,442 +0,0 @@ -package client - -import ( - "context" - "encoding/json" - "fmt" - "os" - "path/filepath" - "time" - - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - "github.com/spf13/cobra" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/tx" - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - govclient "github.com/cosmos/cosmos-sdk/x/gov/client" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" -) - -var ( - ConsumerAdditionProposalHandler = govclient.NewProposalHandler(SubmitConsumerAdditionPropTxCmd) - ConsumerRemovalProposalHandler = govclient.NewProposalHandler(SubmitConsumerRemovalProposalTxCmd) - ChangeRewardDenomsProposalHandler = govclient.NewProposalHandler(SubmitChangeRewardDenomsProposalTxCmd) -) - -// SubmitConsumerAdditionPropTxCmd returns a CLI command handler for submitting -// a consumer addition proposal via a transaction. -func SubmitConsumerAdditionPropTxCmd() *cobra.Command { - return &cobra.Command{ - Use: "consumer-addition [proposal-file]", - Args: cobra.ExactArgs(1), - Short: "Submit a consumer addition proposal", - Long: ` -Submit a consumer addition proposal along with an initial deposit. -The proposal details must be supplied via a JSON file. -Unbonding period, transfer timeout period and ccv timeout period should be provided as nanosecond time periods. - -Example: -$ tx gov submit-legacy-proposal consumer-addition --from= - -Where proposal.json contains: - -{ - "title": "Create the FooChain", - "summary": "Gonna be a great chain", - "chain_id": "foochain", - "initial_height": { - "revision_number": 2, - "revision_height": 3 - }, - "genesis_hash": "Z2VuZXNpcyBoYXNo", - "binary_hash": "YmluYXJ5IGhhc2g=", - "spawn_time": "2022-01-27T15:59:50.121607-08:00", - "blocks_per_distribution_transmission": 1000, - "consumer_redistribution_fraction": "0.75", - "distribution_transmission_channel": "", - "historical_entries": 10000, - "transfer_timeout_period": 3600000000000, - "ccv_timeout_period": 2419200000000000, - "unbonding_period": 1728000000000000, - "deposit": "10000stake" -} - `, - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - proposal, err := ParseConsumerAdditionProposalJSON(args[0]) - if err != nil { - return err - } - - // do not fail for errors regarding the unbonding period, but just log a warning - CheckPropUnbondingPeriod(clientCtx, proposal.UnbondingPeriod) - - content := types.NewConsumerAdditionProposal( - proposal.Title, proposal.Summary, proposal.ChainId, proposal.InitialHeight, - proposal.GenesisHash, proposal.BinaryHash, proposal.SpawnTime, - proposal.ConsumerRedistributionFraction, proposal.BlocksPerDistributionTransmission, - proposal.DistributionTransmissionChannel, proposal.HistoricalEntries, - proposal.CcvTimeoutPeriod, proposal.TransferTimeoutPeriod, proposal.UnbondingPeriod) - - from := clientCtx.GetFromAddress() - - deposit, err := sdk.ParseCoinsNormalized(proposal.Deposit) - if err != nil { - return err - } - - msgContent, err := govv1.NewLegacyContent(content, authtypes.NewModuleAddress(govtypes.ModuleName).String()) - if err != nil { - return err - } - - msg, err := govv1.NewMsgSubmitProposal([]sdk.Msg{msgContent}, deposit, from.String(), "", content.GetTitle(), proposal.Summary) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) - }, - } -} - -// SubmitConsumerRemovalPropTxCmd returns a CLI command handler for submitting -// a consumer addition proposal via a transaction. -func SubmitConsumerRemovalProposalTxCmd() *cobra.Command { - return &cobra.Command{ - Use: "consumer-removal [proposal-file]", - Args: cobra.ExactArgs(1), - Short: "Submit a consumer chain removal proposal", - Long: ` -Submit a consumer chain removal proposal along with an initial deposit. -The proposal details must be supplied via a JSON file. - -Example: -$ tx gov submit-legacy-proposal consumer-removal --from= - -Where proposal.json contains: -{ - "title": "Stop the FooChain", - "summary": "It was a great chain", - "chain_id": "foochain", - "stop_time": "2022-01-27T15:59:50.121607-08:00", - "deposit": "10000stake" -} - `, RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - proposal, err := ParseConsumerRemovalProposalJSON(args[0]) - if err != nil { - return err - } - - content := types.NewConsumerRemovalProposal(proposal.Title, proposal.Summary, proposal.ChainId, proposal.StopTime) - from := clientCtx.GetFromAddress() - - msgContent, err := govv1.NewLegacyContent(content, authtypes.NewModuleAddress(govtypes.ModuleName).String()) - if err != nil { - return err - } - - deposit, err := sdk.ParseCoinsNormalized(proposal.Deposit) - if err != nil { - return err - } - - msg, err := govv1.NewMsgSubmitProposal([]sdk.Msg{msgContent}, deposit, from.String(), "", content.GetTitle(), proposal.Summary) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) - }, - } -} - -// SubmitChangeRewardDenomsProposalTxCmd returns a CLI command handler for submitting -// a change reward denoms proposal via a transaction. -func SubmitChangeRewardDenomsProposalTxCmd() *cobra.Command { - return &cobra.Command{ - Use: "change-reward-denoms [proposal-file]", - Args: cobra.ExactArgs(1), - Short: "Submit a change reward denoms proposal", - Long: `Submit an change reward denoms proposal with an initial deposit. - The proposal details must be supplied via a JSON file. - - Example: - $ tx gov submit-legacy-proposal change-reward-denoms --from= - - Where proposal.json contains: - { - "title": "Change reward denoms", - "summary": "Change reward denoms", - "denoms_to_add": ["untrn"], - "denoms_to_remove": ["stake"], - "deposit": "10000stake" - } - `, - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - proposal, err := ParseChangeRewardDenomsProposalJSON(args[0]) - if err != nil { - return err - } - - content := types.NewChangeRewardDenomsProposal(proposal.Title, proposal.Summary, proposal.DenomsToAdd, proposal.DenomsToRemove) - - from := clientCtx.GetFromAddress() - - msgContent, err := govv1.NewLegacyContent(content, authtypes.NewModuleAddress(govtypes.ModuleName).String()) - if err != nil { - return err - } - - deposit, err := sdk.ParseCoinsNormalized(proposal.Deposit) - if err != nil { - return err - } - - msg, err := govv1.NewMsgSubmitProposal([]sdk.Msg{msgContent}, deposit, from.String(), "", content.GetTitle(), proposal.Summary) - if err != nil { - return err - } - - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) - }, - } -} - -type ConsumerAdditionProposalJSON struct { - Title string `json:"title"` - Summary string `json:"summary"` - ChainId string `json:"chain_id"` - InitialHeight clienttypes.Height `json:"initial_height"` - GenesisHash []byte `json:"genesis_hash"` - BinaryHash []byte `json:"binary_hash"` - SpawnTime time.Time `json:"spawn_time"` - - ConsumerRedistributionFraction string `json:"consumer_redistribution_fraction"` - BlocksPerDistributionTransmission int64 `json:"blocks_per_distribution_transmission"` - DistributionTransmissionChannel string `json:"distribution_transmission_channel"` - HistoricalEntries int64 `json:"historical_entries"` - CcvTimeoutPeriod time.Duration `json:"ccv_timeout_period"` - TransferTimeoutPeriod time.Duration `json:"transfer_timeout_period"` - UnbondingPeriod time.Duration `json:"unbonding_period"` - - Deposit string `json:"deposit"` -} - -type ConsumerAdditionProposalReq struct { - Proposer sdk.AccAddress `json:"proposer"` - - Title string `json:"title"` - Description string `json:"description"` - ChainId string `json:"chainId"` - InitialHeight clienttypes.Height `json:"initialHeight"` - GenesisHash []byte `json:"genesisHash"` - BinaryHash []byte `json:"binaryHash"` - SpawnTime time.Time `json:"spawnTime"` - - ConsumerRedistributionFraction string `json:"consumer_redistribution_fraction"` - BlocksPerDistributionTransmission int64 `json:"blocks_per_distribution_transmission"` - DistributionTransmissionChannel string `json:"distribution_transmission_channel"` - HistoricalEntries int64 `json:"historical_entries"` - CcvTimeoutPeriod time.Duration `json:"ccv_timeout_period"` - TransferTimeoutPeriod time.Duration `json:"transfer_timeout_period"` - UnbondingPeriod time.Duration `json:"unbonding_period"` - - Deposit sdk.Coins `json:"deposit"` -} - -func ParseConsumerAdditionProposalJSON(proposalFile string) (ConsumerAdditionProposalJSON, error) { - proposal := ConsumerAdditionProposalJSON{} - - contents, err := os.ReadFile(filepath.Clean(proposalFile)) - if err != nil { - return proposal, err - } - - if err := json.Unmarshal(contents, &proposal); err != nil { - return proposal, err - } - - return proposal, nil -} - -type ConsumerRemovalProposalJSON struct { - Title string `json:"title"` - Summary string `json:"summary"` - ChainId string `json:"chain_id"` - StopTime time.Time `json:"stop_time"` - Deposit string `json:"deposit"` -} - -type ConsumerRemovalProposalReq struct { - Proposer sdk.AccAddress `json:"proposer"` - - Title string `json:"title"` - Description string `json:"description"` - ChainId string `json:"chainId"` - - StopTime time.Time `json:"stopTime"` - Deposit sdk.Coins `json:"deposit"` -} - -func ParseConsumerRemovalProposalJSON(proposalFile string) (ConsumerRemovalProposalJSON, error) { - proposal := ConsumerRemovalProposalJSON{} - - contents, err := os.ReadFile(filepath.Clean(proposalFile)) - if err != nil { - return proposal, err - } - - if err := json.Unmarshal(contents, &proposal); err != nil { - return proposal, err - } - - return proposal, nil -} - -type ChangeRewardDenomsProposalJSON struct { - Summary string `json:"summary"` - types.ChangeRewardDenomsProposal - Deposit string `json:"deposit"` -} - -type ChangeRewardDenomsProposalReq struct { - Proposer sdk.AccAddress `json:"proposer"` - types.ChangeRewardDenomsProposal - Deposit sdk.Coins `json:"deposit"` -} - -func ParseChangeRewardDenomsProposalJSON(proposalFile string) (ChangeRewardDenomsProposalJSON, error) { - proposal := ChangeRewardDenomsProposalJSON{} - - contents, err := os.ReadFile(filepath.Clean(proposalFile)) - if err != nil { - return proposal, err - } - if err := json.Unmarshal(contents, &proposal); err != nil { - return proposal, err - } - return proposal, nil -} - -func CheckPropUnbondingPeriod(clientCtx client.Context, propUnbondingPeriod time.Duration) { - queryClient := stakingtypes.NewQueryClient(clientCtx) - - res, err := queryClient.Params(context.Background(), &stakingtypes.QueryParamsRequest{}) - if err != nil { - fmt.Println(err.Error()) - return - } - - providerUnbondingTime := res.Params.UnbondingTime - - if providerUnbondingTime < propUnbondingPeriod { - fmt.Printf( - `consumer unbonding period is advised to be smaller than provider unbonding period, but is longer. -This is not a security risk, but will effectively lengthen the unbonding period on the provider. -consumer unbonding: %s -provider unbonding: %s`, - propUnbondingPeriod, - providerUnbondingTime) - } -} - -/* Proposal REST handlers: NOT NEEDED POST 47, BUT PLEASE CHECK THAT ALL FUNCTIONALITY EXISTS IN THE 47 VERSION. - -// ConsumerAdditionProposalRESTHandler returns a ProposalRESTHandler that exposes the consumer addition rest handler. -func ConsumerAdditionProposalRESTHandler(clientCtx client.Context) govrest.ProposalRESTHandler { - return govrest.ProposalRESTHandler{ - SubRoute: "consumer_addition", - Handler: postConsumerAdditionProposalHandlerFn(clientCtx), - } -} - -// ConsumerRemovalProposalRESTHandler returns a ProposalRESTHandler that exposes the consumer removal rest handler. -func ConsumerRemovalProposalRESTHandler(clientCtx client.Context) govrest.ProposalRESTHandler { - return govrest.ProposalRESTHandler{ - SubRoute: "consumer_removal", - Handler: postConsumerRemovalProposalHandlerFn(clientCtx), - } -} - -func postConsumerAdditionProposalHandlerFn(clientCtx client.Context) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var req ConsumerAdditionProposalReq - if !rest.ReadRESTReq(w, r, clientCtx.LegacyAmino, &req) { - return - } - - req.BaseReq = req.BaseReq.Sanitize() - if !req.BaseReq.ValidateBasic(w) { - return - } - - content := types.NewConsumerAdditionProposal( - req.Title, req.Description, req.ChainId, req.InitialHeight, - req.GenesisHash, req.BinaryHash, req.SpawnTime, - req.ConsumerRedistributionFraction, req.BlocksPerDistributionTransmission, - req.DistributionTransmissionChannel, req.HistoricalEntries, - req.CcvTimeoutPeriod, req.TransferTimeoutPeriod, req.UnbondingPeriod) - - msg, err := govtypes.NewMsgSubmitProposal(content, req.Deposit, req.Proposer) - if rest.CheckBadRequestError(w, err) { - return - } - - if rest.CheckBadRequestError(w, msg.ValidateBasic()) { - return - } - - tx.WriteGeneratedTxResponse(clientCtx, w, req.BaseReq, msg) - } -} - -func postConsumerRemovalProposalHandlerFn(clientCtx client.Context) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var req ConsumerRemovalProposalReq - if !rest.ReadRESTReq(w, r, clientCtx.LegacyAmino, &req) { - return - } - - req.BaseReq = req.BaseReq.Sanitize() - if !req.BaseReq.ValidateBasic(w) { - return - } - - content := types.NewConsumerRemovalProposal( - req.Title, req.Description, req.ChainId, req.StopTime, - ) - - msg, err := govtypes.NewMsgSubmitProposal(content, req.Deposit, req.Proposer) - if rest.CheckBadRequestError(w, err) { - return - } - - if rest.CheckBadRequestError(w, msg.ValidateBasic()) { - return - } - - tx.WriteGeneratedTxResponse(clientCtx, w, req.BaseReq, msg) - } -} -*/ diff --git a/x/ccv/provider/handler.go b/x/ccv/provider/handler.go index cf176a86c1..2c2738ce91 100644 --- a/x/ccv/provider/handler.go +++ b/x/ccv/provider/handler.go @@ -3,14 +3,15 @@ package provider import ( errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) -func NewHandler(k *keeper.Keeper) sdk.Handler { +func NewHandler(k *keeper.Keeper) baseapp.MsgServiceHandler { msgServer := keeper.NewMsgServerImpl(k) return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { @@ -18,13 +19,13 @@ func NewHandler(k *keeper.Keeper) sdk.Handler { switch msg := msg.(type) { case *types.MsgAssignConsumerKey: - res, err := msgServer.AssignConsumerKey(sdk.WrapSDKContext(ctx), msg) + res, err := msgServer.AssignConsumerKey(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) case *types.MsgSubmitConsumerMisbehaviour: - res, err := msgServer.SubmitConsumerMisbehaviour(sdk.WrapSDKContext(ctx), msg) + res, err := msgServer.SubmitConsumerMisbehaviour(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) case *types.MsgSubmitConsumerDoubleVoting: - res, err := msgServer.SubmitConsumerDoubleVoting(sdk.WrapSDKContext(ctx), msg) + res, err := msgServer.SubmitConsumerDoubleVoting(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) default: return nil, errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg) diff --git a/x/ccv/provider/handler_test.go b/x/ccv/provider/handler_test.go index 8cefa3f949..11fb18bf1f 100644 --- a/x/ccv/provider/handler_test.go +++ b/x/ccv/provider/handler_test.go @@ -14,11 +14,11 @@ import ( tmproto "github.com/cometbft/cometbft/proto/tendermint/types" - testcrypto "github.com/cosmos/interchain-security/v4/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/provider" - keeper "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + testcrypto "github.com/cosmos/interchain-security/v5/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider" + keeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) func TestInvalidMsg(t *testing.T) { @@ -30,7 +30,7 @@ func TestInvalidMsg(t *testing.T) { require.True(t, strings.Contains(err.Error(), "unrecognized provider message type")) } -func TestAssignConsensusKeyForConsumerChain(t *testing.T) { +func TestAssignConsensusKeyMsgHandling(t *testing.T) { providerCryptoId := testcrypto.NewCryptoIdentityFromIntSeed(0) providerConsAddr := providerCryptoId.ProviderConsAddress() @@ -57,11 +57,10 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidator( ctx, providerCryptoId.SDKValOpAddress(), - // Return a valid validator, found! - ).Return(providerCryptoId.SDKStakingValidator(), true).Times(1), + ).Return(providerCryptoId.SDKStakingValidator(), nil).Times(1), mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, consumerConsAddr.ToSdkConsAddr(), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), ) }, expError: false, @@ -76,7 +75,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { mocks.MockStakingKeeper.EXPECT().GetValidator( ctx, providerCryptoId.SDKValOpAddress(), // Return a valid validator, found! - ).Return(providerCryptoId.SDKStakingValidator(), true).Times(1), + ).Return(providerCryptoId.SDKStakingValidator(), nil).Times(1), ) }, expError: true, @@ -93,8 +92,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidator( ctx, providerCryptoId.SDKValOpAddress(), - // return false: not found! - ).Return(stakingtypes.Validator{}, false).Times(1), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound).Times(1), ) }, expError: true, @@ -114,11 +112,10 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidator( ctx, providerCryptoId.SDKValOpAddress(), - // Return a valid validator, found! - ).Return(providerCryptoId.SDKStakingValidator(), true).Times(1), + ).Return(providerCryptoId.SDKStakingValidator(), nil).Times(1), mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, consumerConsAddr.ToSdkConsAddr(), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), ) }, expError: true, @@ -134,6 +131,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { msg, err := providertypes.NewMsgAssignConsumerKey(tc.chainID, providerCryptoId.SDKValOpAddress(), consumerKey, + providerCryptoId.SDKStakingValidator().OperatorAddress, ) require.NoError(t, err) diff --git a/x/ccv/provider/ibc_module.go b/x/ccv/provider/ibc_module.go index 3b4f0fa050..c800c31a77 100644 --- a/x/ccv/provider/ibc_module.go +++ b/x/ccv/provider/ibc_module.go @@ -4,20 +4,20 @@ import ( "fmt" "strconv" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" - host "github.com/cosmos/ibc-go/v7/modules/core/24-host" - ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" + ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // OnChanOpenInit implements the IBCModule interface diff --git a/x/ccv/provider/ibc_module_test.go b/x/ccv/provider/ibc_module_test.go index df12ed4cb8..fdae2a03ba 100644 --- a/x/ccv/provider/ibc_module_test.go +++ b/x/ccv/provider/ibc_module_test.go @@ -3,23 +3,23 @@ package provider_test import ( "testing" - "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v7/modules/core/24-host" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + conntypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/provider" - providerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider" + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // TestOnChanOpenInit tests the provider's OnChanOpenInit method against spec. diff --git a/x/ccv/provider/keeper/consumer_equivocation.go b/x/ccv/provider/keeper/consumer_equivocation.go index 8fc9808304..34d6857c93 100644 --- a/x/ccv/provider/keeper/consumer_equivocation.go +++ b/x/ccv/provider/keeper/consumer_equivocation.go @@ -3,24 +3,25 @@ package keeper import ( "bytes" "encoding/binary" + "errors" "fmt" - ibcclienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibcclienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" errorsmod "cosmossdk.io/errors" "cosmossdk.io/math" + evidencetypes "cosmossdk.io/x/evidence/types" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" tmtypes "github.com/cometbft/cometbft/types" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // @@ -222,7 +223,7 @@ func (k Keeper) GetByzantineValidators(ctx sdk.Context, misbehaviour ibctmtypes. // create a map with the validators' address that signed header1 header1Signers := map[string]int{} for idx, sign := range lightBlock1.Commit.Signatures { - if sign.Absent() { + if sign.BlockIDFlag == tmtypes.BlockIDFlagAbsent { continue } header1Signers[sign.ValidatorAddress.String()] = idx @@ -230,7 +231,7 @@ func (k Keeper) GetByzantineValidators(ctx sdk.Context, misbehaviour ibctmtypes. // iterate over the header2 signers and check if they signed header1 for sigIdxHeader2, sign := range lightBlock2.Commit.Signatures { - if sign.Absent() { + if sign.BlockIDFlag == tmtypes.BlockIDFlagAbsent { continue } if sigIdxHeader1, ok := header1Signers[sign.ValidatorAddress.String()]; ok { @@ -354,9 +355,11 @@ func verifyLightBlockCommitSig(lightBlock tmtypes.LightBlock, sigIdx int) error // JailAndTombstoneValidator jails and tombstones the validator with the given provider consensus address func (k Keeper) JailAndTombstoneValidator(ctx sdk.Context, providerAddr types.ProviderConsAddress) error { - validator, found := k.stakingKeeper.GetValidatorByConsAddr(ctx, providerAddr.ToSdkConsAddr()) - if !found { + validator, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, providerAddr.ToSdkConsAddr()) + if err != nil && errors.Is(err, stakingtypes.ErrNoValidatorFound) { return errorsmod.Wrapf(slashingtypes.ErrNoValidatorForAddress, "provider consensus address: %s", providerAddr.String()) + } else if err != nil { + return errorsmod.Wrapf(slashingtypes.ErrBadValidatorAddr, "unkown error looking for provider consensus address: %s", providerAddr.String()) } if validator.IsUnbonded() { @@ -390,19 +393,21 @@ func (k Keeper) ComputePowerToSlash(ctx sdk.Context, validator stakingtypes.Vali redelegations []stakingtypes.Redelegation, power int64, powerReduction math.Int, ) int64 { // compute the total numbers of tokens currently being undelegated - undelegationsInTokens := sdk.NewInt(0) + undelegationsInTokens := math.NewInt(0) // Note that we use a **cached** context to avoid any actual slashing of undelegations or redelegations. cachedCtx, _ := ctx.CacheContext() for _, u := range undelegations { - amountSlashed := k.stakingKeeper.SlashUnbondingDelegation(cachedCtx, u, 0, sdk.NewDec(1)) + // v50: errors are ignored + amountSlashed, _ := k.stakingKeeper.SlashUnbondingDelegation(cachedCtx, u, 0, math.LegacyNewDec(1)) undelegationsInTokens = undelegationsInTokens.Add(amountSlashed) } // compute the total numbers of tokens currently being redelegated - redelegationsInTokens := sdk.NewInt(0) + redelegationsInTokens := math.NewInt(0) for _, r := range redelegations { - amountSlashed := k.stakingKeeper.SlashRedelegation(cachedCtx, validator, r, 0, sdk.NewDec(1)) + // v50 errors are ignored + amountSlashed, _ := k.stakingKeeper.SlashRedelegation(cachedCtx, validator, r, 0, math.LegacyNewDec(1)) redelegationsInTokens = redelegationsInTokens.Add(amountSlashed) } @@ -416,9 +421,11 @@ func (k Keeper) ComputePowerToSlash(ctx sdk.Context, validator stakingtypes.Vali // SlashValidator slashes validator with given provider Address func (k Keeper) SlashValidator(ctx sdk.Context, providerAddr types.ProviderConsAddress) error { - validator, found := k.stakingKeeper.GetValidatorByConsAddr(ctx, providerAddr.ToSdkConsAddr()) - if !found { + validator, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, providerAddr.ToSdkConsAddr()) + if err != nil && errors.Is(err, stakingtypes.ErrNoValidatorFound) { return errorsmod.Wrapf(slashingtypes.ErrNoValidatorForAddress, "provider consensus address: %s", providerAddr.String()) + } else if err != nil { + return errorsmod.Wrapf(slashingtypes.ErrBadValidatorAddr, "unkown error looking for provider consensus address: %s", providerAddr.String()) } if validator.IsUnbonded() { @@ -429,21 +436,38 @@ func (k Keeper) SlashValidator(ctx sdk.Context, providerAddr types.ProviderConsA return fmt.Errorf("validator is tombstoned. provider consensus address: %s", providerAddr.String()) } - undelegations := k.stakingKeeper.GetUnbondingDelegationsFromValidator(ctx, validator.GetOperator()) - redelegations := k.stakingKeeper.GetRedelegationsFromSrcValidator(ctx, validator.GetOperator()) - lastPower := k.stakingKeeper.GetLastValidatorPower(ctx, validator.GetOperator()) + valAddr, err := k.ValidatorAddressCodec().StringToBytes(validator.GetOperator()) + if err != nil { + return err + } + + undelegations, err := k.stakingKeeper.GetUnbondingDelegationsFromValidator(ctx, valAddr) + if err != nil { + return err + } + redelegations, err := k.stakingKeeper.GetRedelegationsFromSrcValidator(ctx, valAddr) + if err != nil { + return err + } + lastPower, err := k.stakingKeeper.GetLastValidatorPower(ctx, valAddr) + if err != nil { + return err + } + powerReduction := k.stakingKeeper.PowerReduction(ctx) totalPower := k.ComputePowerToSlash(ctx, validator, undelegations, redelegations, lastPower, powerReduction) - slashFraction := k.slashingKeeper.SlashFractionDoubleSign(ctx) + slashFraction, err := k.slashingKeeper.SlashFractionDoubleSign(ctx) + if err != nil { + return err + } consAdrr, err := validator.GetConsAddr() if err != nil { - panic(err) + return err } - k.stakingKeeper.SlashWithInfractionReason(ctx, consAdrr, 0, totalPower, slashFraction, stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN) - - return nil + _, err = k.stakingKeeper.SlashWithInfractionReason(ctx, consAdrr, 0, totalPower, slashFraction, stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN) + return err } // diff --git a/x/ccv/provider/keeper/consumer_equivocation_test.go b/x/ccv/provider/keeper/consumer_equivocation_test.go index d92caf69a3..cd0aba4f13 100644 --- a/x/ccv/provider/keeper/consumer_equivocation_test.go +++ b/x/ccv/provider/keeper/consumer_equivocation_test.go @@ -9,18 +9,18 @@ import ( "github.com/stretchr/testify/require" "cosmossdk.io/math" + evidencetypes "cosmossdk.io/x/evidence/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" tmtypes "github.com/cometbft/cometbft/types" - cryptotestutil "github.com/cosmos/interchain-security/v4/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + cryptotestutil "github.com/cosmos/interchain-security/v5/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) func TestVerifyDoubleVotingEvidence(t *testing.T) { @@ -339,7 +339,7 @@ func TestJailAndTombstoneValidator(t *testing.T) { // Method will return once validator is not found. mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( ctx, providerConsAddr.ToSdkConsAddr()).Return( - stakingtypes.Validator{}, false, // false = Not found. + stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound, ).Times(1), } }, @@ -354,7 +354,7 @@ func TestJailAndTombstoneValidator(t *testing.T) { // We only expect a single call to GetValidatorByConsAddr. mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( ctx, providerConsAddr.ToSdkConsAddr()).Return( - stakingtypes.Validator{Status: stakingtypes.Unbonded}, true, + stakingtypes.Validator{Status: stakingtypes.Unbonded}, nil, ).Times(1), } }, @@ -368,7 +368,7 @@ func TestJailAndTombstoneValidator(t *testing.T) { return []*gomock.Call{ mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( ctx, providerConsAddr.ToSdkConsAddr()).Return( - stakingtypes.Validator{}, true, + stakingtypes.Validator{}, nil, ).Times(1), mocks.MockSlashingKeeper.EXPECT().IsTombstoned( ctx, providerConsAddr.ToSdkConsAddr()).Return( @@ -386,7 +386,7 @@ func TestJailAndTombstoneValidator(t *testing.T) { return []*gomock.Call{ mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( ctx, providerConsAddr.ToSdkConsAddr()).Return( - stakingtypes.Validator{Jailed: true}, true, + stakingtypes.Validator{Jailed: true}, nil, ).Times(1), mocks.MockSlashingKeeper.EXPECT().IsTombstoned( ctx, providerConsAddr.ToSdkConsAddr()).Return( @@ -410,7 +410,7 @@ func TestJailAndTombstoneValidator(t *testing.T) { return []*gomock.Call{ mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( ctx, providerConsAddr.ToSdkConsAddr()).Return( - stakingtypes.Validator{Status: stakingtypes.Bonded}, true, + stakingtypes.Validator{Status: stakingtypes.Bonded}, nil, ).Times(1), mocks.MockSlashingKeeper.EXPECT().IsTombstoned( ctx, providerConsAddr.ToSdkConsAddr()).Return( @@ -449,7 +449,7 @@ func createUndelegation(initialBalances []int64, completionTimes []time.Time) st var entries []stakingtypes.UnbondingDelegationEntry for i, balance := range initialBalances { entry := stakingtypes.UnbondingDelegationEntry{ - InitialBalance: sdk.NewInt(balance), + InitialBalance: math.NewInt(balance), CompletionTime: completionTimes[i], } entries = append(entries, entry) @@ -463,7 +463,7 @@ func createRedelegation(initialBalances []int64, completionTimes []time.Time) st var entries []stakingtypes.RedelegationEntry for i, balance := range initialBalances { entry := stakingtypes.RedelegationEntry{ - InitialBalance: sdk.NewInt(balance), + InitialBalance: math.NewInt(balance), CompletionTime: completionTimes[i], } entries = append(entries, entry) @@ -504,7 +504,7 @@ func TestComputePowerToSlash(t *testing.T) { createRedelegation([]int64{250, 250}, []time.Time{nowPlus1Hour, nowPlus1Hour}), }, int64(1000), - sdk.NewInt(1), + math.NewInt(1), int64(2000/1 + 1000), }, { @@ -527,7 +527,7 @@ func TestComputePowerToSlash(t *testing.T) { createRedelegation([]int64{400}, []time.Time{nowPlus1Hour}), }, int64(8391), - sdk.NewInt(2), + math.NewInt(2), int64((2000+3500)/2 + 8391), }, { @@ -535,7 +535,7 @@ func TestComputePowerToSlash(t *testing.T) { []stakingtypes.UnbondingDelegation{}, []stakingtypes.Redelegation{}, int64(3000), - sdk.NewInt(5), + math.NewInt(5), int64(3000), // expectedPower is 0/5 + 3000 }, { @@ -551,7 +551,7 @@ func TestComputePowerToSlash(t *testing.T) { createRedelegation([]int64{100}, []time.Time{nowPlus1Hour}), }, int64(17), - sdk.NewInt(3), + math.NewInt(3), int64(2000/3 + 17), }, { @@ -566,7 +566,7 @@ func TestComputePowerToSlash(t *testing.T) { }, []stakingtypes.Redelegation{}, int64(1), - sdk.NewInt(3), + math.NewInt(3), int64(2000/3 + 1), }, { @@ -591,40 +591,40 @@ func TestComputePowerToSlash(t *testing.T) { createRedelegation([]int64{400}, []time.Time{now}), }, int64(8391), - sdk.NewInt(2), + math.NewInt(2), int64((1150+2550)/2 + 8391), }, } pubKey, _ := cryptocodec.FromTmPubKeyInterface(tmtypes.NewMockPV().PrivKey.PubKey()) - validator, _ := stakingtypes.NewValidator(pubKey.Address().Bytes(), pubKey, stakingtypes.Description{}) + validator, _ := stakingtypes.NewValidator(pubKey.Address().String(), pubKey, stakingtypes.Description{}) for _, tc := range testCases { gomock.InOrder(mocks.MockStakingKeeper.EXPECT(). - SlashUnbondingDelegation(gomock.Any(), gomock.Any(), int64(0), sdk.NewDec(1)). + SlashUnbondingDelegation(gomock.Any(), gomock.Any(), int64(0), math.LegacyNewDec(1)). DoAndReturn( - func(_ sdk.Context, undelegation stakingtypes.UnbondingDelegation, _ int64, _ sdk.Dec) math.Int { - sum := sdk.NewInt(0) + func(_ sdk.Context, undelegation stakingtypes.UnbondingDelegation, _ int64, _ math.LegacyDec) (math.Int, error) { + sum := math.NewInt(0) for _, r := range undelegation.Entries { if r.IsMature(ctx.BlockTime()) { continue } - sum = sum.Add(sdk.NewInt(r.InitialBalance.Int64())) + sum = sum.Add(math.NewInt(r.InitialBalance.Int64())) } - return sum + return sum, nil }).AnyTimes(), mocks.MockStakingKeeper.EXPECT(). - SlashRedelegation(gomock.Any(), gomock.Any(), gomock.Any(), int64(0), sdk.NewDec(1)). + SlashRedelegation(gomock.Any(), gomock.Any(), gomock.Any(), int64(0), math.LegacyNewDec(1)). DoAndReturn( - func(ctx sdk.Context, _ stakingtypes.Validator, redelegation stakingtypes.Redelegation, _ int64, _ sdk.Dec) math.Int { - sum := sdk.NewInt(0) + func(ctx sdk.Context, _ stakingtypes.Validator, redelegation stakingtypes.Redelegation, _ int64, _ math.LegacyDec) (math.Int, error) { + sum := math.NewInt(0) for _, r := range redelegation.Entries { if r.IsMature(ctx.BlockTime()) { continue } - sum = sum.Add(sdk.NewInt(r.InitialBalance.Int64())) + sum = sum.Add(math.NewInt(r.InitialBalance.Int64())) } - return sum + return sum, nil }).AnyTimes(), ) @@ -649,13 +649,10 @@ func TestSlashValidator(t *testing.T) { // undelegation or redelegation entries with completion time one hour in the future have not yet matured nowPlus1Hour := now.Add(time.Hour) - keeperParams := testkeeper.NewInMemKeeperParams(t) - testkeeper.NewInMemProviderKeeper(keeperParams, mocks) - pubKey, _ := cryptocodec.FromTmPubKeyInterface(tmtypes.NewMockPV().PrivKey.PubKey()) validator, err := stakingtypes.NewValidator( - sdk.ValAddress(pubKey.Address().Bytes()), + sdk.ValAddress(pubKey.Address()).String(), pubKey, stakingtypes.NewDescription("", "", "", "", ""), ) @@ -679,64 +676,67 @@ func TestSlashValidator(t *testing.T) { // validator's current power currentPower := int64(3000) - powerReduction := sdk.NewInt(2) - slashFraction, _ := sdk.NewDecFromStr("0.5") + powerReduction := math.NewInt(2) + slashFraction, _ := math.LegacyNewDecFromStr("0.5") // the call to `Slash` should provide an `infractionHeight` of 0 and an expected power of // (750 (undelegations) + 750 (redelegations)) / 2 (= powerReduction) + 3000 (currentPower) = 3750 expectedInfractionHeight := int64(0) expectedSlashPower := int64(3750) + expectedValoperAddr, err := keeper.ValidatorAddressCodec().StringToBytes(validator.GetOperator()) + require.NoError(t, err) + expectedCalls := []*gomock.Call{ mocks.MockStakingKeeper.EXPECT(). GetValidatorByConsAddr(ctx, gomock.Any()). - Return(validator, true), + Return(validator, nil), mocks.MockSlashingKeeper.EXPECT(). IsTombstoned(ctx, consAddr). Return(false), mocks.MockStakingKeeper.EXPECT(). - GetUnbondingDelegationsFromValidator(ctx, validator.GetOperator()). - Return(undelegations), + GetUnbondingDelegationsFromValidator(ctx, expectedValoperAddr). + Return(undelegations, nil), mocks.MockStakingKeeper.EXPECT(). - GetRedelegationsFromSrcValidator(ctx, validator.GetOperator()). - Return(redelegations), + GetRedelegationsFromSrcValidator(ctx, expectedValoperAddr). + Return(redelegations, nil), mocks.MockStakingKeeper.EXPECT(). - GetLastValidatorPower(ctx, validator.GetOperator()). - Return(currentPower), + GetLastValidatorPower(ctx, expectedValoperAddr). + Return(currentPower, nil), mocks.MockStakingKeeper.EXPECT(). PowerReduction(ctx). Return(powerReduction), mocks.MockStakingKeeper.EXPECT(). SlashUnbondingDelegation(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). DoAndReturn( - func(_ sdk.Context, undelegation stakingtypes.UnbondingDelegation, _ int64, _ sdk.Dec) math.Int { - sum := sdk.NewInt(0) + func(_ sdk.Context, undelegation stakingtypes.UnbondingDelegation, _ int64, _ math.LegacyDec) (math.Int, error) { + sum := math.NewInt(0) for _, r := range undelegation.Entries { if r.IsMature(ctx.BlockTime()) { continue } - sum = sum.Add(sdk.NewInt(r.InitialBalance.Int64())) + sum = sum.Add(math.NewInt(r.InitialBalance.Int64())) } - return sum + return sum, nil }).AnyTimes(), mocks.MockStakingKeeper.EXPECT(). SlashRedelegation(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). DoAndReturn( - func(_ sdk.Context, _ stakingtypes.Validator, redelegation stakingtypes.Redelegation, _ int64, _ sdk.Dec) math.Int { - sum := sdk.NewInt(0) + func(_ sdk.Context, _ stakingtypes.Validator, redelegation stakingtypes.Redelegation, _ int64, _ math.LegacyDec) (math.Int, error) { + sum := math.NewInt(0) for _, r := range redelegation.Entries { if r.IsMature(ctx.BlockTime()) { continue } - sum = sum.Add(sdk.NewInt(r.InitialBalance.Int64())) + sum = sum.Add(math.NewInt(r.InitialBalance.Int64())) } - return sum + return sum, nil }).AnyTimes(), mocks.MockSlashingKeeper.EXPECT(). SlashFractionDoubleSign(ctx). - Return(slashFraction), + Return(slashFraction, nil), mocks.MockStakingKeeper.EXPECT(). - SlashWithInfractionReason(ctx, consAddr, expectedInfractionHeight, expectedSlashPower, slashFraction, stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN). + SlashWithInfractionReason(ctx, consAddr, expectedInfractionHeight, expectedSlashPower, slashFraction, stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN).Return(math.NewInt(expectedSlashPower), nil). Times(1), } @@ -756,7 +756,7 @@ func TestSlashValidatorDoesNotSlashIfValidatorIsUnbonded(t *testing.T) { pubKey, _ := cryptocodec.FromTmPubKeyInterface(tmtypes.NewMockPV().PrivKey.PubKey()) // validator is initially unbonded - validator, _ := stakingtypes.NewValidator(pubKey.Address().Bytes(), pubKey, stakingtypes.Description{}) + validator, _ := stakingtypes.NewValidator(pubKey.Address().String(), pubKey, stakingtypes.Description{}) consAddr, _ := validator.GetConsAddr() providerAddr := types.NewProviderConsAddress(consAddr) @@ -764,7 +764,7 @@ func TestSlashValidatorDoesNotSlashIfValidatorIsUnbonded(t *testing.T) { expectedCalls := []*gomock.Call{ mocks.MockStakingKeeper.EXPECT(). GetValidatorByConsAddr(ctx, gomock.Any()). - Return(validator, true), + Return(validator, nil), } gomock.InOrder(expectedCalls...) diff --git a/x/ccv/provider/keeper/distribution.go b/x/ccv/provider/keeper/distribution.go index 5b2e6025ef..0b2cdcf0e9 100644 --- a/x/ccv/provider/keeper/distribution.go +++ b/x/ccv/provider/keeper/distribution.go @@ -1,9 +1,10 @@ package keeper import ( + storetypes "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) // EndBlockRD executes EndBlock logic for the Reward Distribution sub-protocol. @@ -46,8 +47,7 @@ func (k Keeper) DeleteConsumerRewardDenom( func (k Keeper) GetAllConsumerRewardDenoms(ctx sdk.Context) (consumerRewardDenoms []string) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.ConsumerRewardDenomsBytePrefix}) - + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.ConsumerRewardDenomsBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { key := iterator.Key()[1:] diff --git a/x/ccv/provider/keeper/genesis.go b/x/ccv/provider/keeper/genesis.go index 2075ff48ae..66895233a7 100644 --- a/x/ccv/provider/keeper/genesis.go +++ b/x/ccv/provider/keeper/genesis.go @@ -5,8 +5,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // InitGenesis initializes the CCV provider state and binds to PortID. diff --git a/x/ccv/provider/keeper/genesis_test.go b/x/ccv/provider/keeper/genesis_test.go index 81b0a90bd8..8fd22824ef 100644 --- a/x/ccv/provider/keeper/genesis_test.go +++ b/x/ccv/provider/keeper/genesis_test.go @@ -5,17 +5,18 @@ import ( "testing" "time" - host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "cosmossdk.io/math" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/interchain-security/v4/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // TestInitAndExportGenesis tests the export and the initialisation of a provider chain genesis @@ -137,7 +138,7 @@ func TestInitAndExportGenesis(t *testing.T) { ctx, host.PortPath(ccv.ProviderPortID), ).Return(nil, true).Times(1), mocks.MockStakingKeeper.EXPECT().GetLastTotalPower( - ctx).Return(sdk.NewInt(100)).Times(1), // Return total voting power as 100 + ctx).Return(math.NewInt(100), nil).Times(1), // Return total voting power as 100 ) // init provider chain @@ -146,9 +147,9 @@ func TestInitAndExportGenesis(t *testing.T) { // Expect slash meter to be initialized to it's allowance value // (replenish fraction * mocked value defined above) slashMeter := pk.GetSlashMeter(ctx) - replenishFraction, err := sdk.NewDecFromStr(pk.GetParams(ctx).SlashMeterReplenishFraction) + replenishFraction, err := math.LegacyNewDecFromStr(pk.GetParams(ctx).SlashMeterReplenishFraction) require.NoError(t, err) - expectedSlashMeterValue := sdk.NewInt(replenishFraction.MulInt(sdk.NewInt(100)).RoundInt64()) + expectedSlashMeterValue := math.NewInt(replenishFraction.MulInt(math.NewInt(100)).RoundInt64()) require.Equal(t, expectedSlashMeterValue, slashMeter) // Expect slash meter replenishment time candidate to be set to the current block time + replenish period diff --git a/x/ccv/provider/keeper/grpc_query.go b/x/ccv/provider/keeper/grpc_query.go index d190a5f8b0..3c00079577 100644 --- a/x/ccv/provider/keeper/grpc_query.go +++ b/x/ccv/provider/keeper/grpc_query.go @@ -10,8 +10,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) var _ types.QueryServer = Keeper{} @@ -215,8 +215,12 @@ func (k Keeper) QueryAllPairsValConAddrByConsumerChainID(goCtx context.Context, } // QueryParams returns all parameters and current values of provider -func (k Keeper) QueryParams(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { - ctx := sdk.UnwrapSDKContext(c) +func (k Keeper) QueryParams(goCtx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) params := k.GetParams(ctx) return &types.QueryParamsResponse{Params: params}, nil diff --git a/x/ccv/provider/keeper/grpc_query_test.go b/x/ccv/provider/keeper/grpc_query_test.go index dfe0a73895..47d8f9f877 100644 --- a/x/ccv/provider/keeper/grpc_query_test.go +++ b/x/ccv/provider/keeper/grpc_query_test.go @@ -5,10 +5,10 @@ import ( "github.com/stretchr/testify/require" - cryptotestutil "github.com/cosmos/interchain-security/v4/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + cryptotestutil "github.com/cosmos/interchain-security/v5/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) func TestQueryAllPairsValConAddrByConsumerChainID(t *testing.T) { diff --git a/x/ccv/provider/keeper/hooks.go b/x/ccv/provider/keeper/hooks.go index 88590a9875..d99ab43c93 100644 --- a/x/ccv/provider/keeper/hooks.go +++ b/x/ccv/provider/keeper/hooks.go @@ -1,15 +1,17 @@ package keeper import ( + "context" "fmt" + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" sdkgov "github.com/cosmos/cosmos-sdk/x/gov/types" v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // Wrapper struct @@ -32,10 +34,12 @@ func (k *Keeper) Hooks() Hooks { // // This stores a record of each unbonding op from staking, allowing us to track which consumer chains have unbonded -func (h Hooks) AfterUnbondingInitiated(ctx sdk.Context, id uint64) error { +func (h Hooks) AfterUnbondingInitiated(goCtx context.Context, id uint64) error { var consumerChainIDS []string + ctx := sdk.UnwrapSDKContext(goCtx) for _, chain := range h.k.GetAllConsumerChains(ctx) { + consumerChainIDS = append(consumerChainIDS, chain.ChainId) } @@ -53,7 +57,7 @@ func (h Hooks) AfterUnbondingInitiated(ctx sdk.Context, id uint64) error { // This change should be updated for SDK v0.48 because it will include changes in handling // check: https://github.com/cosmos/cosmos-sdk/pull/16043 - ctx.Logger().Error("unbonding could not be put on hold: %w", err) + h.k.Logger(ctx).Error("unbonding could not be put on hold: %w", err) return nil } @@ -91,7 +95,9 @@ func (h Hooks) AfterUnbondingInitiated(ctx sdk.Context, id uint64) error { return nil } -func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error { +func (h Hooks) AfterValidatorCreated(goCtx context.Context, valAddr sdk.ValAddress) error { + ctx := sdk.UnwrapSDKContext(goCtx) + if h.k.ValidatorConsensusKeyInUse(ctx, valAddr) { // Abort TX, do NOT allow validator to be created panic("cannot create a validator with a consensus key that is already in use or was recently in use as an assigned consumer chain key") @@ -99,7 +105,9 @@ func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) er return nil } -func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, valConsAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { +func (h Hooks) AfterValidatorRemoved(goCtx context.Context, valConsAddr sdk.ConsAddress, valAddr sdk.ValAddress) error { + ctx := sdk.UnwrapSDKContext(goCtx) + for _, validatorConsumerPubKey := range h.k.GetAllValidatorConsumerPubKeys(ctx, nil) { if sdk.ConsAddress(validatorConsumerPubKey.ProviderAddr).Equals(valConsAddr) { consumerAddrTmp, err := ccvtypes.TMCryptoPublicKeyToConsAddr(*validatorConsumerPubKey.ConsumerKey) @@ -117,35 +125,35 @@ func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, valConsAddr sdk.ConsAddres return nil } -func (h Hooks) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { +func (h Hooks) BeforeDelegationCreated(_ context.Context, _ sdk.AccAddress, _ sdk.ValAddress) error { return nil } -func (h Hooks) BeforeDelegationSharesModified(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) error { +func (h Hooks) BeforeDelegationSharesModified(_ context.Context, _ sdk.AccAddress, _ sdk.ValAddress) error { return nil } -func (h Hooks) AfterDelegationModified(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) error { +func (h Hooks) AfterDelegationModified(_ context.Context, _ sdk.AccAddress, _ sdk.ValAddress) error { return nil } -func (h Hooks) BeforeValidatorSlashed(_ sdk.Context, _ sdk.ValAddress, _ sdk.Dec) error { +func (h Hooks) BeforeValidatorSlashed(_ context.Context, _ sdk.ValAddress, _ math.LegacyDec) error { return nil } -func (h Hooks) BeforeValidatorModified(_ sdk.Context, _ sdk.ValAddress) error { +func (h Hooks) BeforeValidatorModified(_ context.Context, _ sdk.ValAddress) error { return nil } -func (h Hooks) AfterValidatorBonded(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error { +func (h Hooks) AfterValidatorBonded(_ context.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error { return nil } -func (h Hooks) AfterValidatorBeginUnbonding(_ sdk.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error { +func (h Hooks) AfterValidatorBeginUnbonding(_ context.Context, _ sdk.ConsAddress, _ sdk.ValAddress) error { return nil } -func (h Hooks) BeforeDelegationRemoved(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) error { +func (h Hooks) BeforeDelegationRemoved(_ context.Context, _ sdk.AccAddress, _ sdk.ValAddress) error { return nil } @@ -156,29 +164,38 @@ func (h Hooks) BeforeDelegationRemoved(_ sdk.Context, _ sdk.AccAddress, _ sdk.Va // AfterProposalSubmission - call hook if registered // After a consumerAddition proposal submission, a record is created // that maps the proposal ID to the consumer chain ID. -func (h Hooks) AfterProposalSubmission(ctx sdk.Context, proposalID uint64) { +func (h Hooks) AfterProposalSubmission(goCtx context.Context, proposalID uint64) error { + ctx := sdk.UnwrapSDKContext(goCtx) + if p, ok := h.GetConsumerAdditionLegacyPropFromProp(ctx, proposalID); ok { h.k.SetProposedConsumerChain(ctx, p.ChainId, proposalID) } + return nil } // AfterProposalVotingPeriodEnded - call hook if registered // After proposal voting ends, the consumer chainID in store is deleted. // When a consumerAddition proposal passes, the consumer chainID is available in providerKeeper.GetAllPendingConsumerAdditionProps // or providerKeeper.GetAllConsumerChains(ctx). -func (h Hooks) AfterProposalVotingPeriodEnded(ctx sdk.Context, proposalID uint64) { +func (h Hooks) AfterProposalVotingPeriodEnded(goCtx context.Context, proposalID uint64) error { + ctx := sdk.UnwrapSDKContext(goCtx) + if _, ok := h.GetConsumerAdditionLegacyPropFromProp(ctx, proposalID); ok { h.k.DeleteProposedConsumerChainInStore(ctx, proposalID) } + return nil } -func (h Hooks) AfterProposalDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) { +func (h Hooks) AfterProposalDeposit(ctx context.Context, proposalID uint64, depositorAddr sdk.AccAddress) error { + return nil } -func (h Hooks) AfterProposalVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress) { +func (h Hooks) AfterProposalVote(ctx context.Context, proposalID uint64, voterAddr sdk.AccAddress) error { + return nil } -func (h Hooks) AfterProposalFailedMinDeposit(ctx sdk.Context, proposalID uint64) { +func (h Hooks) AfterProposalFailedMinDeposit(ctx context.Context, proposalID uint64) error { + return nil } // GetConsumerAdditionLegacyPropFromProp extracts a consumer addition legacy proposal from @@ -187,9 +204,9 @@ func (h Hooks) GetConsumerAdditionLegacyPropFromProp( ctx sdk.Context, proposalID uint64, ) (providertypes.ConsumerAdditionProposal, bool) { - p, ok := h.k.govKeeper.GetProposal(ctx, proposalID) - if !ok { - panic(fmt.Errorf("failed to get proposal %d from store", proposalID)) + p, err := h.k.govKeeper.Proposals.Get(ctx, proposalID) + if err != nil { + return providertypes.ConsumerAdditionProposal{}, false } // Iterate over the messages in the proposal diff --git a/x/ccv/provider/keeper/hooks_test.go b/x/ccv/provider/keeper/hooks_test.go index f4aad8d441..d7ea94c0dc 100644 --- a/x/ccv/provider/keeper/hooks_test.go +++ b/x/ccv/provider/keeper/hooks_test.go @@ -2,22 +2,14 @@ package keeper_test import ( "testing" - "time" "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" - - "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" - "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - - cryptotestutil "github.com/cosmos/interchain-security/v4/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - providerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" + + cryptotestutil "github.com/cosmos/interchain-security/v5/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" ) func TestValidatorConsensusKeyInUse(t *testing.T) { @@ -77,149 +69,153 @@ func TestValidatorConsensusKeyInUse(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidator(ctx, newValidator.SDKValOpAddress(), - ).Return(newValidator.SDKStakingValidator(), true), + ).Return(newValidator.SDKStakingValidator(), nil), ) tt.setup(ctx, k) t.Run(tt.name, func(t *testing.T) { - if actual := k.ValidatorConsensusKeyInUse(ctx, newValidator.SDKStakingValidator().GetOperator()); actual != tt.expect { + if actual := k.ValidatorConsensusKeyInUse(ctx, newValidator.SDKValOpAddress()); actual != tt.expect { t.Errorf("validatorConsensusKeyInUse() = %v, want %v", actual, tt.expect) } }) } } -func TestAfterPropSubmissionAndVotingPeriodEnded(t *testing.T) { - acct := cryptotestutil.NewCryptoIdentityFromIntSeed(0) - - propMsg, err := v1.NewLegacyContent( - testkeeper.GetTestConsumerAdditionProp(), - authtypes.NewModuleAddress("gov").String(), - ) - require.NoError(t, err) - - prop, err := v1.NewProposal( - []sdk.Msg{propMsg}, - 0, - time.Now(), - time.Now(), - "", - "", - "", - sdk.AccAddress(acct.SDKValOpAddress()), - ) - require.NoError(t, err) - - k, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - - // pass the prop to the mocked gov keeper, - // which is called by both the AfterProposalVotingPeriodEnded and - // AfterProposalSubmission gov hooks - gomock.InOrder( - mocks.MockGovKeeper.EXPECT().GetProposal(ctx, prop.Id).Return(prop, true).Times(2), - ) - - k.Hooks().AfterProposalSubmission(ctx, prop.Id) - // verify that the proposal ID is created - require.NotEmpty(t, k.GetProposedConsumerChain(ctx, prop.Id)) - - k.Hooks().AfterProposalVotingPeriodEnded(ctx, prop.Id) - // verify that the proposal ID is deleted - require.Empty(t, k.GetProposedConsumerChain(ctx, prop.Id)) -} - -func TestGetConsumerAdditionLegacyPropFromProp(t *testing.T) { - acct := cryptotestutil.NewCryptoIdentityFromIntSeed(0) - anotherAcct := cryptotestutil.NewCryptoIdentityFromIntSeed(1) - - // create a dummy bank send message - dummyMsg := &banktypes.MsgSend{ - FromAddress: sdk.AccAddress(acct.SDKValOpAddress()).String(), - ToAddress: sdk.AccAddress(anotherAcct.SDKValOpAddress()).String(), - Amount: sdk.NewCoins(sdk.NewCoin("stake", math.OneInt())), - } - - textProp, err := v1.NewLegacyContent( - v1beta1.NewTextProposal("a title", "a legacy text prop"), - authtypes.NewModuleAddress("gov").String(), - ) - require.NoError(t, err) - - consuProp, err := v1.NewLegacyContent( - testkeeper.GetTestConsumerAdditionProp(), - authtypes.NewModuleAddress("gov").String(), - ) - require.NoError(t, err) - - testCases := map[string]struct { - propMsg sdk.Msg - // setup func(sdk.Context, k providerkeeper, proposalID uint64) - expPanic bool - expConsuAddProp bool - }{ - "prop not found": { - propMsg: nil, - expPanic: true, - }, - "msgs in prop contain no legacy props": { - propMsg: dummyMsg, - }, - "msgs contain a legacy prop but not of ConsumerAdditionProposal type": { - propMsg: textProp, - }, - "msgs contain an invalid legacy prop": { - propMsg: &v1.MsgExecLegacyContent{}, - expPanic: true, - }, - "msg contains a prop of ConsumerAdditionProposal type - hook should create a new proposed chain": { - propMsg: consuProp, - expConsuAddProp: true, - }, - } - - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - k, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - - var ( - prop v1.Proposal - propFound bool - ) - - if tc.propMsg != nil { - propFound = true - prop, err = v1.NewProposal( - []sdk.Msg{tc.propMsg}, - 0, - time.Now(), - time.Now(), - "", - "", - "", - sdk.AccAddress(acct.SDKValOpAddress()), - ) - require.NoError(t, err) - } - - gomock.InOrder( - mocks.MockGovKeeper.EXPECT().GetProposal(ctx, prop.Id).Return(prop, propFound), - ) - - if tc.expPanic { - defer func() { - // fail test if not panic was recovered - if r := recover(); r == nil { - require.Fail(t, r.(string)) - } - }() - } - - // retrieve consumer addition proposal - _, ok := k.Hooks().GetConsumerAdditionLegacyPropFromProp(ctx, prop.Id) - require.Equal(t, tc.expConsuAddProp, ok) - }) - } -} +// TODO: move to integration tests +// func TestAfterPropSubmissionAndVotingPeriodEnded(t *testing.T) { +// acct := cryptotestutil.NewCryptoIdentityFromIntSeed(0) + +// propMsg, err := v1.NewLegacyContent( +// testkeeper.GetTestConsumerAdditionProp(), +// authtypes.NewModuleAddress("gov").String(), +// ) +// require.NoError(t, err) + +// prop, err := v1.NewProposal( +// []sdk.Msg{propMsg}, +// 0, +// time.Now(), +// time.Now(), +// "", +// "", +// "", +// sdk.AccAddress(acct.SDKValOpAddress()), +// false, // proposal not expedited +// ) +// require.NoError(t, err) + +// k, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) +// defer ctrl.Finish() + +// // TODO: not sure how to ho about fetching props on the mock +// // pass the prop to the mocked gov keeper, +// // which is called by both the AfterProposalVotingPeriodEnded and +// // AfterProposalSubmission gov hooks +// // gomock.InOrder( +// // mocks.MockGovKeeper.EXPECT().GetProposal(ctx, prop.Id).Return(prop, true).Times(2), +// // ) + +// k.Hooks().AfterProposalSubmission(ctx, prop.Id) +// // verify that the proposal ID is created +// require.NotEmpty(t, k.GetProposedConsumerChain(ctx, prop.Id)) + +// k.Hooks().AfterProposalVotingPeriodEnded(ctx, prop.Id) +// // verify that the proposal ID is deleted +// require.Empty(t, k.GetProposedConsumerChain(ctx, prop.Id)) +// } + +// func TestGetConsumerAdditionLegacyPropFromProp(t *testing.T) { +// acct := cryptotestutil.NewCryptoIdentityFromIntSeed(0) +// anotherAcct := cryptotestutil.NewCryptoIdentityFromIntSeed(1) + +// // create a dummy bank send message +// dummyMsg := &banktypes.MsgSend{ +// FromAddress: sdk.AccAddress(acct.SDKValOpAddress()).String(), +// ToAddress: sdk.AccAddress(anotherAcct.SDKValOpAddress()).String(), +// Amount: sdk.NewCoins(sdk.NewCoin("stake", math.OneInt())), +// } + +// textProp, err := v1.NewLegacyContent( +// v1beta1.NewTextProposal("a title", "a legacy text prop"), +// authtypes.NewModuleAddress("gov").String(), +// ) +// require.NoError(t, err) + +// consuProp, err := v1.NewLegacyContent( +// testkeeper.GetTestConsumerAdditionProp(), +// authtypes.NewModuleAddress("gov").String(), +// ) +// require.NoError(t, err) + +// testCases := map[string]struct { +// propMsg sdk.Msg +// // setup func(sdk.Context, k providerkeeper, proposalID uint64) +// expPanic bool +// expConsuAddProp bool +// }{ +// "prop not found": { +// propMsg: nil, +// expPanic: true, +// }, +// "msgs in prop contain no legacy props": { +// propMsg: dummyMsg, +// }, +// "msgs contain a legacy prop but not of ConsumerAdditionProposal type": { +// propMsg: textProp, +// }, +// "msgs contain an invalid legacy prop": { +// propMsg: &v1.MsgExecLegacyContent{}, +// expPanic: true, +// }, +// "msg contains a prop of ConsumerAdditionProposal type - hook should create a new proposed chain": { +// propMsg: consuProp, +// expConsuAddProp: true, +// }, +// } + +// for name, tc := range testCases { +// t.Run(name, func(t *testing.T) { +// k, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) +// defer ctrl.Finish() + +// var ( +// prop v1.Proposal +// // propFound bool +// ) + +// if tc.propMsg != nil { +// // propFound = true +// prop, err = v1.NewProposal( +// []sdk.Msg{tc.propMsg}, +// 0, +// time.Now(), +// time.Now(), +// "", +// "", +// "", +// sdk.AccAddress(acct.SDKValOpAddress()), +// false, // proposal not expedited +// ) +// require.NoError(t, err) +// } + +// // gomock.InOrder( +// // mocks.MockGovKeeper.EXPECT().GetProposal(ctx, prop.Id).Return(prop, propFound), +// // ) + +// if tc.expPanic { +// defer func() { +// // fail test if not panic was recovered +// if r := recover(); r == nil { +// require.Fail(t, r.(string)) +// } +// }() +// } + +// // retrieve consumer addition proposal +// _, ok := k.Hooks().GetConsumerAdditionLegacyPropFromProp(ctx, prop.Id) +// require.Equal(t, tc.expConsuAddProp, ok) +// }) +// } +// } diff --git a/x/ccv/provider/keeper/keeper.go b/x/ccv/provider/keeper/keeper.go index 510d957c5d..a697eb1b4a 100644 --- a/x/ccv/provider/keeper/keeper.go +++ b/x/ccv/provider/keeper/keeper.go @@ -1,38 +1,45 @@ package keeper import ( + "context" "encoding/binary" "fmt" "reflect" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v7/modules/core/24-host" - ibchost "github.com/cosmos/ibc-go/v7/modules/core/exported" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + addresscodec "cosmossdk.io/core/address" + + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + conntypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" + ibchost "github.com/cosmos/ibc-go/v8/modules/core/exported" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" errorsmod "cosmossdk.io/errors" + storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" - storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" - "github.com/cometbft/cometbft/libs/log" + "cosmossdk.io/log" + govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" - consumertypes "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // Keeper defines the Cross-Chain Validation Provider Keeper type Keeper struct { - storeKey storetypes.StoreKey + // address capable of executing gov messages (gov module account) + authority string + + storeKey storetypes.StoreKey + cdc codec.BinaryCodec - paramSpace paramtypes.Subspace scopedKeeper ccv.ScopedKeeper channelKeeper ccv.ChannelKeeper portKeeper ccv.PortKeeper @@ -43,8 +50,11 @@ type Keeper struct { slashingKeeper ccv.SlashingKeeper distributionKeeper ccv.DistributionKeeper bankKeeper ccv.BankKeeper - govKeeper ccv.GovKeeper + govKeeper govkeeper.Keeper feeCollectorName string + + validatorAddressCodec addresscodec.Codec + consensusAddressCodec addresscodec.Codec } // NewKeeper creates a new provider Keeper instance @@ -55,69 +65,87 @@ func NewKeeper( stakingKeeper ccv.StakingKeeper, slashingKeeper ccv.SlashingKeeper, accountKeeper ccv.AccountKeeper, distributionKeeper ccv.DistributionKeeper, bankKeeper ccv.BankKeeper, - govKeeper ccv.GovKeeper, feeCollectorName string, + govKeeper govkeeper.Keeper, + authority string, + validatorAddressCodec, consensusAddressCodec addresscodec.Codec, + feeCollectorName string, ) Keeper { - // set KeyTable if it has not already been set - if !paramSpace.HasKeyTable() { - paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) - } - k := Keeper{ - cdc: cdc, - storeKey: key, - paramSpace: paramSpace, - scopedKeeper: scopedKeeper, - channelKeeper: channelKeeper, - portKeeper: portKeeper, - connectionKeeper: connectionKeeper, - clientKeeper: clientKeeper, - stakingKeeper: stakingKeeper, - slashingKeeper: slashingKeeper, - accountKeeper: accountKeeper, - distributionKeeper: distributionKeeper, - bankKeeper: bankKeeper, - govKeeper: govKeeper, - feeCollectorName: feeCollectorName, + cdc: cdc, + storeKey: key, + authority: authority, + scopedKeeper: scopedKeeper, + channelKeeper: channelKeeper, + portKeeper: portKeeper, + connectionKeeper: connectionKeeper, + clientKeeper: clientKeeper, + stakingKeeper: stakingKeeper, + slashingKeeper: slashingKeeper, + accountKeeper: accountKeeper, + distributionKeeper: distributionKeeper, + bankKeeper: bankKeeper, + feeCollectorName: feeCollectorName, + validatorAddressCodec: validatorAddressCodec, + consensusAddressCodec: consensusAddressCodec, + govKeeper: govKeeper, } k.mustValidateFields() return k } -// SetParamSpace sets the param space for the provider keeper. -// Note: this is only used for testing! -func (k *Keeper) SetParamSpace(ctx sdk.Context, ps paramtypes.Subspace) { - k.paramSpace = ps +// GetAuthority returns the x/ccv/provider module's authority. +func (k Keeper) GetAuthority() string { + return k.authority +} + +// ValidatorAddressCodec returns the app validator address codec. +func (k Keeper) ValidatorAddressCodec() addresscodec.Codec { + return k.validatorAddressCodec +} + +// ConsensusAddressCodec returns the app consensus address codec. +func (k Keeper) ConsensusAddressCodec() addresscodec.Codec { + return k.consensusAddressCodec } // Validates that the provider keeper is initialized with non-zero and // non-nil values for all its fields. Otherwise this method will panic. func (k Keeper) mustValidateFields() { // Ensures no fields are missed in this validation - if reflect.ValueOf(k).NumField() != 15 { - panic("number of fields in provider keeper is not 15") - } - - ccv.PanicIfZeroOrNil(k.cdc, "cdc") // 1 - ccv.PanicIfZeroOrNil(k.storeKey, "storeKey") // 2 - ccv.PanicIfZeroOrNil(k.paramSpace, "paramSpace") // 3 - ccv.PanicIfZeroOrNil(k.scopedKeeper, "scopedKeeper") // 4 - ccv.PanicIfZeroOrNil(k.channelKeeper, "channelKeeper") // 5 - ccv.PanicIfZeroOrNil(k.portKeeper, "portKeeper") // 6 - ccv.PanicIfZeroOrNil(k.connectionKeeper, "connectionKeeper") // 7 - ccv.PanicIfZeroOrNil(k.accountKeeper, "accountKeeper") // 8 - ccv.PanicIfZeroOrNil(k.clientKeeper, "clientKeeper") // 9 - ccv.PanicIfZeroOrNil(k.stakingKeeper, "stakingKeeper") // 10 - ccv.PanicIfZeroOrNil(k.slashingKeeper, "slashingKeeper") // 11 - ccv.PanicIfZeroOrNil(k.distributionKeeper, "distributionKeeper") // 12 - ccv.PanicIfZeroOrNil(k.bankKeeper, "bankKeeper") // 13 - ccv.PanicIfZeroOrNil(k.govKeeper, "govKeeper") // 14 - ccv.PanicIfZeroOrNil(k.feeCollectorName, "feeCollectorName") // 15 + if reflect.ValueOf(k).NumField() != 17 { + panic(fmt.Sprintf("number of fields in provider keeper is not 18 - have %d", reflect.ValueOf(k).NumField())) + } + + if k.validatorAddressCodec == nil || k.consensusAddressCodec == nil { + panic("validator and/or consensus address codec are nil") + } + + ccv.PanicIfZeroOrNil(k.cdc, "cdc") // 1 + ccv.PanicIfZeroOrNil(k.storeKey, "storeKey") // 2 + ccv.PanicIfZeroOrNil(k.scopedKeeper, "scopedKeeper") // 3 + ccv.PanicIfZeroOrNil(k.channelKeeper, "channelKeeper") // 4 + ccv.PanicIfZeroOrNil(k.portKeeper, "portKeeper") // 5 + ccv.PanicIfZeroOrNil(k.connectionKeeper, "connectionKeeper") // 6 + ccv.PanicIfZeroOrNil(k.accountKeeper, "accountKeeper") // 7 + ccv.PanicIfZeroOrNil(k.clientKeeper, "clientKeeper") // 8 + ccv.PanicIfZeroOrNil(k.stakingKeeper, "stakingKeeper") // 9 + ccv.PanicIfZeroOrNil(k.slashingKeeper, "slashingKeeper") // 10 + ccv.PanicIfZeroOrNil(k.distributionKeeper, "distributionKeeper") // 11 + ccv.PanicIfZeroOrNil(k.bankKeeper, "bankKeeper") // 12 + ccv.PanicIfZeroOrNil(k.feeCollectorName, "feeCollectorName") // 13 + ccv.PanicIfZeroOrNil(k.authority, "authority") // 14 + ccv.PanicIfZeroOrNil(k.validatorAddressCodec, "validatorAddressCodec") // 15 + ccv.PanicIfZeroOrNil(k.consensusAddressCodec, "consensusAddressCodec") // 16 + + // this can be nil in tests + // ccv.PanicIfZeroOrNil(k.govKeeper, "govKeeper") // 17 } // Logger returns a module-specific logger. -func (k Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", "x/"+ibchost.ModuleName+"-"+types.ModuleName) +func (k Keeper) Logger(ctx context.Context) log.Logger { + sdkCtx := sdk.UnwrapSDKContext(ctx) + return sdkCtx.Logger().With("module", "x/"+ibchost.ModuleName+"-"+types.ModuleName) } // IsBound checks if the CCV module is already bound to the desired port @@ -201,7 +229,7 @@ func (k Keeper) DeleteProposedConsumerChainInStore(ctx sdk.Context, proposalID u // GetAllProposedConsumerChainIDs returns the proposed chainID of all gov consumerAddition proposals that are still in the voting period. func (k Keeper) GetAllProposedConsumerChainIDs(ctx sdk.Context) []types.ProposedChain { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.ProposedConsumerChainByteKey}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.ProposedConsumerChainByteKey}) defer iterator.Close() proposedChains := []types.ProposedChain{} @@ -240,7 +268,7 @@ func (k Keeper) GetAllPendingConsumerChainIDs(ctx sdk.Context) []string { // Thus, the returned array is in ascending order of chainIDs. func (k Keeper) GetAllConsumerChains(ctx sdk.Context) (chains []types.Chain) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.ChainToClientBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.ChainToClientBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -288,7 +316,7 @@ func (k Keeper) DeleteChannelToChain(ctx sdk.Context, channelID string) { // Thus, the returned array is in ascending order of channelIDs. func (k Keeper) GetAllChannelToChains(ctx sdk.Context) (channels []types.ChannelToChain) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.ChannelToChainBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.ChannelToChainBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -459,7 +487,7 @@ func (k Keeper) DeleteUnbondingOp(ctx sdk.Context, id uint64) { // Thus, the iteration is in ascending order of IDs. func (k Keeper) GetAllUnbondingOps(ctx sdk.Context) (ops []types.UnbondingOp) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.UnbondingOpBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.UnbondingOpBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -550,7 +578,7 @@ func (k Keeper) SetUnbondingOpIndex(ctx sdk.Context, chainID string, vscID uint6 // Thus, the returned array is in ascending order of vscIDs. func (k Keeper) GetAllUnbondingOpIndexes(ctx sdk.Context, chainID string) (indexes []types.VscUnbondingOps) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.UnbondingOpIndexBytePrefix, chainID)) + iterator := storetypes.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.UnbondingOpIndexBytePrefix, chainID)) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -753,7 +781,7 @@ func (k Keeper) GetValsetUpdateBlockHeight(ctx sdk.Context, valsetUpdateId uint6 // Thus, the returned array is in ascending order of vscIDs. func (k Keeper) GetAllValsetUpdateBlockHeights(ctx sdk.Context) (valsetUpdateBlockHeights []types.ValsetUpdateIdToHeight) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.ValsetUpdateBlockHeightBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.ValsetUpdateBlockHeightBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -959,7 +987,7 @@ func (k Keeper) DeleteInitTimeoutTimestamp(ctx sdk.Context, chainID string) { // Thus, the returned array is in ascending order of chainIDs (NOT in timestamp order). func (k Keeper) GetAllInitTimeoutTimestamps(ctx sdk.Context) (initTimeoutTimestamps []types.InitTimeoutTimestamp) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.InitTimeoutTimestampBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.InitTimeoutTimestampBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -1023,7 +1051,7 @@ func (k Keeper) DeleteVscSendTimestamp(ctx sdk.Context, chainID string, vscID ui // Thus, the iteration is in ascending order of vscIDs, and as a result in send timestamp order. func (k Keeper) GetAllVscSendTimestamps(ctx sdk.Context, chainID string) (vscSendTimestamps []types.VscSendTimestamp) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.VscSendTimestampBytePrefix, chainID)) + iterator := storetypes.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.VscSendTimestampBytePrefix, chainID)) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -1052,7 +1080,8 @@ func (k Keeper) GetAllVscSendTimestamps(ctx sdk.Context, chainID string) (vscSen // DeleteVscSendTimestampsForConsumer deletes all VSC send timestamps for a given consumer chain func (k Keeper) DeleteVscSendTimestampsForConsumer(ctx sdk.Context, consumerChainID string) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.VscSendTimestampBytePrefix, consumerChainID)) + iterator := storetypes.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.VscSendTimestampBytePrefix, consumerChainID)) + defer iterator.Close() keysToDel := [][]byte{} @@ -1069,7 +1098,7 @@ func (k Keeper) DeleteVscSendTimestampsForConsumer(ctx sdk.Context, consumerChai // GetFirstVscSendTimestamp gets the vsc send timestamp with the lowest vscID for the given chainID. func (k Keeper) GetFirstVscSendTimestamp(ctx sdk.Context, chainID string) (vscSendTimestamp types.VscSendTimestamp, found bool) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.VscSendTimestampBytePrefix, chainID)) + iterator := storetypes.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.VscSendTimestampBytePrefix, chainID)) defer iterator.Close() if iterator.Valid() { @@ -1117,7 +1146,7 @@ func (k Keeper) GetSlashLog( return bz != nil } -func (k Keeper) BondDenom(ctx sdk.Context) string { +func (k Keeper) BondDenom(ctx sdk.Context) (string, error) { return k.stakingKeeper.BondDenom(ctx) } diff --git a/x/ccv/provider/keeper/keeper_test.go b/x/ccv/provider/keeper/keeper_test.go index 9c9d421fd9..954a0e6873 100644 --- a/x/ccv/provider/keeper/keeper_test.go +++ b/x/ccv/provider/keeper/keeper_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibctesting "github.com/cosmos/ibc-go/v8/testing" "github.com/stretchr/testify/require" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" @@ -14,10 +14,10 @@ import ( abci "github.com/cometbft/cometbft/abci/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" - cryptotestutil "github.com/cosmos/interchain-security/v4/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + cryptotestutil "github.com/cosmos/interchain-security/v5/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) const consumer = "consumer" diff --git a/x/ccv/provider/keeper/key_assignment.go b/x/ccv/provider/keeper/key_assignment.go index c54d922f0f..a13a8abb97 100644 --- a/x/ccv/provider/keeper/key_assignment.go +++ b/x/ccv/provider/keeper/key_assignment.go @@ -4,6 +4,7 @@ import ( "fmt" errorsmod "cosmossdk.io/errors" + storetypes "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -11,8 +12,8 @@ import ( abci "github.com/cometbft/cometbft/abci/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // GetValidatorConsumerPubKey returns a validator's public key assigned for a consumer chain @@ -70,7 +71,7 @@ func (k Keeper) GetAllValidatorConsumerPubKeys(ctx sdk.Context, chainID *string) // iterate over the validators public keys assigned for chainID prefix = types.ChainIdWithLenKey(types.ConsumerValidatorsBytePrefix, *chainID) } - iterator := sdk.KVStorePrefixIterator(store, prefix) + iterator := storetypes.KVStorePrefixIterator(store, prefix) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { // TODO: store chainID and provider cons address in value bytes, marshaled as protobuf type @@ -154,7 +155,7 @@ func (k Keeper) GetAllValidatorsByConsumerAddr(ctx sdk.Context, chainID *string) // iterate over the mappings from consensus addresses on chainID prefix = types.ChainIdWithLenKey(types.ValidatorsByConsumerAddrBytePrefix, *chainID) } - iterator := sdk.KVStorePrefixIterator(store, prefix) + iterator := storetypes.KVStorePrefixIterator(store, prefix) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { // TODO: store chainID and consumer cons address in value bytes, marshaled as protobuf type @@ -240,7 +241,7 @@ func (k Keeper) SetKeyAssignmentReplacement( func (k Keeper) GetAllKeyAssignmentReplacements(ctx sdk.Context, chainID string) (replacements []types.KeyAssignmentReplacement) { store := ctx.KVStore(k.storeKey) iteratorPrefix := types.ChainIdWithLenKey(types.KeyAssignmentReplacementsBytePrefix, chainID) - iterator := sdk.KVStorePrefixIterator(store, iteratorPrefix) + iterator := storetypes.KVStorePrefixIterator(store, iteratorPrefix) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { // TODO: store chainID and provider cons address in value bytes, marshaled as protobuf type @@ -336,7 +337,7 @@ func (k Keeper) GetConsumerAddrsToPrune( func (k Keeper) GetAllConsumerAddrsToPrune(ctx sdk.Context, chainID string) (consumerAddrsToPrune []types.ConsumerAddrsToPrune) { store := ctx.KVStore(k.storeKey) iteratorPrefix := types.ChainIdWithLenKey(types.ConsumerAddrsToPruneBytePrefix, chainID) - iterator := sdk.KVStorePrefixIterator(store, iteratorPrefix) + iterator := storetypes.KVStorePrefixIterator(store, iteratorPrefix) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { _, vscID, err := types.ParseChainIdAndUintIdKey(types.ConsumerAddrsToPruneBytePrefix, iterator.Key()) @@ -398,7 +399,7 @@ func (k Keeper) AssignConsumerKey( } providerAddr := types.NewProviderConsAddress(consAddrTmp) - if existingVal, found := k.stakingKeeper.GetValidatorByConsAddr(ctx, consumerAddr.ToSdkConsAddr()); found { + if existingVal, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, consumerAddr.ToSdkConsAddr()); err == nil { // If there is already a different validator using the consumer key to validate on the provider // we prevent assigning the consumer key. if existingVal.OperatorAddress != validator.OperatorAddress { @@ -447,15 +448,23 @@ func (k Keeper) AssignConsumerKey( ) } else { // the validator had no key assigned on this consumer chain - providerKey, err := validator.TmConsPublicKey() + providerKey, err := validator.CmtConsPublicKey() if err != nil { return err } oldConsumerKey = providerKey } + valAddr, err := k.ValidatorAddressCodec().StringToBytes(validator.GetOperator()) + if err != nil { + return err + } + // check whether the validator is valid, i.e., its power is positive - power := k.stakingKeeper.GetLastValidatorPower(ctx, validator.GetOperator()) + power, err := k.stakingKeeper.GetLastValidatorPower(ctx, valAddr) + if err != nil { + return err + } if 0 < power { // to enable multiple calls of AssignConsumerKey in the same block by the same validator @@ -658,10 +667,10 @@ func (k Keeper) IsConsumerProposedOrRegistered(ctx sdk.Context, chainID string) // In case it panics, the TX aborts and thus, the validator is not created. See AfterValidatorCreated hook. func (k Keeper) ValidatorConsensusKeyInUse(ctx sdk.Context, valAddr sdk.ValAddress) bool { // Get the validator being added in the staking module. - val, found := k.stakingKeeper.GetValidator(ctx, valAddr) - if !found { + val, err := k.stakingKeeper.GetValidator(ctx, valAddr) + if err != nil { // Abort TX, do NOT allow validator to be created - panic("did not find newly created validator in staking module") + panic(fmt.Errorf("error finding newly created validator in staking module: %s", err)) } // Get the consensus address of the validator being added diff --git a/x/ccv/provider/keeper/key_assignment_test.go b/x/ccv/provider/keeper/key_assignment_test.go index 4fab08c981..272b923ec7 100644 --- a/x/ccv/provider/keeper/key_assignment_test.go +++ b/x/ccv/provider/keeper/key_assignment_test.go @@ -16,11 +16,11 @@ import ( abci "github.com/cometbft/cometbft/abci/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" - cryptotestutil "github.com/cosmos/interchain-security/v4/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - providerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + cryptotestutil "github.com/cosmos/interchain-security/v5/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) func TestValidatorConsumerPubKeyCRUD(t *testing.T) { @@ -415,14 +415,14 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { }, { name: "1", - mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) { + mockSetup: func(sdkCtx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) { gomock.InOrder( - mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(sdkCtx, consumerIdentities[0].SDKValConsAddress(), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower( - ctx, providerIdentities[0].SDKValOpAddress(), - ).Return(int64(0)), + sdkCtx, providerIdentities[0].SDKValOpAddress(), + ).Return(int64(0), nil), ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { @@ -440,35 +440,36 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { }, { name: "2", - mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) { + mockSetup: func(sdkCtx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) { + ctx := sdk.WrapSDKContext(sdkCtx) gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, consumerIdentities[0].SDKValConsAddress(), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower( ctx, providerIdentities[0].SDKValOpAddress(), - ).Return(int64(0)), + ).Return(int64(0), nil), mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, consumerIdentities[1].SDKValConsAddress(), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower( ctx, providerIdentities[0].SDKValOpAddress(), - ).Return(int64(0)), + ).Return(int64(0), nil), ) }, - doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { - k.SetConsumerClientId(ctx, chainID, "") - err := k.AssignConsumerKey(ctx, chainID, + doActions: func(sdkCtx sdk.Context, k providerkeeper.Keeper) { + k.SetConsumerClientId(sdkCtx, chainID, "") + err := k.AssignConsumerKey(sdkCtx, chainID, providerIdentities[0].SDKStakingValidator(), consumerIdentities[0].TMProtoCryptoPublicKey(), ) require.NoError(t, err) - err = k.AssignConsumerKey(ctx, chainID, + err = k.AssignConsumerKey(sdkCtx, chainID, providerIdentities[0].SDKStakingValidator(), consumerIdentities[1].TMProtoCryptoPublicKey(), ) require.NoError(t, err) - providerAddr, found := k.GetValidatorByConsumerAddr(ctx, chainID, + providerAddr, found := k.GetValidatorByConsumerAddr(sdkCtx, chainID, consumerIdentities[1].ConsumerConsAddress()) require.True(t, found) require.Equal(t, providerIdentities[0].ProviderConsAddress(), providerAddr) @@ -480,13 +481,13 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, consumerIdentities[0].SDKValConsAddress(), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower( ctx, providerIdentities[0].SDKValOpAddress(), - ).Return(int64(0)), + ).Return(int64(0), nil), mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, consumerIdentities[0].SDKValConsAddress(), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { @@ -513,7 +514,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, providerIdentities[0].SDKValConsAddress(), - ).Return(providerIdentities[0].SDKStakingValidator(), true), + ).Return(providerIdentities[0].SDKStakingValidator(), nil), ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { @@ -531,7 +532,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, consumerIdentities[0].SDKValConsAddress(), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { @@ -553,10 +554,10 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, consumerIdentities[0].SDKValConsAddress(), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, consumerIdentities[1].SDKValConsAddress(), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { @@ -583,10 +584,10 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, consumerIdentities[0].SDKValConsAddress(), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, consumerIdentities[0].SDKValConsAddress(), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { @@ -613,7 +614,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, providerIdentities[0].SDKValConsAddress(), - ).Return(providerIdentities[0].SDKStakingValidator(), true), + ).Return(providerIdentities[0].SDKStakingValidator(), nil), ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { @@ -661,7 +662,7 @@ func TestCannotReassignDefaultKeyAssignment(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, cId.SDKValConsAddress(), - ).Return(cId.SDKStakingValidator(), true), // found = true + ).Return(cId.SDKStakingValidator(), nil), // nil == no error ) // AssignConsumerKey should return an error if we try to re-assign the already existing default key assignment @@ -801,7 +802,10 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { // When the mocked method is called, locate the appropriate validator // in the provider valset and return its power. for i, id := range providerIDS { - if id.SDKStakingValidator().GetOperator().Equals(valAddr) { + decodeValAddr, err := k.ValidatorAddressCodec().StringToBytes(id.SDKStakingValidator().GetOperator()) + require.NoError(t, err) + + if string(decodeValAddr) == valAddr.String() { return providerValset.power[i] } } diff --git a/x/ccv/provider/keeper/legacy_params.go b/x/ccv/provider/keeper/legacy_params.go new file mode 100644 index 0000000000..bea628e4ed --- /dev/null +++ b/x/ccv/provider/keeper/legacy_params.go @@ -0,0 +1,86 @@ +package keeper + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" +) + +// getTemplateClient returns the template client for provider proposals +func getTemplateClient(ctx sdk.Context, paramSpace paramtypes.Subspace) *ibctmtypes.ClientState { + var cs ibctmtypes.ClientState + paramSpace.Get(ctx, types.KeyTemplateClient, &cs) + return &cs +} + +// getTrustingPeriodFraction returns a TrustingPeriodFraction +// used to compute the provider IBC client's TrustingPeriod as UnbondingPeriod / TrustingPeriodFraction +func getTrustingPeriodFraction(ctx sdk.Context, paramSpace paramtypes.Subspace) string { + var f string + paramSpace.Get(ctx, types.KeyTrustingPeriodFraction, &f) + return f +} + +// getCCVTimeoutPeriod returns the timeout period for sent ibc packets +func getCCVTimeoutPeriod(ctx sdk.Context, paramSpace paramtypes.Subspace) time.Duration { + var p time.Duration + paramSpace.Get(ctx, ccvtypes.KeyCCVTimeoutPeriod, &p) + return p +} + +// getInitTimeoutPeriod returns the init timeout period +func getInitTimeoutPeriod(ctx sdk.Context, paramSpace paramtypes.Subspace) time.Duration { + var p time.Duration + paramSpace.Get(ctx, types.KeyInitTimeoutPeriod, &p) + return p +} + +// getVscTimeoutPeriod returns the vsc timeout period +func getVscTimeoutPeriod(ctx sdk.Context, paramSpace paramtypes.Subspace) time.Duration { + var p time.Duration + paramSpace.Get(ctx, types.KeyVscTimeoutPeriod, &p) + return p +} + +// getSlashMeterReplenishPeriod returns the period in which: +// Once the slash meter becomes not-full, the slash meter is replenished after this period. +func getSlashMeterReplenishPeriod(ctx sdk.Context, paramSpace paramtypes.Subspace) time.Duration { + var p time.Duration + paramSpace.Get(ctx, types.KeySlashMeterReplenishPeriod, &p) + return p +} + +// getSlashMeterReplenishFraction returns the string fraction of total voting power that is replenished +// to the slash meter every replenish period. This param also serves as a maximum fraction of total +// voting power that the slash meter can hold. +func getSlashMeterReplenishFraction(ctx sdk.Context, paramSpace paramtypes.Subspace) string { + var f string + paramSpace.Get(ctx, types.KeySlashMeterReplenishFraction, &f) + return f +} + +func getConsumerRewardDenomRegistrationFee(ctx sdk.Context, paramSpace paramtypes.Subspace) sdk.Coin { + var c sdk.Coin + paramSpace.Get(ctx, types.KeyConsumerRewardDenomRegistrationFee, &c) + return c +} + +// Legacy: Only for migration purposes. GetParamsLegacy returns the paramset for the provider +// module from a given param subspace +func GetParamsLegacy(ctx sdk.Context, paramspace paramtypes.Subspace) types.Params { + return types.NewParams( + getTemplateClient(ctx, paramspace), + getTrustingPeriodFraction(ctx, paramspace), + getCCVTimeoutPeriod(ctx, paramspace), + getInitTimeoutPeriod(ctx, paramspace), + getVscTimeoutPeriod(ctx, paramspace), + getSlashMeterReplenishPeriod(ctx, paramspace), + getSlashMeterReplenishFraction(ctx, paramspace), + getConsumerRewardDenomRegistrationFee(ctx, paramspace), + ) +} diff --git a/x/ccv/provider/keeper/legacy_proposal.go b/x/ccv/provider/keeper/legacy_proposal.go new file mode 100644 index 0000000000..2ea1353173 --- /dev/null +++ b/x/ccv/provider/keeper/legacy_proposal.go @@ -0,0 +1,85 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" +) + +func (k Keeper) HandleLegacyConsumerRewardDenomProposal(ctx sdk.Context, p *types.ChangeRewardDenomsProposal) error { + for _, denomToAdd := range p.DenomsToAdd { + // Log error and move on if one of the denoms is already registered + if k.ConsumerRewardDenomExists(ctx, denomToAdd) { + ctx.Logger().Error("denom %s already registered", denomToAdd) + continue + } + k.SetConsumerRewardDenom(ctx, denomToAdd) + ctx.EventManager().EmitEvent(sdk.NewEvent( + types.EventTypeAddConsumerRewardDenom, + sdk.NewAttribute(types.AttributeConsumerRewardDenom, denomToAdd), + )) + } + for _, denomToRemove := range p.DenomsToRemove { + // Log error and move on if one of the denoms is not registered + if !k.ConsumerRewardDenomExists(ctx, denomToRemove) { + ctx.Logger().Error("denom %s not registered", denomToRemove) + continue + } + k.DeleteConsumerRewardDenom(ctx, denomToRemove) + ctx.EventManager().EmitEvent(sdk.NewEvent( + types.EventTypeRemoveConsumerRewardDenom, + sdk.NewAttribute(types.AttributeConsumerRewardDenom, denomToRemove), + )) + } + return nil +} + +// [DEPRECATED] +// HandleConsumerAdditionProposal will receive the consumer chain's client state from the proposal. +// If the client can be successfully created in a cached context, it stores the proposal as a pending proposal. +// +// Note: This method implements SpawnConsumerChainProposalHandler in spec. +// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-hcaprop1 +// Spec tag: [CCV-PCF-HCAPROP.1] +func (k Keeper) HandleLegacyConsumerAdditionProposal(ctx sdk.Context, p *types.ConsumerAdditionProposal) error { + // verify the consumer addition proposal execution + // in cached context and discard the cached writes + if _, _, err := k.CreateConsumerClientInCachedCtx(ctx, *p); err != nil { + return err + } + + k.SetPendingConsumerAdditionProp(ctx, p) + + k.Logger(ctx).Info("consumer addition proposal enqueued", + "chainID", p.ChainId, + "title", p.Title, + "spawn time", p.SpawnTime.UTC(), + ) + + return nil +} + +// [DEPRECATED] +// HandleConsumerRemovalProposal stops a consumer chain and released the outstanding unbonding operations. +// If the consumer can be successfully stopped in a cached context, it stores the proposal as a pending proposal. +// +// This method implements StopConsumerChainProposalHandler from spec. +// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-hcrprop1 +// Spec tag: [CCV-PCF-HCRPROP.1] +func (k Keeper) HandleLegacyConsumerRemovalProposal(ctx sdk.Context, p *types.ConsumerRemovalProposal) error { + // verify the consumer removal proposal execution + // in cached context and discard the cached writes + if _, _, err := k.StopConsumerChainInCachedCtx(ctx, *p); err != nil { + return err + } + + k.SetPendingConsumerRemovalProp(ctx, p) + + k.Logger(ctx).Info("consumer removal proposal enqueued", + "chainID", p.ChainId, + "title", p.Title, + "stop time", p.StopTime.UTC(), + ) + + return nil +} diff --git a/x/ccv/provider/keeper/legacy_proposal_test.go b/x/ccv/provider/keeper/legacy_proposal_test.go new file mode 100644 index 0000000000..bc7abbc0c6 --- /dev/null +++ b/x/ccv/provider/keeper/legacy_proposal_test.go @@ -0,0 +1,256 @@ +package keeper_test + +import ( + "testing" + "time" + + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" +) + +// +// Initialization sub-protocol related tests of proposal.go +// + +// Tests the HandleConsumerAdditionProposal method against the SpawnConsumerChainProposalHandler spec. +// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-hcaprop1 +// Spec tag: [CCV-PCF-HCAPROP.1] +func TestHandleLegacyConsumerAdditionProposal(t *testing.T) { + type testCase struct { + description string + malleate func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) + prop *providertypes.ConsumerAdditionProposal + // Time when prop is handled + blockTime time.Time + // Whether it's expected that the proposal is successfully verified + // and appended to the pending proposals + expAppendProp bool + } + + // Snapshot times asserted in tests + now := time.Now().UTC() + + tests := []testCase{ + { + description: "expect to append valid proposal", + malleate: func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) {}, + prop: providertypes.NewConsumerAdditionProposal( + "title", + "description", + "chainID", + clienttypes.NewHeight(2, 3), + []byte("gen_hash"), + []byte("bin_hash"), + now, // Spawn time + "0.75", + 10, + "", + 10000, + 100000000000, + 100000000000, + 100000000000, + ).(*providertypes.ConsumerAdditionProposal), + blockTime: now, + expAppendProp: true, + }, + { + description: "expect to not append invalid proposal using an already existing chain id", + malleate: func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) { + k.SetConsumerClientId(ctx, chainID, "anyClientId") + }, + + prop: providertypes.NewConsumerAdditionProposal( + "title", + "description", + "chainID", + clienttypes.NewHeight(2, 3), + []byte("gen_hash"), + []byte("bin_hash"), + now, + "0.75", + 10, + "", + 10000, + 100000000000, + 100000000000, + 100000000000, + ).(*providertypes.ConsumerAdditionProposal), + blockTime: now, + expAppendProp: false, + }, + } + + for _, tc := range tests { + // Common setup + keeperParams := testkeeper.NewInMemKeeperParams(t) + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, keeperParams) + providerKeeper.SetParams(ctx, providertypes.DefaultParams()) + ctx = ctx.WithBlockTime(tc.blockTime) + + if tc.expAppendProp { + // Mock calls are only asserted if we expect a client to be created. + gomock.InOrder( + testkeeper.GetMocksForCreateConsumerClient(ctx, &mocks, tc.prop.ChainId, clienttypes.NewHeight(2, 3))..., + ) + } + + tc.malleate(ctx, providerKeeper, tc.prop.ChainId) + + err := providerKeeper.HandleLegacyConsumerAdditionProposal(ctx, tc.prop) + + if tc.expAppendProp { + require.NoError(t, err) + // check that prop was added to the stored pending props + gotProposal, found := providerKeeper.GetPendingConsumerAdditionProp(ctx, tc.prop.SpawnTime, tc.prop.ChainId) + require.True(t, found) + require.Equal(t, *tc.prop, gotProposal) + } else { + require.Error(t, err) + // check that prop wasn't added to the stored pending props + _, found := providerKeeper.GetPendingConsumerAdditionProp(ctx, tc.prop.SpawnTime, tc.prop.ChainId) + require.False(t, found) + } + + ctrl.Finish() + } +} + +// TestHandleConsumerRemovalProposal tests HandleConsumerRemovalProposal against its corresponding spec method. +// +// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-hcrprop1 +// Spec tag: [CCV-PCF-HCRPROP.1] +func TestHandleLegacyConsumerRemovalProposal(t *testing.T) { + type testCase struct { + description string + setupMocks func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) + + // Consumer removal proposal to handle + prop *providertypes.ConsumerRemovalProposal + // Time when prop is handled + blockTime time.Time + // Whether it's expected that the proposal is successfully verified + // and appended to the pending proposals + expAppendProp bool + + // chainID of the consumer chain + // tests need to check that the CCV channel is not closed prematurely + chainId string + } + + // Snapshot times asserted in tests + now := time.Now().UTC() + hourAfterNow := now.Add(time.Hour).UTC() + hourBeforeNow := now.Add(-time.Hour).UTC() + + tests := []testCase{ + { + description: "valid proposal", + setupMocks: func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) { + k.SetConsumerClientId(ctx, chainID, "ClientID") + }, + prop: providertypes.NewConsumerRemovalProposal( + "title", + "description", + "chainID", + now, + ).(*providertypes.ConsumerRemovalProposal), + blockTime: hourAfterNow, // After stop time. + expAppendProp: true, + chainId: "chainID", + }, + { + description: "valid proposal - stop_time in the past", + setupMocks: func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) { + k.SetConsumerClientId(ctx, chainID, "ClientID") + }, + prop: providertypes.NewConsumerRemovalProposal( + "title", + "description", + "chainID", + hourBeforeNow, + ).(*providertypes.ConsumerRemovalProposal), + blockTime: hourAfterNow, // After stop time. + expAppendProp: true, + chainId: "chainID", + }, + { + description: "valid proposal - before stop_time in the future", + setupMocks: func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) { + k.SetConsumerClientId(ctx, chainID, "ClientID") + }, + prop: providertypes.NewConsumerRemovalProposal( + "title", + "description", + "chainID", + hourAfterNow, + ).(*providertypes.ConsumerRemovalProposal), + blockTime: now, + expAppendProp: true, + chainId: "chainID", + }, + { + description: "rejected valid proposal - consumer chain does not exist", + setupMocks: func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) {}, + prop: providertypes.NewConsumerRemovalProposal( + "title", + "description", + "chainID-2", + hourAfterNow, + ).(*providertypes.ConsumerRemovalProposal), + blockTime: hourAfterNow, // After stop time. + expAppendProp: false, + chainId: "chainID-2", + }, + } + + for _, tc := range tests { + + // Common setup + keeperParams := testkeeper.NewInMemKeeperParams(t) + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, keeperParams) + providerKeeper.SetParams(ctx, providertypes.DefaultParams()) + ctx = ctx.WithBlockTime(tc.blockTime) + + // Mock expectations and setup for stopping the consumer chain, if applicable + // Note: when expAppendProp is false, no mocks are setup, + // meaning no external keeper methods are allowed to be called. + if tc.expAppendProp { + testkeeper.SetupForStoppingConsumerChain(t, ctx, &providerKeeper, mocks) + + // assert mocks for expected calls to `StopConsumerChain` when closing the underlying channel + gomock.InOrder(testkeeper.GetMocksForStopConsumerChainWithCloseChannel(ctx, &mocks)...) + } + + tc.setupMocks(ctx, providerKeeper, tc.prop.ChainId) + + err := providerKeeper.HandleLegacyConsumerRemovalProposal(ctx, tc.prop) + + if tc.expAppendProp { + require.NoError(t, err) + + // Proposal should be stored as pending + found := providerKeeper.PendingConsumerRemovalPropExists(ctx, tc.prop.ChainId, tc.prop.StopTime) + require.True(t, found) + + // confirm that the channel was not closed + _, found = providerKeeper.GetChainToChannel(ctx, tc.chainId) + require.True(t, found) + } else { + require.Error(t, err) + + // Expect no pending proposal to exist + found := providerKeeper.PendingConsumerRemovalPropExists(ctx, tc.prop.ChainId, tc.prop.StopTime) + require.False(t, found) + } + + // Assert mock calls from setup function + ctrl.Finish() + } +} diff --git a/x/ccv/provider/keeper/msg_server.go b/x/ccv/provider/keeper/msg_server.go index 9a27d1d144..0a5ba95368 100644 --- a/x/ccv/provider/keeper/msg_server.go +++ b/x/ccv/provider/keeper/msg_server.go @@ -8,13 +8,14 @@ import ( cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" tmtypes "github.com/cometbft/cometbft/types" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) type msgServer struct { @@ -29,6 +30,18 @@ func NewMsgServerImpl(keeper *Keeper) types.MsgServer { var _ types.MsgServer = msgServer{} +// UpdateParams updates the params. +func (k msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + if k.GetAuthority() != msg.Authority { + return nil, errorsmod.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", k.authority, msg.Authority) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + k.Keeper.SetParams(ctx, msg.Params) + + return &types.MsgUpdateParamsResponse{}, nil +} + // AssignConsumerKey defines a method to assign a consensus key on a consumer chain // for a given validator on the provider func (k msgServer) AssignConsumerKey(goCtx context.Context, msg *types.MsgAssignConsumerKey) (*types.MsgAssignConsumerKeyResponse, error) { @@ -40,9 +53,11 @@ func (k msgServer) AssignConsumerKey(goCtx context.Context, msg *types.MsgAssign } // validator must already be registered - validator, found := k.stakingKeeper.GetValidator(ctx, providerValidatorAddr) - if !found { + validator, err := k.stakingKeeper.GetValidator(ctx, providerValidatorAddr) + if err != nil && err == stakingtypes.ErrNoValidatorFound { return nil, stakingtypes.ErrNoValidatorFound + } else if err != nil { + return nil, err } // parse consumer key as long as it's in the right format @@ -106,6 +121,52 @@ func (k msgServer) AssignConsumerKey(goCtx context.Context, msg *types.MsgAssign return &types.MsgAssignConsumerKeyResponse{}, nil } +// ConsumerAddition defines a rpc handler method for MsgConsumerAddition +func (k msgServer) ConsumerAddition(goCtx context.Context, msg *types.MsgConsumerAddition) (*types.MsgConsumerAdditionResponse, error) { + if k.GetAuthority() != msg.Authority { + return nil, errorsmod.Wrapf(types.ErrUnauthorized, "expected %s, got %s", k.GetAuthority(), msg.Authority) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + err := k.Keeper.HandleConsumerAdditionProposal(ctx, msg) + if err != nil { + return nil, errorsmod.Wrapf(err, "failed handling ConsumerAddition proposal") + } + return &types.MsgConsumerAdditionResponse{}, nil +} + +// ConsumerRemoval defines a rpc handler method for MsgConsumerRemoval +func (k msgServer) ConsumerRemoval( + goCtx context.Context, + msg *types.MsgConsumerRemoval) (*types.MsgConsumerRemovalResponse, error) { + if k.GetAuthority() != msg.Authority { + return nil, errorsmod.Wrapf(types.ErrUnauthorized, "expected %s, got %s", k.GetAuthority(), msg.Authority) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + err := k.Keeper.HandleConsumerRemovalProposal(ctx, msg) + if err != nil { + return nil, errorsmod.Wrapf(err, "failed handling ConsumerAddition proposal") + } + + return &types.MsgConsumerRemovalResponse{}, nil +} + +// ChangeRewardDenoms defines a rpc handler method for MsgChangeRewardDenoms +func (k msgServer) ChangeRewardDenoms(goCtx context.Context, msg *types.MsgChangeRewardDenoms) (*types.MsgChangeRewardDenomsResponse, error) { + if k.GetAuthority() != msg.Authority { + return nil, errorsmod.Wrapf(types.ErrUnauthorized, "expected %s, got %s", k.GetAuthority(), msg.Authority) + } + + sdkCtx := sdk.UnwrapSDKContext(goCtx) + err := k.Keeper.HandleConsumerRewardDenomProposal(sdkCtx, msg) + if err != nil { + return nil, errorsmod.Wrapf(err, "failed handling Change Reward Denoms proposal") + } + + return &types.MsgChangeRewardDenomsResponse{}, nil +} + func (k msgServer) SubmitConsumerMisbehaviour(goCtx context.Context, msg *types.MsgSubmitConsumerMisbehaviour) (*types.MsgSubmitConsumerMisbehaviourResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) if err := k.Keeper.HandleConsumerMisbehaviour(ctx, *msg.Misbehaviour); err != nil { diff --git a/x/ccv/provider/keeper/params.go b/x/ccv/provider/keeper/params.go index 209d0f0ddb..bb3962dbb2 100644 --- a/x/ccv/provider/keeper/params.go +++ b/x/ccv/provider/keeper/params.go @@ -1,98 +1,92 @@ package keeper import ( + "fmt" "time" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) // GetTemplateClient returns the template client for provider proposals func (k Keeper) GetTemplateClient(ctx sdk.Context) *ibctmtypes.ClientState { - var cs ibctmtypes.ClientState - k.paramSpace.Get(ctx, types.KeyTemplateClient, &cs) - return &cs + params := k.GetParams(ctx) + return params.TemplateClient } // GetTrustingPeriodFraction returns a TrustingPeriodFraction // used to compute the provider IBC client's TrustingPeriod as UnbondingPeriod / TrustingPeriodFraction func (k Keeper) GetTrustingPeriodFraction(ctx sdk.Context) string { - var f string - k.paramSpace.Get(ctx, types.KeyTrustingPeriodFraction, &f) - return f + params := k.GetParams(ctx) + return params.TrustingPeriodFraction } // GetCCVTimeoutPeriod returns the timeout period for sent ibc packets func (k Keeper) GetCCVTimeoutPeriod(ctx sdk.Context) time.Duration { - var p time.Duration - k.paramSpace.Get(ctx, ccvtypes.KeyCCVTimeoutPeriod, &p) - return p + params := k.GetParams(ctx) + return params.CcvTimeoutPeriod } // GetInitTimeoutPeriod returns the init timeout period func (k Keeper) GetInitTimeoutPeriod(ctx sdk.Context) time.Duration { - var p time.Duration - k.paramSpace.Get(ctx, types.KeyInitTimeoutPeriod, &p) - return p + params := k.GetParams(ctx) + return params.InitTimeoutPeriod } // GetVscTimeoutPeriod returns the vsc timeout period func (k Keeper) GetVscTimeoutPeriod(ctx sdk.Context) time.Duration { - var p time.Duration - k.paramSpace.Get(ctx, types.KeyVscTimeoutPeriod, &p) - return p + params := k.GetParams(ctx) + return params.VscTimeoutPeriod } // SetVscTimeoutPeriod sets the vsc timeout period func (k Keeper) SetVscTimeoutPeriod(ctx sdk.Context, period time.Duration) { - k.paramSpace.Set(ctx, types.KeyVscTimeoutPeriod, period) + params := k.GetParams(ctx) + params.VscTimeoutPeriod = period + k.SetParams(ctx, params) } // GetSlashMeterReplenishPeriod returns the period in which: // Once the slash meter becomes not-full, the slash meter is replenished after this period. func (k Keeper) GetSlashMeterReplenishPeriod(ctx sdk.Context) time.Duration { - var p time.Duration - k.paramSpace.Get(ctx, types.KeySlashMeterReplenishPeriod, &p) - return p + params := k.GetParams(ctx) + return params.SlashMeterReplenishPeriod } // GetSlashMeterReplenishFraction returns the string fraction of total voting power that is replenished // to the slash meter every replenish period. This param also serves as a maximum fraction of total // voting power that the slash meter can hold. func (k Keeper) GetSlashMeterReplenishFraction(ctx sdk.Context) string { - var f string - k.paramSpace.Get(ctx, types.KeySlashMeterReplenishFraction, &f) - return f + params := k.GetParams(ctx) + return params.SlashMeterReplenishFraction } func (k Keeper) GetConsumerRewardDenomRegistrationFee(ctx sdk.Context) sdk.Coin { // Due to difficulties doing migrations in coordinated upgrades, this param is hardcoded to 10 ATOM in v1.1.0-multiden. // The below code is the proper way to store the param. A future scheduled upgrade will // need to run migrations to add the param. This will allow us to change the fee by governance. - var c sdk.Coin - k.paramSpace.Get(ctx, types.KeyConsumerRewardDenomRegistrationFee, &c) - return c + params := k.GetParams(ctx) + return params.ConsumerRewardDenomRegistrationFee } // GetParams returns the paramset for the provider module func (k Keeper) GetParams(ctx sdk.Context) types.Params { - return types.NewParams( - k.GetTemplateClient(ctx), - k.GetTrustingPeriodFraction(ctx), - k.GetCCVTimeoutPeriod(ctx), - k.GetInitTimeoutPeriod(ctx), - k.GetVscTimeoutPeriod(ctx), - k.GetSlashMeterReplenishPeriod(ctx), - k.GetSlashMeterReplenishFraction(ctx), - k.GetConsumerRewardDenomRegistrationFee(ctx), - ) + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.ParametersKey()) + var params types.Params + err := k.cdc.Unmarshal(bz, ¶ms) + if err != nil { + panic(fmt.Sprintf("error unmarshalling module parameters: %v:", err)) + } + return params } // SetParams sets the params for the provider module func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { - k.paramSpace.SetParamSet(ctx, ¶ms) + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(¶ms) + store.Set(types.ParametersKey(), bz) } diff --git a/x/ccv/provider/keeper/params_test.go b/x/ccv/provider/keeper/params_test.go index a941523e87..6dd030418e 100644 --- a/x/ccv/provider/keeper/params_test.go +++ b/x/ccv/provider/keeper/params_test.go @@ -4,15 +4,16 @@ import ( "testing" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + "cosmossdk.io/math" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) // TestParams tests the getting/setting of provider ccv module params. @@ -46,7 +47,7 @@ func TestParams(t *testing.T) { "0.4", sdk.Coin{ Denom: "stake", - Amount: sdk.NewInt(10000000), + Amount: math.NewInt(10000000), }, ) providerKeeper.SetParams(ctx, newParams) diff --git a/x/ccv/provider/keeper/proposal.go b/x/ccv/provider/keeper/proposal.go index 89d71ff344..9036f27cb1 100644 --- a/x/ccv/provider/keeper/proposal.go +++ b/x/ccv/provider/keeper/proposal.go @@ -1,16 +1,18 @@ package keeper import ( + "errors" "fmt" "strconv" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" errorsmod "cosmossdk.io/errors" + storetypes "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -19,32 +21,50 @@ import ( abci "github.com/cometbft/cometbft/abci/types" tmtypes "github.com/cometbft/cometbft/types" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) -// HandleConsumerAdditionProposal will receive the consumer chain's client state from the proposal. -// If the client can be successfully created in a cached context, it stores the proposal as a pending proposal. -// -// Note: This method implements SpawnConsumerChainProposalHandler in spec. -// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-hcaprop1 -// Spec tag: [CCV-PCF-HCAPROP.1] -func (k Keeper) HandleConsumerAdditionProposal(ctx sdk.Context, p *types.ConsumerAdditionProposal) error { - // verify the consumer addition proposal execution - // in cached context and discard the cached writes - if _, _, err := k.CreateConsumerClientInCachedCtx(ctx, *p); err != nil { - return err +// Wrapper for the new proposal message MsgConsumerAddition +// Will replace legacy handler HandleLegacyConsumerAdditionProposal +func (k Keeper) HandleConsumerAdditionProposal(ctx sdk.Context, proposal *types.MsgConsumerAddition) error { + p := types.ConsumerAdditionProposal{ + ChainId: proposal.ChainId, + InitialHeight: proposal.InitialHeight, + GenesisHash: proposal.GenesisHash, + BinaryHash: proposal.BinaryHash, + SpawnTime: proposal.SpawnTime, + UnbondingPeriod: proposal.UnbondingPeriod, + CcvTimeoutPeriod: proposal.CcvTimeoutPeriod, + TransferTimeoutPeriod: proposal.TransferTimeoutPeriod, + ConsumerRedistributionFraction: proposal.ConsumerRedistributionFraction, + BlocksPerDistributionTransmission: proposal.BlocksPerDistributionTransmission, + HistoricalEntries: proposal.HistoricalEntries, + DistributionTransmissionChannel: proposal.DistributionTransmissionChannel, } + return k.HandleLegacyConsumerAdditionProposal(ctx, &p) - k.SetPendingConsumerAdditionProp(ctx, p) +} - k.Logger(ctx).Info("consumer addition proposal enqueued", - "chainID", p.ChainId, - "title", p.Title, - "spawn time", p.SpawnTime.UTC(), - ) +// Wrapper for the new proposal message MsgConsumerRemoval +// Will replace legacy handler HandleLegacyConsumerRemovalProposal +func (k Keeper) HandleConsumerRemovalProposal(ctx sdk.Context, proposal *types.MsgConsumerRemoval) error { + p := types.ConsumerRemovalProposal{ + ChainId: proposal.ChainId, + StopTime: proposal.StopTime, + } + return k.HandleLegacyConsumerRemovalProposal(ctx, &p) - return nil +} + +// Wrapper for the new proposal message MsgChangeRewardDenoms +// Will replace legacy handler HandleLegacyConsumerRewardDenomProposal +func (k Keeper) HandleConsumerRewardDenomProposal(ctx sdk.Context, proposal *types.MsgChangeRewardDenoms) error { + p := types.ChangeRewardDenomsProposal{ + DenomsToAdd: proposal.DenomsToAdd, + DenomsToRemove: proposal.DenomsToRemove, + } + return k.HandleLegacyConsumerRewardDenomProposal(ctx, &p) } // CreateConsumerClient will create the CCV client for the given consumer chain. The CCV channel must be built @@ -122,30 +142,6 @@ func (k Keeper) CreateConsumerClient(ctx sdk.Context, prop *types.ConsumerAdditi return nil } -// HandleConsumerRemovalProposal stops a consumer chain and released the outstanding unbonding operations. -// If the consumer can be successfully stopped in a cached context, it stores the proposal as a pending proposal. -// -// This method implements StopConsumerChainProposalHandler from spec. -// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-hcrprop1 -// Spec tag: [CCV-PCF-HCRPROP.1] -func (k Keeper) HandleConsumerRemovalProposal(ctx sdk.Context, p *types.ConsumerRemovalProposal) error { - // verify the consumer removal proposal execution - // in cached context and discard the cached writes - if _, _, err := k.StopConsumerChainInCachedCtx(ctx, *p); err != nil { - return err - } - - k.SetPendingConsumerRemovalProp(ctx, p) - - k.Logger(ctx).Info("consumer removal proposal enqueued", - "chainID", p.ChainId, - "title", p.Title, - "stop time", p.StopTime.UTC(), - ) - - return nil -} - // StopConsumerChain cleans up the states for the given consumer chain ID and // completes the outstanding unbonding operations on the consumer chain. // @@ -225,7 +221,10 @@ func (k Keeper) MakeConsumerGenesis( prop *types.ConsumerAdditionProposal, ) (gen ccv.ConsumerGenesisState, nextValidatorsHash []byte, err error) { chainID := prop.ChainId - providerUnbondingPeriod := k.stakingKeeper.UnbondingTime(ctx) + providerUnbondingPeriod, err := k.stakingKeeper.UnbondingTime(ctx) + if err != nil { + return gen, nil, errorsmod.Wrapf(types.ErrNoUnbondingTime, "unbonding time not found: %s", err) + } height := clienttypes.GetSelfHeight(ctx) clientState := k.GetTemplateClient(ctx) @@ -260,12 +259,14 @@ func (k Keeper) MakeConsumerGenesis( return gen, nil, err } - val, found := k.stakingKeeper.GetValidator(ctx, addr) - if !found { - return gen, nil, errorsmod.Wrapf(stakingtypes.ErrNoValidatorFound, "error getting validator from LastValidatorPowers: %s", err) + val, err := k.stakingKeeper.GetValidator(ctx, addr) + if err != nil && errors.Is(err, stakingtypes.ErrNoValidatorFound) { + return gen, nil, errorsmod.Wrapf(stakingtypes.ErrNoValidatorFound, "error getting validator from LastValidatorPowers") + } else if err != nil { + return gen, nil, errorsmod.Wrapf(err, "error getting validator from LastValidatorPowers") } - tmProtoPk, err := val.TmConsPublicKey() + tmProtoPk, err := val.CmtConsPublicKey() if err != nil { return gen, nil, err } @@ -388,7 +389,8 @@ func (k Keeper) BeginBlockInit(ctx sdk.Context) { // Note: this method is split out from BeginBlockInit to be easily unit tested. func (k Keeper) GetConsumerAdditionPropsToExecute(ctx sdk.Context) (propsToExecute []types.ConsumerAdditionProposal) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.PendingCAPBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.PendingCAPBytePrefix}) + defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -418,7 +420,8 @@ func (k Keeper) GetConsumerAdditionPropsToExecute(ctx sdk.Context) (propsToExecu // then they are ordered by chainID. func (k Keeper) GetAllPendingConsumerAdditionProps(ctx sdk.Context) (props []types.ConsumerAdditionProposal) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.PendingCAPBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.PendingCAPBytePrefix}) + defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -526,7 +529,7 @@ func (k Keeper) GetConsumerRemovalPropsToExecute(ctx sdk.Context) []types.Consum propsToExecute := []types.ConsumerRemovalProposal{} store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.PendingCRPBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.PendingCRPBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -557,7 +560,7 @@ func (k Keeper) GetConsumerRemovalPropsToExecute(ctx sdk.Context) []types.Consum // Thus, the returned array is in stopTime order. func (k Keeper) GetAllPendingConsumerRemovalProps(ctx sdk.Context) (props []types.ConsumerRemovalProposal) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, []byte{types.PendingCRPBytePrefix}) + iterator := storetypes.KVStorePrefixIterator(store, []byte{types.PendingCRPBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -590,31 +593,3 @@ func (k Keeper) StopConsumerChainInCachedCtx(ctx sdk.Context, p types.ConsumerRe err = k.StopConsumerChain(cc, p.ChainId, true) return } - -func (k Keeper) HandleConsumerRewardDenomProposal(ctx sdk.Context, p *types.ChangeRewardDenomsProposal) error { - for _, denomToAdd := range p.DenomsToAdd { - // Log error and move on if one of the denoms is already registered - if k.ConsumerRewardDenomExists(ctx, denomToAdd) { - ctx.Logger().Error("denom %s already registered", denomToAdd) - continue - } - k.SetConsumerRewardDenom(ctx, denomToAdd) - ctx.EventManager().EmitEvent(sdk.NewEvent( - types.EventTypeAddConsumerRewardDenom, - sdk.NewAttribute(types.AttributeConsumerRewardDenom, denomToAdd), - )) - } - for _, denomToRemove := range p.DenomsToRemove { - // Log error and move on if one of the denoms is not registered - if !k.ConsumerRewardDenomExists(ctx, denomToRemove) { - ctx.Logger().Error("denom %s not registered", denomToRemove) - continue - } - k.DeleteConsumerRewardDenom(ctx, denomToRemove) - ctx.EventManager().EmitEvent(sdk.NewEvent( - types.EventTypeRemoveConsumerRewardDenom, - sdk.NewAttribute(types.AttributeConsumerRewardDenom, denomToRemove), - )) - } - return nil -} diff --git a/x/ccv/provider/keeper/proposal_test.go b/x/ccv/provider/keeper/proposal_test.go index e78823899a..6105568a9b 100644 --- a/x/ccv/provider/keeper/proposal_test.go +++ b/x/ccv/provider/keeper/proposal_test.go @@ -7,8 +7,9 @@ import ( "testing" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + "cosmossdk.io/math" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" _go "github.com/cosmos/ics23/go" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" @@ -17,119 +18,16 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - providerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // // Initialization sub-protocol related tests of proposal.go // -// Tests the HandleConsumerAdditionProposal method against the SpawnConsumerChainProposalHandler spec. -// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-hcaprop1 -// Spec tag: [CCV-PCF-HCAPROP.1] -func TestHandleConsumerAdditionProposal(t *testing.T) { - type testCase struct { - description string - malleate func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) - prop *providertypes.ConsumerAdditionProposal - // Time when prop is handled - blockTime time.Time - // Whether it's expected that the proposal is successfully verified - // and appended to the pending proposals - expAppendProp bool - } - - // Snapshot times asserted in tests - now := time.Now().UTC() - - tests := []testCase{ - { - description: "expect to append valid proposal", - malleate: func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) {}, - prop: providertypes.NewConsumerAdditionProposal( - "title", - "description", - "chainID", - clienttypes.NewHeight(2, 3), - []byte("gen_hash"), - []byte("bin_hash"), - now, // Spawn time - "0.75", - 10, - "", - 10000, - 100000000000, - 100000000000, - 100000000000, - ).(*providertypes.ConsumerAdditionProposal), - blockTime: now, - expAppendProp: true, - }, - { - description: "expect to not append invalid proposal using an already existing chain id", - malleate: func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) { - k.SetConsumerClientId(ctx, chainID, "anyClientId") - }, - - prop: providertypes.NewConsumerAdditionProposal( - "title", - "description", - "chainID", - clienttypes.NewHeight(2, 3), - []byte("gen_hash"), - []byte("bin_hash"), - now, - "0.75", - 10, - "", - 10000, - 100000000000, - 100000000000, - 100000000000, - ).(*providertypes.ConsumerAdditionProposal), - blockTime: now, - expAppendProp: false, - }, - } - - for _, tc := range tests { - // Common setup - keeperParams := testkeeper.NewInMemKeeperParams(t) - providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, keeperParams) - providerKeeper.SetParams(ctx, providertypes.DefaultParams()) - ctx = ctx.WithBlockTime(tc.blockTime) - - if tc.expAppendProp { - // Mock calls are only asserted if we expect a client to be created. - gomock.InOrder( - testkeeper.GetMocksForCreateConsumerClient(ctx, &mocks, tc.prop.ChainId, clienttypes.NewHeight(2, 3))..., - ) - } - - tc.malleate(ctx, providerKeeper, tc.prop.ChainId) - - err := providerKeeper.HandleConsumerAdditionProposal(ctx, tc.prop) - - if tc.expAppendProp { - require.NoError(t, err) - // check that prop was added to the stored pending props - gotProposal, found := providerKeeper.GetPendingConsumerAdditionProp(ctx, tc.prop.SpawnTime, tc.prop.ChainId) - require.True(t, found) - require.Equal(t, *tc.prop, gotProposal) - } else { - require.Error(t, err) - // check that prop wasn't added to the stored pending props - _, found := providerKeeper.GetPendingConsumerAdditionProp(ctx, tc.prop.SpawnTime, tc.prop.ChainId) - require.False(t, found) - } - - ctrl.Finish() - } -} - // Tests the CreateConsumerClient method against the spec, // with more granularity than what's covered in TestHandleCreateConsumerChainProposal. // See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-crclient1 @@ -370,141 +268,8 @@ func TestGetAllConsumerAdditionProps(t *testing.T) { // Consumer Chain Removal sub-protocol related tests of proposal.go // -// TestHandleConsumerRemovalProposal tests HandleConsumerRemovalProposal against its corresponding spec method. -// -// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-hcrprop1 -// Spec tag: [CCV-PCF-HCRPROP.1] -func TestHandleConsumerRemovalProposal(t *testing.T) { - type testCase struct { - description string - setupMocks func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) - - // Consumer removal proposal to handle - prop *providertypes.ConsumerRemovalProposal - // Time when prop is handled - blockTime time.Time - // Whether it's expected that the proposal is successfully verified - // and appended to the pending proposals - expAppendProp bool - - // chainID of the consumer chain - // tests need to check that the CCV channel is not closed prematurely - chainId string - } - - // Snapshot times asserted in tests - now := time.Now().UTC() - hourAfterNow := now.Add(time.Hour).UTC() - hourBeforeNow := now.Add(-time.Hour).UTC() - - tests := []testCase{ - { - description: "valid proposal", - setupMocks: func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) { - k.SetConsumerClientId(ctx, chainID, "ClientID") - }, - prop: providertypes.NewConsumerRemovalProposal( - "title", - "description", - "chainID", - now, - ).(*providertypes.ConsumerRemovalProposal), - blockTime: hourAfterNow, // After stop time. - expAppendProp: true, - chainId: "chainID", - }, - { - description: "valid proposal - stop_time in the past", - setupMocks: func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) { - k.SetConsumerClientId(ctx, chainID, "ClientID") - }, - prop: providertypes.NewConsumerRemovalProposal( - "title", - "description", - "chainID", - hourBeforeNow, - ).(*providertypes.ConsumerRemovalProposal), - blockTime: hourAfterNow, // After stop time. - expAppendProp: true, - chainId: "chainID", - }, - { - description: "valid proposal - before stop_time in the future", - setupMocks: func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) { - k.SetConsumerClientId(ctx, chainID, "ClientID") - }, - prop: providertypes.NewConsumerRemovalProposal( - "title", - "description", - "chainID", - hourAfterNow, - ).(*providertypes.ConsumerRemovalProposal), - blockTime: now, - expAppendProp: true, - chainId: "chainID", - }, - { - description: "rejected valid proposal - consumer chain does not exist", - setupMocks: func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) {}, - prop: providertypes.NewConsumerRemovalProposal( - "title", - "description", - "chainID-2", - hourAfterNow, - ).(*providertypes.ConsumerRemovalProposal), - blockTime: hourAfterNow, // After stop time. - expAppendProp: false, - chainId: "chainID-2", - }, - } - - for _, tc := range tests { - - // Common setup - keeperParams := testkeeper.NewInMemKeeperParams(t) - providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, keeperParams) - providerKeeper.SetParams(ctx, providertypes.DefaultParams()) - ctx = ctx.WithBlockTime(tc.blockTime) - - // Mock expectations and setup for stopping the consumer chain, if applicable - // Note: when expAppendProp is false, no mocks are setup, - // meaning no external keeper methods are allowed to be called. - if tc.expAppendProp { - testkeeper.SetupForStoppingConsumerChain(t, ctx, &providerKeeper, mocks) - - // assert mocks for expected calls to `StopConsumerChain` when closing the underlying channel - gomock.InOrder(testkeeper.GetMocksForStopConsumerChainWithCloseChannel(ctx, &mocks)...) - } - - tc.setupMocks(ctx, providerKeeper, tc.prop.ChainId) - - err := providerKeeper.HandleConsumerRemovalProposal(ctx, tc.prop) - - if tc.expAppendProp { - require.NoError(t, err) - - // Proposal should be stored as pending - found := providerKeeper.PendingConsumerRemovalPropExists(ctx, tc.prop.ChainId, tc.prop.StopTime) - require.True(t, found) - - // confirm that the channel was not closed - _, found = providerKeeper.GetChainToChannel(ctx, tc.chainId) - require.True(t, found) - } else { - require.Error(t, err) - - // Expect no pending proposal to exist - found := providerKeeper.PendingConsumerRemovalPropExists(ctx, tc.prop.ChainId, tc.prop.StopTime) - require.False(t, found) - } - - // Assert mock calls from setup function - ctrl.Finish() - } -} - // Tests the StopConsumerChain method against the spec, -// with more granularity than what's covered in TestHandleConsumerRemovalProposal, or integration tests. +// with more granularity than what's covered in TestHandleLegacyConsumerRemovalProposal, or integration tests. // See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-stcc1 // Spec tag: [CCV-PCF-STCC.1] func TestStopConsumerChain(t *testing.T) { @@ -773,7 +538,7 @@ func TestMakeConsumerGenesis(t *testing.T) { SlashMeterReplenishFraction: providertypes.DefaultSlashMeterReplenishFraction, ConsumerRewardDenomRegistrationFee: sdk.Coin{ Denom: "stake", - Amount: sdk.NewInt(1000000), + Amount: math.NewInt(1000000), }, } providerKeeper.SetParams(ctx, moduleParams) diff --git a/x/ccv/provider/keeper/relay.go b/x/ccv/provider/keeper/relay.go index 59fec69534..75b49ded0c 100644 --- a/x/ccv/provider/keeper/relay.go +++ b/x/ccv/provider/keeper/relay.go @@ -1,19 +1,20 @@ package keeper import ( + "errors" "fmt" "strconv" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // OnRecvVSCMaturedPacket handles a VSCMatured packet and returns a no-op result ack. @@ -88,10 +89,10 @@ func (k Keeper) completeMaturedUnbondingOps(ctx sdk.Context) { // Attempt to complete unbonding in staking module err := k.stakingKeeper.UnbondingCanComplete(ctx, id) if err != nil { - if stakingtypes.ErrUnbondingNotFound.Is(err) { + if errors.Is(err, stakingtypes.ErrNoUnbondingDelegation) { // The unbonding was not found. - unbondingType, found := k.stakingKeeper.GetUnbondingType(ctx, id) - if found && unbondingType == stakingtypes.UnbondingType_UnbondingDelegation { + unbondingType, errGet := k.stakingKeeper.GetUnbondingType(ctx, id) + if errGet == nil && unbondingType == stakingtypes.UnbondingType_UnbondingDelegation { // If this is an unbonding delegation, it may have been removed // after through a CancelUnbondingDelegation message k.Logger(ctx).Debug("unbonding delegation was already removed:", "unbondingID", id) @@ -185,7 +186,7 @@ func (k Keeper) SendVSCPacketsToChain(ctx sdk.Context, chainID, channelID string k.GetCCVTimeoutPeriod(ctx), ) if err != nil { - if clienttypes.ErrClientNotActive.Is(err) { + if errors.Is(err, clienttypes.ErrClientNotActive) { // IBC client is expired! // leave the packet data stored to be sent once the client is upgraded // the client cannot expire during iteration (in the middle of a block) @@ -215,7 +216,12 @@ func (k Keeper) QueueVSCPackets(ctx sdk.Context) { // Get the validator updates from the staking module. // Note: GetValidatorUpdates panics if the updates provided by the x/staking module // of cosmos-sdk is invalid. - stakingValUpdates := k.stakingKeeper.GetValidatorUpdates(ctx) + stakingValUpdates, err := k.stakingKeeper.GetValidatorUpdates(ctx) + + // NOTE: attempted to maintan the panic behaviour while migrating cosmos-sdk v47 -> v50 + if err != nil { + panic(fmt.Errorf("could not get validator updates from staking module: %w", err)) + } for _, chain := range k.GetAllConsumerChains(ctx) { // Apply the key assignment to the validator updates. @@ -387,16 +393,20 @@ func (k Keeper) HandleSlashPacket(ctx sdk.Context, chainID string, data ccv.Slas ) // Obtain validator from staking keeper - validator, found := k.stakingKeeper.GetValidatorByConsAddr(ctx, providerConsAddr.ToSdkConsAddr()) + validator, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, providerConsAddr.ToSdkConsAddr()) + if err != nil && errors.Is(err, stakingtypes.ErrNoValidatorFound) { + k.Logger(ctx).Error("validator not found", "validator", providerConsAddr.String()) + return + } // make sure the validator is not yet unbonded; // stakingKeeper.Slash() panics otherwise - if !found || validator.IsUnbonded() { + if validator.IsUnbonded() { // if validator is not found or is unbonded, drop slash packet and log error. // Note that it is impossible for the validator to be not found or unbonded if both the provider // and the consumer are following the protocol. Thus if this branch is taken then one or both // chains is incorrect, but it is impossible to tell which. - k.Logger(ctx).Error("validator not found or is unbonded", "validator", providerConsAddr.String()) + k.Logger(ctx).Error("validator already unbonded", "validator", providerConsAddr.String()) return } @@ -428,8 +438,13 @@ func (k Keeper) HandleSlashPacket(ctx sdk.Context, chainID string, data ccv.Slas if !validator.IsJailed() { k.stakingKeeper.Jail(ctx, providerConsAddr.ToSdkConsAddr()) k.Logger(ctx).Info("validator jailed", "provider cons addr", providerConsAddr.String()) - jailTime := ctx.BlockTime().Add(k.slashingKeeper.DowntimeJailDuration(ctx)) - k.slashingKeeper.JailUntil(ctx, providerConsAddr.ToSdkConsAddr(), jailTime) + jailDuration, err := k.slashingKeeper.DowntimeJailDuration(ctx) + if err != nil { + k.Logger(ctx).Error("failed to get jail duration", "err", err.Error()) + return + } + jailEndTime := ctx.BlockTime().Add(jailDuration) + k.slashingKeeper.JailUntil(ctx, providerConsAddr.ToSdkConsAddr(), jailEndTime) } ctx.EventManager().EmitEvent( @@ -460,7 +475,7 @@ func (k Keeper) EndBlockCCR(ctx sdk.Context) { "chainID", initTimeoutTimestamp.ChainId) err := k.StopConsumerChain(ctx, initTimeoutTimestamp.ChainId, false) if err != nil { - if providertypes.ErrConsumerChainNotFound.Is(err) { + if errors.Is(err, providertypes.ErrConsumerChainNotFound) { // consumer chain not found continue } @@ -487,7 +502,7 @@ func (k Keeper) EndBlockCCR(ctx sdk.Context) { ) err := k.StopConsumerChain(ctx, channelToChain.ChainId, true) if err != nil { - if providertypes.ErrConsumerChainNotFound.Is(err) { + if errors.Is(err, providertypes.ErrConsumerChainNotFound) { // consumer chain not found continue } diff --git a/x/ccv/provider/keeper/relay_test.go b/x/ccv/provider/keeper/relay_test.go index 02df262d53..61b770c320 100644 --- a/x/ccv/provider/keeper/relay_test.go +++ b/x/ccv/provider/keeper/relay_test.go @@ -4,25 +4,24 @@ import ( "strings" "testing" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - ibctesting "github.com/cosmos/ibc-go/v7/testing" + "cosmossdk.io/math" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + ibctesting "github.com/cosmos/ibc-go/v8/testing" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" - "cosmossdk.io/math" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" abci "github.com/cometbft/cometbft/abci/types" - cryptotestutil "github.com/cosmos/interchain-security/v4/testutil/crypto" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + cryptotestutil "github.com/cosmos/interchain-security/v5/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // TestQueueVSCPackets tests queueing validator set updates. @@ -74,7 +73,7 @@ func TestQueueVSCPackets(t *testing.T) { } gomock.InOrder( - mockStakingKeeper.EXPECT().GetValidatorUpdates(gomock.Eq(ctx)).Return(mockUpdates), + mockStakingKeeper.EXPECT().GetValidatorUpdates(gomock.Eq(ctx)).Return(mockUpdates, nil), ) pk := testkeeper.NewInMemProviderKeeper(keeperParams, mocks) @@ -148,9 +147,13 @@ func TestOnRecvDowntimeSlashPacket(t *testing.T) { providerAddr := providertypes.NewProviderConsAddress(packetData.Validator.Address) calls := []*gomock.Call{ mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, providerAddr.ToSdkConsAddr()). - Return(stakingtypes.Validator{}, true).Times(1), + Return(stakingtypes.Validator{ + // must be a hex string so it can be properly decoded by sdktypes.ValAddressFromHex(val.GetOperator()) + // empty string is fine, as it's not used in this test + OperatorAddress: "557D5BD0FA991DAB8EED2B9DCF98AC1B3200D43D", + }, nil).Times(1), mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(ctx, gomock.Any()). - Return(int64(2)).Times(1), + Return(int64(2), nil).Times(1), } // Add mocks for slash packet handling @@ -322,7 +325,7 @@ func TestHandleSlashPacket(t *testing.T) { // Method will return once validator is not found. mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( ctx, providerConsAddr.ToSdkConsAddr()).Return( - stakingtypes.Validator{}, false, // false = Not found. + stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound, // false = Not found. ).Times(1), } }, @@ -341,7 +344,7 @@ func TestHandleSlashPacket(t *testing.T) { return []*gomock.Call{ mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( ctx, providerConsAddr.ToSdkConsAddr()).Return( - stakingtypes.Validator{}, true, // true = Found. + stakingtypes.Validator{}, nil, // nil = no error. ).Times(1), // Execution will stop after this call as validator is tombstoned. mocks.MockSlashingKeeper.EXPECT().IsTombstoned(ctx, @@ -364,7 +367,7 @@ func TestHandleSlashPacket(t *testing.T) { return []*gomock.Call{ mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( ctx, providerConsAddr.ToSdkConsAddr()).Return( - stakingtypes.Validator{}, true, + stakingtypes.Validator{}, nil, ).Times(1), mocks.MockSlashingKeeper.EXPECT().IsTombstoned(ctx, diff --git a/x/ccv/provider/keeper/throttle.go b/x/ccv/provider/keeper/throttle.go index b7e7fd5941..5e23f7857f 100644 --- a/x/ccv/provider/keeper/throttle.go +++ b/x/ccv/provider/keeper/throttle.go @@ -10,7 +10,7 @@ import ( tmtypes "github.com/cometbft/cometbft/types" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) // Obtains the effective validator power relevant to a validator consensus address. @@ -19,15 +19,25 @@ func (k Keeper) GetEffectiveValPower(ctx sdktypes.Context, ) math.Int { // Obtain staking module val object from the provider's consensus address. // Note: if validator is not found or unbonded, this will be handled appropriately in HandleSlashPacket - val, found := k.stakingKeeper.GetValidatorByConsAddr(ctx, valConsAddr.ToSdkConsAddr()) + val, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, valConsAddr.ToSdkConsAddr()) - if !found || val.IsJailed() { + if err != nil || val.IsJailed() { // If validator is not found, or found but jailed, it's power is 0. This path is explicitly defined since the // staking keeper's LastValidatorPower values are not updated till the staking keeper's endblocker. - return sdktypes.ZeroInt() + return math.ZeroInt() } else { // Otherwise, return the staking keeper's LastValidatorPower value. - return sdktypes.NewInt(k.stakingKeeper.GetLastValidatorPower(ctx, val.GetOperator())) + // NOTE: @MSalopek double check this conversion and see if it's necessary + valAddr, err := sdktypes.ValAddressFromHex(val.GetOperator()) + if err != nil { + return math.ZeroInt() + } + + power, err := k.stakingKeeper.GetLastValidatorPower(ctx, valAddr) + if err != nil { + return math.ZeroInt() + } + return math.NewInt(power) } } @@ -98,19 +108,21 @@ func (k Keeper) GetSlashMeterAllowance(ctx sdktypes.Context) math.Int { strFrac := k.GetSlashMeterReplenishFraction(ctx) // MustNewDecFromStr should not panic, since the (string representation) of the slash meter replenish fraction // is validated in ValidateGenesis and anytime the param is mutated. - decFrac := sdktypes.MustNewDecFromStr(strFrac) + decFrac := math.LegacyMustNewDecFromStr(strFrac) // Compute allowance in units of tendermint voting power (integer), // noting that total power changes over time - totalPower := k.stakingKeeper.GetLastTotalPower(ctx) + // NOTE: ignoring err seems safe here, since the func returns a default math.ZeroInt() + // and there are no concrete actions we can take if the err is not nil. + totalPower, _ := k.stakingKeeper.GetLastTotalPower(ctx) - roundedInt := sdktypes.NewInt(decFrac.MulInt(totalPower).RoundInt64()) + roundedInt := math.NewInt(decFrac.MulInt(totalPower).RoundInt64()) if roundedInt.IsZero() { k.Logger(ctx).Info("slash meter replenish fraction is too small " + "to add any allowance to the meter, considering bankers rounding") // Return non-zero allowance to guarantee some slash packets are eventually handled - return sdktypes.NewInt(1) + return math.NewInt(1) } return roundedInt } @@ -127,7 +139,7 @@ func (k Keeper) GetSlashMeter(ctx sdktypes.Context) math.Int { // there is no deletion method exposed, so nil bytes would indicate something is very wrong. panic("slash meter not set") } - value := sdktypes.ZeroInt() + value := math.ZeroInt() err := value.Unmarshal(bz) if err != nil { // We should have obtained value bytes that were serialized in SetSlashMeter, @@ -147,12 +159,12 @@ func (k Keeper) SetSlashMeter(ctx sdktypes.Context, value math.Int) { // // Explanation: slash meter replenish fraction is validated to be in range of [0, 1], // and MaxMeterValue = MaxAllowance = MaxReplenishFrac * MaxTotalVotingPower = 1 * MaxTotalVotingPower. - if value.GT(sdktypes.NewInt(tmtypes.MaxTotalVotingPower)) { + if value.GT(math.NewInt(tmtypes.MaxTotalVotingPower)) { panic("slash meter value cannot be greater than tendermint's MaxTotalVotingPower") } // Further, HandleThrottleQueues should never subtract more than MaxTotalVotingPower from the meter, // since we cannot slash more than an entire validator set. So MinMeterValue = -1 * MaxTotalVotingPower. - if value.LT(sdktypes.NewInt(-tmtypes.MaxTotalVotingPower)) { + if value.LT(math.NewInt(-tmtypes.MaxTotalVotingPower)) { panic("slash meter value cannot be less than negative tendermint's MaxTotalVotingPower") } store := ctx.KVStore(k.storeKey) diff --git a/x/ccv/provider/keeper/throttle_legacy.go b/x/ccv/provider/keeper/throttle_legacy.go index 6f347b8f60..53c6f39c72 100644 --- a/x/ccv/provider/keeper/throttle_legacy.go +++ b/x/ccv/provider/keeper/throttle_legacy.go @@ -3,10 +3,11 @@ package keeper import ( "fmt" + storetypes "cosmossdk.io/store/types" sdktypes "github.com/cosmos/cosmos-sdk/types" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // Pending packet data type enum, used to encode the type of packet data stored at each entry in the mutual queue. @@ -26,7 +27,7 @@ func (k Keeper) LegacyGetAllThrottledPacketData(ctx sdktypes.Context, consumerCh store := ctx.KVStore(k.storeKey) iteratorPrefix := providertypes.ChainIdWithLenKey(providertypes.ThrottledPacketDataBytePrefix, consumerChainID) - iterator := sdktypes.KVStorePrefixIterator(store, iteratorPrefix) + iterator := storetypes.KVStorePrefixIterator(store, iteratorPrefix) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -60,7 +61,7 @@ func (k Keeper) LegacyGetAllThrottledPacketData(ctx sdktypes.Context, consumerCh func (k Keeper) LegacyDeleteThrottledPacketDataForConsumer(ctx sdktypes.Context, consumerChainID string) { store := ctx.KVStore(k.storeKey) iteratorPrefix := providertypes.ChainIdWithLenKey(providertypes.ThrottledPacketDataBytePrefix, consumerChainID) - iterator := sdktypes.KVStorePrefixIterator(store, iteratorPrefix) + iterator := storetypes.KVStorePrefixIterator(store, iteratorPrefix) defer iterator.Close() keysToDel := [][]byte{} diff --git a/x/ccv/provider/keeper/throttle_test.go b/x/ccv/provider/keeper/throttle_test.go index 478ec0f235..cb8e8804c4 100644 --- a/x/ccv/provider/keeper/throttle_test.go +++ b/x/ccv/provider/keeper/throttle_test.go @@ -9,12 +9,10 @@ import ( "cosmossdk.io/math" - sdktypes "github.com/cosmos/cosmos-sdk/types" - tmtypes "github.com/cometbft/cometbft/types" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) // TestSlashMeterReplenishment tests the CheckForSlashMeterReplenishment, ReplenishSlashMeter, @@ -30,20 +28,20 @@ func TestSlashMeterReplenishment(t *testing.T) { { replenishPeriod: time.Minute, replenishFraction: "0.01", - totalPower: sdktypes.NewInt(1000), - expectedAllowance: sdktypes.NewInt(10), + totalPower: math.NewInt(1000), + expectedAllowance: math.NewInt(10), }, { replenishPeriod: time.Hour, replenishFraction: "0.1", - totalPower: sdktypes.NewInt(100000), - expectedAllowance: sdktypes.NewInt(10000), + totalPower: math.NewInt(100000), + expectedAllowance: math.NewInt(10000), }, { replenishPeriod: 30 * time.Minute, replenishFraction: "0.5", - totalPower: sdktypes.NewInt(1000000000000000), - expectedAllowance: sdktypes.NewInt(500000000000000), + totalPower: math.NewInt(1000000000000000), + expectedAllowance: math.NewInt(500000000000000), }, } for _, tc := range testCases { @@ -65,7 +63,7 @@ func TestSlashMeterReplenishment(t *testing.T) { // Any ctx is accepted, and the method will be called multiple times during the tests gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetLastTotalPower( - gomock.Any()).Return(tc.totalPower).AnyTimes(), + gomock.Any()).Return(tc.totalPower, nil).AnyTimes(), ) // Now we can initialize the slash meter (this would happen in InitGenesis) @@ -79,8 +77,8 @@ func TestSlashMeterReplenishment(t *testing.T) { require.Equal(t, now.Add(tc.replenishPeriod), initialReplenishCandidate) // Decrement slash meter - providerKeeper.SetSlashMeter(ctx, providerKeeper.GetSlashMeter(ctx).Sub(sdktypes.NewInt(3))) - require.Equal(t, tc.expectedAllowance.Sub(sdktypes.NewInt(3)), providerKeeper.GetSlashMeter(ctx)) + providerKeeper.SetSlashMeter(ctx, providerKeeper.GetSlashMeter(ctx).Sub(math.NewInt(3))) + require.Equal(t, tc.expectedAllowance.Sub(math.NewInt(3)), providerKeeper.GetSlashMeter(ctx)) // Check for replenishment, confirm meter is not replenished (since no time has passed since init) meterBefore := providerKeeper.GetSlashMeter(ctx) @@ -146,7 +144,7 @@ func TestConsecutiveReplenishments(t *testing.T) { // Any ctx is accepted, and the method will be called multiple times during the tests gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetLastTotalPower( - gomock.Any()).Return(sdktypes.NewInt(1000)).AnyTimes(), + gomock.Any()).Return(math.NewInt(1000), nil).AnyTimes(), ) // Now we can initialize the slash meter (this would happen in InitGenesis) @@ -159,45 +157,45 @@ func TestConsecutiveReplenishments(t *testing.T) { require.Equal(t, now.Add(time.Hour), providerKeeper.GetSlashMeterReplenishTimeCandidate(ctx)) // Decrement slash meter to negative value that would take 4 replenishments to recover from - providerKeeper.SetSlashMeter(ctx, sdktypes.NewInt(-150)) + providerKeeper.SetSlashMeter(ctx, math.NewInt(-150)) // Confirm no replenishment occurs when no time has passed, replenish candidate is not updated providerKeeper.CheckForSlashMeterReplenishment(ctx) - require.Equal(t, sdktypes.NewInt(-150), providerKeeper.GetSlashMeter(ctx)) + require.Equal(t, math.NewInt(-150), providerKeeper.GetSlashMeter(ctx)) require.Equal(t, now.Add(time.Hour), providerKeeper.GetSlashMeterReplenishTimeCandidate(ctx)) // Now increment block time past replenishment period and confirm that meter is replenished ONCE, // and replenish candidate is updated to block time + replenish period ctx = ctx.WithBlockTime(ctx.BlockTime().Add(2 * time.Hour)) providerKeeper.CheckForSlashMeterReplenishment(ctx) - require.Equal(t, sdktypes.NewInt(-100), providerKeeper.GetSlashMeter(ctx)) + require.Equal(t, math.NewInt(-100), providerKeeper.GetSlashMeter(ctx)) require.Equal(t, now.Add(3*time.Hour), providerKeeper.GetSlashMeterReplenishTimeCandidate(ctx)) // Note 3 hours, not 2 // Simulate next block and check that no consecutive replenishments occur (replenish period has not passed) // and replenish candidate is not updated ctx = ctx.WithBlockTime(ctx.BlockTime().Add(5 * time.Second)) providerKeeper.CheckForSlashMeterReplenishment(ctx) - require.Equal(t, sdktypes.NewInt(-100), providerKeeper.GetSlashMeter(ctx)) + require.Equal(t, math.NewInt(-100), providerKeeper.GetSlashMeter(ctx)) require.Equal(t, now.Add(3*time.Hour), providerKeeper.GetSlashMeterReplenishTimeCandidate(ctx)) // Increment block time past replenishment period and confirm that meter is replenished ONCE more // and replenish candidate is updated to block time + replenish period ctx = ctx.WithBlockTime(ctx.BlockTime().Add(time.Hour * 1)) providerKeeper.CheckForSlashMeterReplenishment(ctx) - require.Equal(t, sdktypes.NewInt(-50), providerKeeper.GetSlashMeter(ctx)) + require.Equal(t, math.NewInt(-50), providerKeeper.GetSlashMeter(ctx)) require.Equal(t, now.Add(4*time.Hour).Add(5*time.Second), providerKeeper.GetSlashMeterReplenishTimeCandidate(ctx)) // Replenishments should happen if we increment block times past replenishment period ctx = ctx.WithBlockTime(ctx.BlockTime().Add(time.Hour * 1)) providerKeeper.CheckForSlashMeterReplenishment(ctx) - require.Equal(t, sdktypes.NewInt(0), providerKeeper.GetSlashMeter(ctx)) + require.Equal(t, math.NewInt(0), providerKeeper.GetSlashMeter(ctx)) require.Equal(t, now.Add(5*time.Hour).Add(5*time.Second), providerKeeper.GetSlashMeterReplenishTimeCandidate(ctx)) providerKeeper.CheckForSlashMeterReplenishment(ctx) - require.Equal(t, sdktypes.NewInt(0), providerKeeper.GetSlashMeter(ctx)) + require.Equal(t, math.NewInt(0), providerKeeper.GetSlashMeter(ctx)) require.Equal(t, now.Add(5*time.Hour).Add(5*time.Second), providerKeeper.GetSlashMeterReplenishTimeCandidate(ctx)) ctx = ctx.WithBlockTime(ctx.BlockTime().Add(time.Hour * 1)) providerKeeper.CheckForSlashMeterReplenishment(ctx) - require.Equal(t, sdktypes.NewInt(50), providerKeeper.GetSlashMeter(ctx)) + require.Equal(t, math.NewInt(50), providerKeeper.GetSlashMeter(ctx)) require.Equal(t, now.Add(6*time.Hour).Add(5*time.Second), providerKeeper.GetSlashMeterReplenishTimeCandidate(ctx)) } @@ -219,28 +217,28 @@ func TestTotalVotingPowerChanges(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetLastTotalPower( // Expect two calls, once for initialization, once for allowance check - ctx).Return(sdktypes.NewInt(1000)).Times(2), + ctx).Return(math.NewInt(1000), nil).Times(2), ) // Initialize the slash meter (this would happen in InitGenesis) providerKeeper.InitializeSlashMeter(ctx) // Confirm slash meter is full, and allowance is expected value via params - require.Equal(t, sdktypes.NewInt(100), providerKeeper.GetSlashMeterAllowance(ctx)) - require.Equal(t, sdktypes.NewInt(100), providerKeeper.GetSlashMeter(ctx)) + require.Equal(t, math.NewInt(100), providerKeeper.GetSlashMeterAllowance(ctx)) + require.Equal(t, math.NewInt(100), providerKeeper.GetSlashMeter(ctx)) // Mutate context so mocked total power is less than before ctx = ctx.WithBlockTime(ctx.BlockTime().Add(time.Microsecond)) // Don't add enough time for replenishment gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetLastTotalPower( // Expect two calls, once for replenish check, once for allowance check - ctx).Return(sdktypes.NewInt(500)).Times(2), + ctx).Return(math.NewInt(500), nil).Times(2), ) // Replenishment should not happen here, but slash meter should be decremented to new allowance providerKeeper.CheckForSlashMeterReplenishment(ctx) - require.Equal(t, sdktypes.NewInt(50), providerKeeper.GetSlashMeterAllowance(ctx)) - require.Equal(t, sdktypes.NewInt(50), providerKeeper.GetSlashMeter(ctx)) + require.Equal(t, math.NewInt(50), providerKeeper.GetSlashMeterAllowance(ctx)) + require.Equal(t, math.NewInt(50), providerKeeper.GetSlashMeter(ctx)) // Mutate context so mocked total power is again less than before, // with ctx time set to a time that will replenish meter @@ -249,20 +247,20 @@ func TestTotalVotingPowerChanges(t *testing.T) { mocks.MockStakingKeeper.EXPECT().GetLastTotalPower( // Expect three calls, once for replenish check, // once for replenishment, once for allowance check - ctx).Return(sdktypes.NewInt(100)).Times(3), + ctx).Return(math.NewInt(100), nil).Times(3), ) // Replenishment should happen here, slash meter should be decremented to new allowance regardless providerKeeper.CheckForSlashMeterReplenishment(ctx) - require.Equal(t, sdktypes.NewInt(10), providerKeeper.GetSlashMeterAllowance(ctx)) - require.Equal(t, sdktypes.NewInt(10), providerKeeper.GetSlashMeter(ctx)) + require.Equal(t, math.NewInt(10), providerKeeper.GetSlashMeterAllowance(ctx)) + require.Equal(t, math.NewInt(10), providerKeeper.GetSlashMeter(ctx)) // Mutate context so mocked total power is now more than before ctx = ctx.WithBlockTime(ctx.BlockTime().Add(time.Microsecond)) // Don't add enough time for replenishment gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetLastTotalPower( // Expect two calls, once for replenish check, once for allowance check - ctx).Return(sdktypes.NewInt(5000)).Times(2), + ctx).Return(math.NewInt(5000), nil).Times(2), ) // @@ -271,8 +269,8 @@ func TestTotalVotingPowerChanges(t *testing.T) { // Replenishment should not happen here, slash meter should remain at previous value providerKeeper.CheckForSlashMeterReplenishment(ctx) - require.Equal(t, sdktypes.NewInt(500), providerKeeper.GetSlashMeterAllowance(ctx)) - require.Equal(t, sdktypes.NewInt(10), providerKeeper.GetSlashMeter(ctx)) + require.Equal(t, math.NewInt(500), providerKeeper.GetSlashMeterAllowance(ctx)) + require.Equal(t, math.NewInt(10), providerKeeper.GetSlashMeter(ctx)) // Mutate context so mocked total power is again more than before, // with ctx time set to a time that will replenish meter @@ -281,13 +279,13 @@ func TestTotalVotingPowerChanges(t *testing.T) { mocks.MockStakingKeeper.EXPECT().GetLastTotalPower( // Expect three calls, once for replenish check, // once for replenishment, once for allowance check - ctx).Return(sdktypes.NewInt(10000)).Times(3), + ctx).Return(math.NewInt(10000), nil).Times(3), ) // Replenishment should happen here, slash meter should be set to new allowance providerKeeper.CheckForSlashMeterReplenishment(ctx) - require.Equal(t, sdktypes.NewInt(1000), providerKeeper.GetSlashMeterAllowance(ctx)) - require.Equal(t, sdktypes.NewInt(1000), providerKeeper.GetSlashMeter(ctx)) + require.Equal(t, math.NewInt(1000), providerKeeper.GetSlashMeterAllowance(ctx)) + require.Equal(t, math.NewInt(1000), providerKeeper.GetSlashMeter(ctx)) } // TestNegativeSlashMeter tests behavior of the slash meter when it goes negative, @@ -306,33 +304,33 @@ func TestNegativeSlashMeter(t *testing.T) { // Slashing 100 of voting power makes total voting power = 900, and meter = -90. // Expected replenish allowance is then 9, meaning it'd take 10 replenishes // for meter to reach 0 in value, and 11 replenishes for meter to reach a value of 9. - slashedPower: sdktypes.NewInt(100), - totalPower: sdktypes.NewInt(1000), + slashedPower: math.NewInt(100), + totalPower: math.NewInt(1000), replenishFraction: "0.01", numReplenishesTillFull: 11, - finalMeterValue: sdktypes.NewInt(9), + finalMeterValue: math.NewInt(9), }, { // Meter is initialized to a value of: 0.1*100 = 10. // Slashing 30 of voting power makes total voting power = 70, and meter = -20. // Expected replenish allowance is then 7, meaning it'd take 3 replenishes // for meter to reach 1 in value, and 4 replenishes for meter to reach a value of 7. - slashedPower: sdktypes.NewInt(30), - totalPower: sdktypes.NewInt(100), + slashedPower: math.NewInt(30), + totalPower: math.NewInt(100), replenishFraction: "0.1", numReplenishesTillFull: 4, - finalMeterValue: sdktypes.NewInt(7), + finalMeterValue: math.NewInt(7), }, { // Meter is initialized to a value of 1, since replenish fraction is too low, and min allowance is 1. // Slashing 5 of voting power makes total voting power = 995, and meter = -4. // Expected replenish allowance is then 1 (still minimum amount), meaning it'd take 4 replenishes // for meter to reach 0 in value, and 5 replenishes for meter to reach a value of 1. - slashedPower: sdktypes.NewInt(5), - totalPower: sdktypes.NewInt(1000), + slashedPower: math.NewInt(5), + totalPower: math.NewInt(1000), replenishFraction: "0.0000001", numReplenishesTillFull: 5, - finalMeterValue: sdktypes.NewInt(1), + finalMeterValue: math.NewInt(1), }, } @@ -349,9 +347,9 @@ func TestNegativeSlashMeter(t *testing.T) { // then total power minus slashed power any amount of times gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetLastTotalPower( - gomock.Any()).Return(tc.totalPower).Times(1), + gomock.Any()).Return(tc.totalPower, nil).Times(1), mocks.MockStakingKeeper.EXPECT().GetLastTotalPower( - gomock.Any()).Return(tc.totalPower.Sub(tc.slashedPower)).AnyTimes(), + gomock.Any()).Return(tc.totalPower.Sub(tc.slashedPower), nil).AnyTimes(), ) // Initialize the slash meter (using first mocked value) @@ -360,11 +358,11 @@ func TestNegativeSlashMeter(t *testing.T) { // remaining calls to GetLastTotalPower should return the second mocked value. // Confirm that meter is initialized to expected initial allowance - decFrac, err := sdktypes.NewDecFromStr(tc.replenishFraction) + decFrac, err := math.LegacyNewDecFromStr(tc.replenishFraction) require.NoError(t, err) - expectedInitAllowance := sdktypes.NewInt(decFrac.MulInt(tc.totalPower).RoundInt64()) + expectedInitAllowance := math.NewInt(decFrac.MulInt(tc.totalPower).RoundInt64()) if expectedInitAllowance.IsZero() { // Allowances have a minimum of 1. - expectedInitAllowance = sdktypes.NewInt(1) + expectedInitAllowance = math.NewInt(1) } require.Equal(t, expectedInitAllowance, providerKeeper.GetSlashMeter(ctx)) @@ -374,9 +372,9 @@ func TestNegativeSlashMeter(t *testing.T) { require.True(t, providerKeeper.GetSlashMeter(ctx).LT(before)) // New expected allowance is replenish fraction * (total power - slashed power) - expectedNewAllowance := sdktypes.NewInt(decFrac.MulInt(tc.totalPower.Sub(tc.slashedPower)).RoundInt64()) + expectedNewAllowance := math.NewInt(decFrac.MulInt(tc.totalPower.Sub(tc.slashedPower)).RoundInt64()) if expectedNewAllowance.IsZero() { - expectedNewAllowance = sdktypes.NewInt(1) + expectedNewAllowance = math.NewInt(1) } require.Equal(t, expectedNewAllowance, providerKeeper.GetSlashMeterAllowance(ctx)) @@ -416,33 +414,33 @@ func TestGetSlashMeterAllowance(t *testing.T) { }{ { replenishFraction: "0.00", - totalPower: sdktypes.NewInt(100), - expectedAllowance: sdktypes.NewInt(1), // 0.0 * 100 = 0, 1 is returned + totalPower: math.NewInt(100), + expectedAllowance: math.NewInt(1), // 0.0 * 100 = 0, 1 is returned }, { replenishFraction: "0.00000000001", - totalPower: sdktypes.NewInt(100), - expectedAllowance: sdktypes.NewInt(1), // 0.00000000001 * 100 = 0 (bankers rounding), 1 is returned + totalPower: math.NewInt(100), + expectedAllowance: math.NewInt(1), // 0.00000000001 * 100 = 0 (bankers rounding), 1 is returned }, { replenishFraction: "0.01", - totalPower: sdktypes.NewInt(100), - expectedAllowance: sdktypes.NewInt(1), // 0.00000000001 * 100 = 0 (bankers rounding), 1 is returned + totalPower: math.NewInt(100), + expectedAllowance: math.NewInt(1), // 0.00000000001 * 100 = 0 (bankers rounding), 1 is returned }, { replenishFraction: "0.015", - totalPower: sdktypes.NewInt(100), - expectedAllowance: sdktypes.NewInt(2), // 0.015 * 10 = 2 (bankers rounding) + totalPower: math.NewInt(100), + expectedAllowance: math.NewInt(2), // 0.015 * 10 = 2 (bankers rounding) }, { replenishFraction: "0.27", - totalPower: sdktypes.NewInt(100), - expectedAllowance: sdktypes.NewInt(27), + totalPower: math.NewInt(100), + expectedAllowance: math.NewInt(27), }, { replenishFraction: "0.34", - totalPower: sdktypes.NewInt(10000000), - expectedAllowance: sdktypes.NewInt(3400000), + totalPower: math.NewInt(10000000), + expectedAllowance: math.NewInt(3400000), }, } for _, tc := range testCases { @@ -453,7 +451,7 @@ func TestGetSlashMeterAllowance(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetLastTotalPower( - gomock.Any()).Return(tc.totalPower).Times(1), + gomock.Any()).Return(tc.totalPower, nil).Times(1), ) // Set desired params @@ -473,18 +471,18 @@ func TestSlashMeter(t *testing.T) { meterValue math.Int shouldPanic bool }{ - {meterValue: sdktypes.NewInt(-7999999999999999999), shouldPanic: true}, - {meterValue: sdktypes.NewInt(-tmtypes.MaxTotalVotingPower - 1), shouldPanic: true}, - {meterValue: sdktypes.NewInt(-tmtypes.MaxTotalVotingPower), shouldPanic: false}, - {meterValue: sdktypes.NewInt(-50000000078987), shouldPanic: false}, - {meterValue: sdktypes.NewInt(-4237), shouldPanic: false}, - {meterValue: sdktypes.NewInt(0), shouldPanic: false}, - {meterValue: sdktypes.NewInt(1), shouldPanic: false}, - {meterValue: sdktypes.NewInt(4237897), shouldPanic: false}, - {meterValue: sdktypes.NewInt(500078078987), shouldPanic: false}, - {meterValue: sdktypes.NewInt(tmtypes.MaxTotalVotingPower), shouldPanic: false}, - {meterValue: sdktypes.NewInt(tmtypes.MaxTotalVotingPower + 1), shouldPanic: true}, - {meterValue: sdktypes.NewInt(7999974823991111199), shouldPanic: true}, + {meterValue: math.NewInt(-7999999999999999999), shouldPanic: true}, + {meterValue: math.NewInt(-tmtypes.MaxTotalVotingPower - 1), shouldPanic: true}, + {meterValue: math.NewInt(-tmtypes.MaxTotalVotingPower), shouldPanic: false}, + {meterValue: math.NewInt(-50000000078987), shouldPanic: false}, + {meterValue: math.NewInt(-4237), shouldPanic: false}, + {meterValue: math.NewInt(0), shouldPanic: false}, + {meterValue: math.NewInt(1), shouldPanic: false}, + {meterValue: math.NewInt(4237897), shouldPanic: false}, + {meterValue: math.NewInt(500078078987), shouldPanic: false}, + {meterValue: math.NewInt(tmtypes.MaxTotalVotingPower), shouldPanic: false}, + {meterValue: math.NewInt(tmtypes.MaxTotalVotingPower + 1), shouldPanic: true}, + {meterValue: math.NewInt(7999974823991111199), shouldPanic: true}, } for _, tc := range testCases { diff --git a/x/ccv/provider/migrations/migrator.go b/x/ccv/provider/migrations/migrator.go index 9127844dee..bec37a666d 100644 --- a/x/ccv/provider/migrations/migrator.go +++ b/x/ccv/provider/migrations/migrator.go @@ -4,8 +4,9 @@ import ( sdktypes "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - providerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - v3 "github.com/cosmos/interchain-security/v4/x/ccv/provider/migrations/v3" + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + v3 "github.com/cosmos/interchain-security/v5/x/ccv/provider/migrations/v3" + v4 "github.com/cosmos/interchain-security/v5/x/ccv/provider/migrations/v4" ) // Migrator is a struct for handling in-place store migrations. @@ -31,3 +32,7 @@ func (m Migrator) Migrate1to2(ctx sdktypes.Context) error { func (m Migrator) Migrate2to3(ctx sdktypes.Context) error { return v3.MigrateQueuedPackets(ctx, m.providerKeeper) } + +func (m Migrator) Migrate3to4(ctx sdktypes.Context) error { + return v4.MigrateParams(ctx, m.providerKeeper, m.paramSpace) +} diff --git a/x/ccv/provider/migrations/v3/migration_test.go b/x/ccv/provider/migrations/v3/migration_test.go index 189c75e271..7a079bf0be 100644 --- a/x/ccv/provider/migrations/v3/migration_test.go +++ b/x/ccv/provider/migrations/v3/migration_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/require" - testutil "github.com/cosmos/interchain-security/v4/testutil/keeper" + testutil "github.com/cosmos/interchain-security/v5/testutil/keeper" ) func TestMigrate2To3(t *testing.T) { diff --git a/x/ccv/provider/migrations/v3/migrations.go b/x/ccv/provider/migrations/v3/migrations.go index c2cd9054ba..28f037f7f2 100644 --- a/x/ccv/provider/migrations/v3/migrations.go +++ b/x/ccv/provider/migrations/v3/migrations.go @@ -5,7 +5,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - providerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" ) // MigrateQueuedPackets processes all queued packet data for all consumer chains that were stored diff --git a/x/ccv/provider/migrations/v4/migrations.go b/x/ccv/provider/migrations/v4/migrations.go new file mode 100644 index 0000000000..447501e80d --- /dev/null +++ b/x/ccv/provider/migrations/v4/migrations.go @@ -0,0 +1,22 @@ +package v4 + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" +) + +// MigrateParams migrates the provider module's parameters from the x/params to self store. +func MigrateParams(ctx sdk.Context, keeper providerkeeper.Keeper, legacySubspace paramtypes.Subspace) error { + keeper.Logger(ctx).Info("starting provider params migration") + params := providerkeeper.GetParamsLegacy(ctx, legacySubspace) + err := params.Validate() + if err != nil { + return err + } + + keeper.SetParams(ctx, params) + keeper.Logger(ctx).Info("successfully migrated provider parameters") + return nil +} diff --git a/x/ccv/provider/module.go b/x/ccv/provider/module.go index f34b92bb07..68130ef12d 100644 --- a/x/ccv/provider/module.go +++ b/x/ccv/provider/module.go @@ -5,7 +5,7 @@ import ( "encoding/json" "fmt" - porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types" + "cosmossdk.io/core/appmodule" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" @@ -17,18 +17,24 @@ import ( simtypes "github.com/cosmos/cosmos-sdk/types/simulation" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - abci "github.com/cometbft/cometbft/abci/types" - - "github.com/cosmos/interchain-security/v4/x/ccv/provider/client/cli" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/migrations" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/client/cli" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/migrations" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) var ( - _ module.AppModule = AppModule{} - _ porttypes.IBCModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} + _ module.AppModule = (*AppModule)(nil) + _ module.AppModuleBasic = (*AppModuleBasic)(nil) + _ module.AppModuleSimulation = (*AppModule)(nil) + _ module.HasGenesis = (*AppModule)(nil) + _ module.HasName = (*AppModule)(nil) + _ module.HasConsensusVersion = (*AppModule)(nil) + _ module.HasInvariants = (*AppModule)(nil) + _ module.HasServices = (*AppModule)(nil) + _ appmodule.AppModule = (*AppModule)(nil) + _ appmodule.HasBeginBlocker = (*AppModule)(nil) + _ appmodule.HasEndBlocker = (*AppModule)(nil) ) // AppModuleBasic is the IBC Provider AppModuleBasic @@ -39,6 +45,12 @@ func (AppModuleBasic) Name() string { return providertypes.ModuleName } +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (am AppModule) IsOnePerModuleType() {} + +// IsAppModule implements the appmodule.AppModule interface. +func (am AppModule) IsAppModule() {} + // RegisterLegacyAminoCodec implements AppModuleBasic interface func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { providertypes.RegisterLegacyAminoCodec(cdc) @@ -108,22 +120,23 @@ func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { func (am AppModule) RegisterServices(cfg module.Configurator) { providertypes.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) providertypes.RegisterQueryServer(cfg.QueryServer(), am.keeper) - m := migrations.NewMigrator(*am.keeper, am.paramSpace) - if err := cfg.RegisterMigration(providertypes.ModuleName, 2, m.Migrate2to3); err != nil { - panic(fmt.Sprintf("failed to register migrator for %s: %s", providertypes.ModuleName, err)) + + migrator := migrations.NewMigrator(*am.keeper, am.paramSpace) + // TODO: check/adapt 'fromVersion' once v0.50 branch merged with main + err := cfg.RegisterMigration(am.Name(), 2, migrator.Migrate2to3) + if err != nil { + panic(err) } } // InitGenesis performs genesis initialization for the provider module. It returns no validator updates. // Note: This method along with ValidateGenesis satisfies the CCV spec: // https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-initg1 -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) { var genesisState providertypes.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) am.keeper.InitGenesis(ctx, &genesisState) - - return []abci.ValidatorUpdate{} } // ExportGenesis returns the exported genesis state as raw bytes for the provider @@ -134,31 +147,36 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 3 } +func (AppModule) ConsensusVersion() uint64 { return 4 } // BeginBlock implements the AppModule interface -func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { - // Create clients to consumer chains that are due to be spawned via pending consumer addition proposals - am.keeper.BeginBlockInit(ctx) +func (am AppModule) BeginBlock(ctx context.Context) error { + sdkCtx := sdk.UnwrapSDKContext(ctx) // Create clients to consumer chains that are due to be spawned via pending consumer addition proposals + + am.keeper.BeginBlockInit(sdkCtx) // Stop and remove state for any consumer chains that are due to be stopped via pending consumer removal proposals - am.keeper.BeginBlockCCR(ctx) + am.keeper.BeginBlockCCR(sdkCtx) // Check for replenishing slash meter before any slash packets are processed for this block - am.keeper.BeginBlockCIS(ctx) + am.keeper.BeginBlockCIS(sdkCtx) + + return nil } // EndBlock implements the AppModule interface -func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { +func (am AppModule) EndBlock(ctx context.Context) error { + sdkCtx := sdk.UnwrapSDKContext(ctx) + // EndBlock logic needed for the Consumer Initiated Slashing sub-protocol. // Important: EndBlockCIS must be called before EndBlockVSU - am.keeper.EndBlockCIS(ctx) + am.keeper.EndBlockCIS(sdkCtx) // EndBlock logic needed for the Consumer Chain Removal sub-protocol - am.keeper.EndBlockCCR(ctx) + am.keeper.EndBlockCCR(sdkCtx) // EndBlock logic needed for the Validator Set Update sub-protocol - am.keeper.EndBlockVSU(ctx) + am.keeper.EndBlockVSU(sdkCtx) // EndBlock logic need for the Reward Distribution sub-protocol - am.keeper.EndBlockRD(ctx) + am.keeper.EndBlockRD(sdkCtx) - return []abci.ValidatorUpdate{} + return nil } // AppModuleSimulation functions @@ -168,7 +186,7 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) { } // RegisterStoreDecoder registers a decoder for provider module's types -func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { +func (am AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) { } // WeightedOperations returns the all the provider module operations with their respective weights. diff --git a/x/ccv/provider/module_test.go b/x/ccv/provider/module_test.go index 869c24253f..b37c34d1da 100644 --- a/x/ccv/provider/module_test.go +++ b/x/ccv/provider/module_test.go @@ -3,18 +3,18 @@ package provider_test import ( "testing" - host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "cosmossdk.io/math" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - sdk "github.com/cosmos/cosmos-sdk/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/provider" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // Tests the provider's InitGenesis implementation against the spec. @@ -143,7 +143,7 @@ func TestInitGenesis(t *testing.T) { if !tc.expPanic { orderedCalls = append(orderedCalls, mocks.MockStakingKeeper.EXPECT().GetLastTotalPower( - ctx).Return(sdk.NewInt(100)).Times(1), // Return total voting power as 100 + ctx).Return(math.NewInt(100), nil).Times(1), // Return total voting power as 100 ) } @@ -159,7 +159,7 @@ func TestInitGenesis(t *testing.T) { continue // Nothing else to verify } - valUpdates := appModule.InitGenesis(ctx, cdc, jsonBytes) + appModule.InitGenesis(ctx, cdc, jsonBytes) numStatesCounted := 0 for _, state := range tc.consumerStates { @@ -174,14 +174,12 @@ func TestInitGenesis(t *testing.T) { } require.Equal(t, len(tc.consumerStates), numStatesCounted) - require.Empty(t, valUpdates, "InitGenesis should return no validator updates") - // Expect slash meter to be initialized to it's allowance value // (replenish fraction * mocked value defined above) slashMeter := providerKeeper.GetSlashMeter(ctx) - replenishFraction, err := sdk.NewDecFromStr(providerKeeper.GetParams(ctx).SlashMeterReplenishFraction) + replenishFraction, err := math.LegacyNewDecFromStr(providerKeeper.GetParams(ctx).SlashMeterReplenishFraction) require.NoError(t, err) - expectedSlashMeterValue := sdk.NewInt(replenishFraction.MulInt(sdk.NewInt(100)).RoundInt64()) + expectedSlashMeterValue := math.NewInt(replenishFraction.MulInt(math.NewInt(100)).RoundInt64()) require.Equal(t, expectedSlashMeterValue, slashMeter) // Expect slash meter replenishment time candidate to be set to the current block time + replenish period diff --git a/x/ccv/provider/proposal_handler.go b/x/ccv/provider/proposal_handler.go index 50089a8ab5..6c6f78b792 100644 --- a/x/ccv/provider/proposal_handler.go +++ b/x/ccv/provider/proposal_handler.go @@ -7,8 +7,8 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) // NewProviderProposalHandler defines the handler for consumer addition, @@ -18,11 +18,11 @@ func NewProviderProposalHandler(k keeper.Keeper) govv1beta1.Handler { return func(ctx sdk.Context, content govv1beta1.Content) error { switch c := content.(type) { case *types.ConsumerAdditionProposal: - return k.HandleConsumerAdditionProposal(ctx, c) + return k.HandleLegacyConsumerAdditionProposal(ctx, c) case *types.ConsumerRemovalProposal: - return k.HandleConsumerRemovalProposal(ctx, c) + return k.HandleLegacyConsumerRemovalProposal(ctx, c) case *types.ChangeRewardDenomsProposal: - return k.HandleConsumerRewardDenomProposal(ctx, c) + return k.HandleLegacyConsumerRewardDenomProposal(ctx, c) default: return errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized ccv proposal content type: %T", c) } diff --git a/x/ccv/provider/proposal_handler_test.go b/x/ccv/provider/proposal_handler_test.go index 65e84ac661..2112bb8d33 100644 --- a/x/ccv/provider/proposal_handler_test.go +++ b/x/ccv/provider/proposal_handler_test.go @@ -4,7 +4,8 @@ import ( "testing" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "cosmossdk.io/math" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" @@ -12,9 +13,9 @@ import ( distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" - "github.com/cosmos/interchain-security/v4/x/ccv/provider" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) // TestProviderProposalHandler tests the highest level handler for proposals @@ -75,7 +76,7 @@ func TestProviderProposalHandler(t *testing.T) { Title: "title", Description: "desc", Recipient: "", - Amount: sdk.NewCoins(sdk.NewCoin("communityfunds", sdk.NewInt(10))), + Amount: sdk.NewCoins(sdk.NewCoin("communityfunds", math.NewInt(10))), }, }, } diff --git a/x/ccv/provider/types/codec.go b/x/ccv/provider/types/codec.go index 6ab621f0e1..2966cebf5d 100644 --- a/x/ccv/provider/types/codec.go +++ b/x/ccv/provider/types/codec.go @@ -6,12 +6,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/msgservice" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - "github.com/cosmos/ibc-go/v7/modules/core/exported" - tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + "github.com/cosmos/ibc-go/v8/modules/core/exported" + tendermint "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" ) -// RegisterLegacyAminoCodec registers the necessary x/ibc transfer interfaces and concrete types -// on the provided LegacyAmino codec. These types are used for Amino JSON serialization. func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { } @@ -28,7 +26,12 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { registry.RegisterImplementations( (*sdk.Msg)(nil), &MsgAssignConsumerKey{}, + &MsgConsumerAddition{}, + &MsgConsumerRemoval{}, + &MsgChangeRewardDenoms{}, + &MsgUpdateParams{}, ) + // keep so existing proposals can be correctly deserialized registry.RegisterImplementations( (*govv1beta1.Content)(nil), &EquivocationProposal{}, diff --git a/x/ccv/provider/types/consumer.go b/x/ccv/provider/types/consumer.go index 4c43bd58e7..02651ac03e 100644 --- a/x/ccv/provider/types/consumer.go +++ b/x/ccv/provider/types/consumer.go @@ -1,7 +1,7 @@ package types import ( - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) func NewConsumerStates( diff --git a/x/ccv/provider/types/errors.go b/x/ccv/provider/types/errors.go index 6c19a7b396..b177f25ae7 100644 --- a/x/ccv/provider/types/errors.go +++ b/x/ccv/provider/types/errors.go @@ -24,4 +24,8 @@ var ( ErrInvalidConsumerClient = errorsmod.Register(ModuleName, 16, "ccv channel is not built on correct client") ErrDuplicateConsumerChain = errorsmod.Register(ModuleName, 17, "consumer chain already exists") ErrConsumerChainNotFound = errorsmod.Register(ModuleName, 18, "consumer chain not found") + ErrNoUnbondingTime = errorsmod.Register(ModuleName, 19, "provider unbonding time not found") + ErrInvalidAddress = errorsmod.Register(ModuleName, 20, "invalid address") + ErrUnauthorized = errorsmod.Register(ModuleName, 21, "unauthorized") + ErrBlankConsumerChainID = errorsmod.Register(ModuleName, 22, "consumer chain id must not be blank") ) diff --git a/x/ccv/provider/types/genesis.go b/x/ccv/provider/types/genesis.go index ae929ba541..7ef643970b 100644 --- a/x/ccv/provider/types/genesis.go +++ b/x/ccv/provider/types/genesis.go @@ -3,13 +3,13 @@ package types import ( "fmt" - host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) func NewGenesisState( diff --git a/x/ccv/provider/types/genesis.pb.go b/x/ccv/provider/types/genesis.pb.go index d5041f1b10..d885dbc667 100644 --- a/x/ccv/provider/types/genesis.pb.go +++ b/x/ccv/provider/types/genesis.pb.go @@ -7,7 +7,7 @@ import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" - types "github.com/cosmos/interchain-security/v4/x/ccv/types" + types "github.com/cosmos/interchain-security/v5/x/ccv/types" io "io" math "math" math_bits "math/bits" @@ -353,63 +353,63 @@ func init() { var fileDescriptor_48411d9c7900d48e = []byte{ // 908 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcd, 0x6e, 0x1b, 0x37, - 0x10, 0xf6, 0xda, 0x8e, 0x63, 0xd1, 0x3f, 0x75, 0x59, 0x57, 0x59, 0xdb, 0xad, 0x62, 0xa8, 0x08, - 0x60, 0xa0, 0xad, 0x14, 0xbb, 0x39, 0xa4, 0x3f, 0x39, 0xc4, 0x49, 0xd1, 0x0a, 0x45, 0x51, 0x41, - 0x76, 0x5c, 0x20, 0x3d, 0x10, 0x14, 0x49, 0x48, 0x8c, 0x25, 0x72, 0xc1, 0xe1, 0xae, 0x2d, 0x14, - 0x05, 0x52, 0xb4, 0x0f, 0xd0, 0xc7, 0xca, 0xd1, 0xc7, 0x9e, 0x82, 0xc2, 0x7e, 0x83, 0x3e, 0x41, - 0xb1, 0x5c, 0xee, 0x66, 0xe5, 0xca, 0x81, 0x94, 0x93, 0x2d, 0x7e, 0x9c, 0xef, 0xfb, 0x86, 0x43, - 0xce, 0x2c, 0xda, 0x97, 0xca, 0x0a, 0xc3, 0xfa, 0x54, 0x2a, 0x02, 0x82, 0xc5, 0x46, 0xda, 0x51, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x6e, 0x1b, 0x45, + 0x14, 0xce, 0x26, 0x69, 0x1a, 0x4f, 0x7e, 0x08, 0x43, 0x70, 0x37, 0x09, 0xb8, 0x91, 0x51, 0xa5, + 0x48, 0x80, 0xdd, 0x04, 0x90, 0xca, 0x4f, 0x2f, 0x9a, 0x16, 0x81, 0x85, 0x10, 0x96, 0x93, 0x06, + 0xa9, 0x5c, 0x8c, 0xc6, 0x33, 0x23, 0x7b, 0x1a, 0x7b, 0x66, 0x35, 0x67, 0x76, 0x13, 0x0b, 0x21, + 0x15, 0xc1, 0x03, 0xf0, 0x58, 0xbd, 0xcc, 0x25, 0x57, 0x15, 0x4a, 0xde, 0x80, 0x27, 0x40, 0x3b, + 0x3b, 0xbb, 0x5d, 0x07, 0xa7, 0xb2, 0x7b, 0x95, 0x78, 0xbe, 0x39, 0xdf, 0xf7, 0x9d, 0x39, 0x33, + 0xe7, 0x2c, 0xda, 0x97, 0xca, 0x0a, 0xc3, 0xfa, 0x54, 0x2a, 0x02, 0x82, 0xc5, 0x46, 0xda, 0x51, 0x93, 0xb1, 0xa4, 0x19, 0x19, 0x9d, 0x48, 0x2e, 0x4c, 0x33, 0xd9, 0x6f, 0xf6, 0x84, 0x12, 0x20, - 0xa1, 0x11, 0x19, 0x6d, 0x35, 0xfe, 0x64, 0x42, 0x48, 0x83, 0xb1, 0xa4, 0x91, 0x87, 0x34, 0x92, + 0xa1, 0x11, 0x19, 0x6d, 0x35, 0xfe, 0x68, 0x42, 0x48, 0x83, 0xb1, 0xa4, 0x91, 0x87, 0x34, 0x92, 0xfd, 0xed, 0xcd, 0x9e, 0xee, 0x69, 0xb7, 0xbf, 0x99, 0xfe, 0x97, 0x85, 0x6e, 0xdf, 0xbf, 0x49, 0x2d, 0xd9, 0x6f, 0x42, 0x9f, 0x1a, 0xc1, 0x09, 0xd3, 0x0a, 0xe2, 0xa1, 0x30, 0x3e, 0xe2, 0xde, - 0x5b, 0x22, 0xce, 0xa4, 0x11, 0x7e, 0xdb, 0xc1, 0x34, 0x69, 0x14, 0xfe, 0x5c, 0x4c, 0xfd, 0x62, + 0x1b, 0x22, 0xce, 0xa4, 0x11, 0x7e, 0xdb, 0xc1, 0x34, 0x69, 0x14, 0xfe, 0x5c, 0x4c, 0xfd, 0x62, 0x05, 0xad, 0x7e, 0x97, 0x65, 0x76, 0x64, 0xa9, 0x15, 0x78, 0x0f, 0x6d, 0x24, 0x74, 0x00, 0xc2, 0x92, 0x38, 0xe2, 0xd4, 0x0a, 0x22, 0x79, 0x18, 0xec, 0x06, 0x7b, 0x8b, 0x9d, 0xf5, 0x6c, 0xfd, - 0x99, 0x5b, 0x6e, 0x71, 0xfc, 0x2b, 0x7a, 0x2f, 0xf7, 0x49, 0x20, 0x8d, 0x85, 0x70, 0x7e, 0x77, - 0x61, 0x6f, 0xe5, 0xe0, 0xa0, 0x31, 0xc5, 0xe1, 0x34, 0x9e, 0xf8, 0x58, 0x27, 0x7b, 0x58, 0x7b, - 0xf5, 0xfa, 0xee, 0xdc, 0xbf, 0xaf, 0xef, 0x56, 0x47, 0x74, 0x38, 0xf8, 0xaa, 0x7e, 0x8d, 0xb8, + 0xa9, 0x5b, 0x6e, 0x71, 0xfc, 0x2b, 0x7a, 0x27, 0xf7, 0x49, 0x20, 0x8d, 0x85, 0x70, 0x7e, 0x77, + 0x61, 0x6f, 0xe5, 0xe0, 0xa0, 0x31, 0xc5, 0xe1, 0x34, 0x1e, 0xfb, 0x58, 0x27, 0x7b, 0x58, 0x7b, + 0xf9, 0xea, 0xee, 0xdc, 0xbf, 0xaf, 0xee, 0x56, 0x47, 0x74, 0x38, 0xf8, 0xaa, 0x7e, 0x8d, 0xb8, 0xde, 0x59, 0x67, 0xe5, 0xed, 0x80, 0x7f, 0x41, 0x6b, 0xb1, 0xea, 0x6a, 0xc5, 0xa5, 0xea, 0x11, - 0x1d, 0x41, 0xb8, 0xe0, 0xa4, 0xef, 0x4f, 0x25, 0xfd, 0x2c, 0x8f, 0xfc, 0x29, 0x3a, 0x5c, 0x4c, - 0x85, 0x3b, 0xab, 0xf1, 0x9b, 0x25, 0xc0, 0x2f, 0xd0, 0xe6, 0x90, 0xda, 0xd8, 0x08, 0x32, 0xae, - 0xb1, 0xb8, 0x1b, 0xec, 0xad, 0x1c, 0x3c, 0x9c, 0x4a, 0xe3, 0x47, 0x47, 0xc0, 0x4b, 0x52, 0xd0, + 0x1d, 0x41, 0xb8, 0xe0, 0xa4, 0xef, 0x4f, 0x25, 0xfd, 0x34, 0x8f, 0xfc, 0x29, 0x3a, 0x5c, 0x4c, + 0x85, 0x3b, 0xab, 0xf1, 0xeb, 0x25, 0xc0, 0xcf, 0xd1, 0xe6, 0x90, 0xda, 0xd8, 0x08, 0x32, 0xae, + 0xb1, 0xb8, 0x1b, 0xec, 0xad, 0x1c, 0x3c, 0x98, 0x4a, 0xe3, 0x47, 0x47, 0xc0, 0x4b, 0x52, 0xd0, 0xc1, 0x19, 0x6b, 0x79, 0x0d, 0xff, 0x86, 0xb6, 0xaf, 0x9f, 0x37, 0xb1, 0x9a, 0xf4, 0x85, 0xec, 0xf5, 0x6d, 0x78, 0xcb, 0x65, 0xf5, 0xf5, 0x54, 0x8a, 0x27, 0x63, 0xe5, 0x39, 0xd6, 0xdf, 0x3b, 0x0a, 0x9f, 0x60, 0x35, 0x99, 0x88, 0xe2, 0x3f, 0x02, 0xb4, 0x53, 0x1c, 0x36, 0xe5, 0x5c, 0x5a, - 0xa9, 0x15, 0x89, 0x8c, 0x8e, 0x34, 0xd0, 0x01, 0x84, 0x4b, 0xce, 0xc0, 0xa3, 0x99, 0x2a, 0xfa, - 0xd8, 0xd3, 0xb4, 0x3d, 0x8b, 0xb7, 0xb0, 0xc5, 0x6e, 0xc0, 0x01, 0xbf, 0x0c, 0xd0, 0x76, 0xe1, + 0xa9, 0x15, 0x89, 0x8c, 0x8e, 0x34, 0xd0, 0x01, 0x84, 0x4b, 0xce, 0xc0, 0xc3, 0x99, 0x2a, 0xfa, + 0xc8, 0xd3, 0xb4, 0x3d, 0x8b, 0xb7, 0xb0, 0xc5, 0x6e, 0xc0, 0x01, 0xbf, 0x08, 0xd0, 0x76, 0xe1, 0xc2, 0x88, 0xa1, 0x4e, 0xe8, 0xa0, 0x64, 0xe2, 0xb6, 0x33, 0xf1, 0xcd, 0x4c, 0x26, 0x3a, 0x19, 0xcb, 0x35, 0x0f, 0x21, 0x9b, 0x0c, 0x03, 0x6e, 0xa1, 0xa5, 0x88, 0x1a, 0x3a, 0x84, 0x70, 0xd9, - 0x55, 0xf9, 0xd3, 0xa9, 0xd4, 0xda, 0x2e, 0xc4, 0x93, 0x7b, 0x02, 0x97, 0x4d, 0x42, 0x07, 0x92, + 0x55, 0xf9, 0xe3, 0xa9, 0xd4, 0xda, 0x2e, 0xc4, 0x93, 0x7b, 0x02, 0x97, 0x4d, 0x42, 0x07, 0x92, 0x53, 0xab, 0x4d, 0xf1, 0x96, 0x49, 0x14, 0x77, 0x4f, 0xc5, 0x08, 0xc2, 0xca, 0x0c, 0xd9, 0x9c, 0xe4, 0x34, 0x79, 0x5a, 0xed, 0xb8, 0xfb, 0x83, 0x18, 0xe5, 0xd9, 0x24, 0x13, 0xe0, 0x54, 0x03, - 0xff, 0x1e, 0xa0, 0x9d, 0x02, 0x04, 0xd2, 0x1d, 0x91, 0x72, 0x91, 0x4d, 0x88, 0xde, 0xc5, 0xc3, + 0xff, 0x1e, 0xa0, 0x9d, 0x02, 0x04, 0xd2, 0x1d, 0x91, 0x72, 0x91, 0x4d, 0x88, 0xde, 0xc6, 0xc3, 0xe1, 0xa8, 0x54, 0x61, 0xf3, 0x3f, 0x0f, 0x30, 0x8e, 0xe3, 0x04, 0xdd, 0x19, 0x13, 0x85, 0xf4, 0x5e, 0x47, 0x26, 0x56, 0x22, 0x5c, 0x71, 0xf2, 0x5f, 0xce, 0x7a, 0xab, 0x0c, 0x1c, 0xeb, 0x76, 0x4a, 0xe0, 0xb5, 0x37, 0xd9, 0x04, 0x0c, 0x9f, 0xa1, 0x3b, 0x52, 0x49, 0x4b, 0xac, 0x1c, 0x0a, 0x1d, 0x67, 0x7f, 0xc1, 0xd2, 0x61, 0x04, 0xe1, 0xea, 0x0c, 0xba, 0x2d, 0x25, 0xed, 0x71, 0x46, - 0x71, 0x9c, 0x33, 0x78, 0xdd, 0x0f, 0xe5, 0x04, 0x0c, 0xf0, 0x9f, 0x01, 0xfa, 0x48, 0x9c, 0x47, + 0x71, 0x9c, 0x33, 0x78, 0xdd, 0xf7, 0xe5, 0x04, 0x0c, 0xf0, 0x9f, 0x01, 0xfa, 0x40, 0x9c, 0x47, 0xda, 0x58, 0xc1, 0x49, 0x02, 0x8c, 0x80, 0x50, 0xbc, 0x2c, 0xbf, 0x36, 0xc3, 0x63, 0xfa, 0xd6, - 0x13, 0x9d, 0x00, 0x3b, 0x12, 0x8a, 0x5f, 0xb7, 0xb0, 0x25, 0x6e, 0xc0, 0xa1, 0xfe, 0x72, 0x11, + 0x13, 0x9d, 0x00, 0x3b, 0x12, 0x8a, 0x5f, 0xb7, 0xb0, 0x25, 0x6e, 0xc0, 0xa1, 0xfe, 0x62, 0x11, 0xad, 0x8d, 0x35, 0x57, 0xbc, 0x85, 0x96, 0x33, 0x35, 0xdf, 0xcb, 0x2b, 0x9d, 0xdb, 0xee, 0x77, - 0x8b, 0xe3, 0x8f, 0x11, 0x62, 0x7d, 0xaa, 0x94, 0x18, 0xa4, 0xe0, 0xbc, 0x03, 0x2b, 0x7e, 0xa5, + 0x8b, 0xe3, 0x0f, 0x11, 0x62, 0x7d, 0xaa, 0x94, 0x18, 0xa4, 0xe0, 0xbc, 0x03, 0x2b, 0x7e, 0xa5, 0xc5, 0xf1, 0x0e, 0xaa, 0xb0, 0x81, 0x14, 0xca, 0xa6, 0xe8, 0x82, 0x43, 0x97, 0xb3, 0x85, 0x16, 0xc7, 0xf7, 0xd0, 0x7a, 0x7a, 0x10, 0x92, 0x0e, 0xf2, 0x76, 0xb5, 0xe8, 0x06, 0xc5, 0x9a, 0x5f, 0xf5, 0x2d, 0x86, 0xa2, 0x8d, 0xe2, 0x1e, 0xf8, 0x21, 0x1a, 0xde, 0x72, 0x6f, 0xec, 0xe6, 0x6e, 0x5d, 0xaa, 0x7b, 0x79, 0x3a, 0xf9, 0xe4, 0x8b, 0xb9, 0xe3, 0x31, 0x6c, 0x51, 0x35, 0x12, 0x59, - 0x9f, 0xf6, 0xcd, 0x34, 0x4d, 0xa1, 0x27, 0xf2, 0xfe, 0xf5, 0xf0, 0x6d, 0x42, 0xc5, 0xfd, 0x3e, - 0x12, 0xf6, 0x89, 0x0b, 0x6b, 0x53, 0x76, 0x2a, 0xec, 0x53, 0x6a, 0x69, 0x7e, 0xd1, 0x3c, 0x7b, - 0xd6, 0x62, 0xb3, 0x4d, 0x80, 0x3f, 0x43, 0x18, 0x06, 0x14, 0xfa, 0x84, 0xeb, 0x33, 0x95, 0x96, - 0x99, 0x50, 0x76, 0xea, 0x9a, 0x55, 0xa5, 0xb3, 0xe1, 0x90, 0xa7, 0x1e, 0x78, 0xcc, 0x4e, 0xf1, - 0x0b, 0xf4, 0xc1, 0xd8, 0x34, 0x21, 0x52, 0x71, 0x71, 0x1e, 0x2e, 0x3b, 0x83, 0x0f, 0xa6, 0x7b, - 0x89, 0xc0, 0xca, 0xb3, 0xc3, 0x9b, 0x7b, 0xbf, 0x3c, 0xbb, 0x5a, 0x29, 0x69, 0xfd, 0x39, 0xaa, - 0x4e, 0x9e, 0x06, 0x33, 0x8c, 0xf7, 0x2a, 0x5a, 0xf2, 0x55, 0x9d, 0x77, 0xb8, 0xff, 0x75, 0xf8, - 0xf3, 0xab, 0xcb, 0x5a, 0x70, 0x71, 0x59, 0x0b, 0xfe, 0xb9, 0xac, 0x05, 0x7f, 0x5d, 0xd5, 0xe6, - 0x2e, 0xae, 0x6a, 0x73, 0x7f, 0x5f, 0xd5, 0xe6, 0x9e, 0x3f, 0xea, 0x49, 0xdb, 0x8f, 0xbb, 0x0d, - 0xa6, 0x87, 0x4d, 0xa6, 0x61, 0xa8, 0xa1, 0xf9, 0x26, 0xab, 0xcf, 0x8b, 0x2f, 0x92, 0xe4, 0x41, - 0xf3, 0x7c, 0xfc, 0xb3, 0xc4, 0x8e, 0x22, 0x01, 0xdd, 0x25, 0xf7, 0x45, 0xf2, 0xc5, 0x7f, 0x01, - 0x00, 0x00, 0xff, 0xff, 0xa6, 0x52, 0x42, 0x65, 0x8e, 0x09, 0x00, 0x00, + 0x9f, 0xf6, 0xcd, 0x34, 0x4d, 0xa1, 0x27, 0xf2, 0xfe, 0xf5, 0xe0, 0x4d, 0x42, 0xc5, 0xfd, 0x3e, + 0x12, 0xf6, 0xb1, 0x0b, 0x6b, 0x53, 0x76, 0x2a, 0xec, 0x13, 0x6a, 0x69, 0x7e, 0xd1, 0x3c, 0x7b, + 0xd6, 0x62, 0xb3, 0x4d, 0x80, 0x3f, 0x41, 0x18, 0x06, 0x14, 0xfa, 0x84, 0xeb, 0x33, 0x95, 0x96, + 0x99, 0x50, 0x76, 0xea, 0x9a, 0x55, 0xa5, 0xb3, 0xe1, 0x90, 0x27, 0x1e, 0x78, 0xc4, 0x4e, 0xf1, + 0x73, 0xf4, 0xde, 0xd8, 0x34, 0x21, 0x52, 0x71, 0x71, 0x1e, 0x2e, 0x3b, 0x83, 0x9f, 0x4f, 0xf7, + 0x12, 0x81, 0x95, 0x67, 0x87, 0x37, 0xf7, 0x6e, 0x79, 0x76, 0xb5, 0x52, 0xd2, 0xfa, 0x33, 0x54, + 0x9d, 0x3c, 0x0d, 0x66, 0x18, 0xef, 0x55, 0xb4, 0xe4, 0xab, 0x3a, 0xef, 0x70, 0xff, 0xeb, 0xf0, + 0xe7, 0x97, 0x97, 0xb5, 0xe0, 0xe2, 0xb2, 0x16, 0xfc, 0x73, 0x59, 0x0b, 0xfe, 0xba, 0xaa, 0xcd, + 0x5d, 0x5c, 0xd5, 0xe6, 0xfe, 0xbe, 0xaa, 0xcd, 0x3d, 0x7b, 0xd8, 0x93, 0xb6, 0x1f, 0x77, 0x1b, + 0x4c, 0x0f, 0x9b, 0x4c, 0xc3, 0x50, 0x43, 0xf3, 0x75, 0x56, 0x9f, 0x16, 0x5f, 0x24, 0xc9, 0x17, + 0xcd, 0xf3, 0xf1, 0xcf, 0x12, 0x3b, 0x8a, 0x04, 0x74, 0x97, 0xdc, 0x17, 0xc9, 0x67, 0xff, 0x05, + 0x00, 0x00, 0xff, 0xff, 0xae, 0xb1, 0x22, 0x59, 0x8e, 0x09, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/x/ccv/provider/types/genesis_test.go b/x/ccv/provider/types/genesis_test.go index 45d766fcfb..7e15c218b8 100644 --- a/x/ccv/provider/types/genesis_test.go +++ b/x/ccv/provider/types/genesis_test.go @@ -4,9 +4,10 @@ import ( "testing" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + "cosmossdk.io/math" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" @@ -14,9 +15,9 @@ import ( abci "github.com/cometbft/cometbft/abci/types" tmtypes "github.com/cometbft/cometbft/types" - "github.com/cosmos/interchain-security/v4/testutil/crypto" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" - ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/testutil/crypto" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // Tests validation of consumer states and params within a provider genesis state @@ -81,7 +82,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), nil, nil, nil, @@ -102,7 +103,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), nil, nil, nil, @@ -123,7 +124,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), nil, nil, nil, @@ -144,7 +145,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), nil, nil, nil, @@ -171,7 +172,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), nil, nil, nil, @@ -198,7 +199,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), nil, nil, nil, @@ -225,7 +226,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: sdk.NewInt(1000000)}), + sdk.Coin{Denom: "stake", Amount: math.NewInt(1000000)}), nil, nil, nil, @@ -252,7 +253,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), nil, nil, nil, @@ -279,7 +280,7 @@ func TestValidateGenesisState(t *testing.T) { 0, // 0 vsc timeout here types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), nil, nil, nil, @@ -306,7 +307,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, 0, // 0 slash meter replenish period here types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), nil, nil, nil, @@ -333,7 +334,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, "1.15", - sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), nil, nil, nil, @@ -685,7 +686,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: sdk.NewInt(10000000)}), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: math.NewInt(10000000)}), nil, nil, nil, @@ -706,7 +707,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(-1000000)}), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(-1000000)}), nil, nil, nil, diff --git a/x/ccv/provider/types/key_assignment.go b/x/ccv/provider/types/key_assignment.go index 04192ae53a..ee403e1e49 100644 --- a/x/ccv/provider/types/key_assignment.go +++ b/x/ccv/provider/types/key_assignment.go @@ -8,7 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // A validator's consensus address on the provider chain. diff --git a/x/ccv/provider/types/keys.go b/x/ccv/provider/types/keys.go index 615b901368..9208d8711c 100644 --- a/x/ccv/provider/types/keys.go +++ b/x/ccv/provider/types/keys.go @@ -8,7 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) type Status int @@ -145,6 +145,9 @@ const ( // ProposedConsumerChainByteKey is the byte prefix storing the consumer chainId in consumerAddition gov proposal submitted before voting finishes ProposedConsumerChainByteKey + // ParametersKey is the is the single byte key for storing provider's parameters. + ParametersByteKey + // NOTE: DO NOT ADD NEW BYTE PREFIXES HERE WITHOUT ADDING THEM TO getAllKeyPrefixes() IN keys_test.go ) @@ -152,6 +155,11 @@ const ( // Fully defined key func section // +// ParametersKey returns the key for the parameters of the provider module in the store +func ParametersKey() []byte { + return []byte{ParametersByteKey} +} + // PortKey returns the key to the port ID in the store func PortKey() []byte { return []byte{PortByteKey} diff --git a/x/ccv/provider/types/keys_test.go b/x/ccv/provider/types/keys_test.go index 4d5ea58ff8..50a9fc4400 100644 --- a/x/ccv/provider/types/keys_test.go +++ b/x/ccv/provider/types/keys_test.go @@ -8,8 +8,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - cryptoutil "github.com/cosmos/interchain-security/v4/testutil/crypto" - providertypes "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + cryptoutil "github.com/cosmos/interchain-security/v5/testutil/crypto" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) // Tests that all singular keys, or prefixes to fully resolves keys are non duplicate byte values. @@ -56,6 +56,7 @@ func getAllKeyPrefixes() []byte { providertypes.VSCMaturedHandledThisBlockBytePrefix, providertypes.EquivocationEvidenceMinHeightBytePrefix, providertypes.ProposedConsumerChainByteKey, + providertypes.ParametersByteKey, } } diff --git a/x/ccv/provider/types/proposal.go b/x/ccv/provider/types/legacy_proposal.go similarity index 97% rename from x/ccv/provider/types/proposal.go rename to x/ccv/provider/types/legacy_proposal.go index 93cadfd14e..4076e37ed7 100644 --- a/x/ccv/provider/types/proposal.go +++ b/x/ccv/provider/types/legacy_proposal.go @@ -6,15 +6,16 @@ import ( "strings" time "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" errorsmod "cosmossdk.io/errors" + "cosmossdk.io/math" + evidencetypes "cosmossdk.io/x/evidence/types" sdk "github.com/cosmos/cosmos-sdk/types" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) const ( @@ -279,12 +280,12 @@ func (crdp *ChangeRewardDenomsProposal) ValidateBasic() error { // Return error if any denom is "invalid" for _, denom := range crdp.DenomsToAdd { - if !sdk.NewCoin(denom, sdk.NewInt(1)).IsValid() { + if !sdk.NewCoin(denom, math.NewInt(1)).IsValid() { return fmt.Errorf("invalid change reward denoms proposal: %s is not a valid denom", denom) } } for _, denom := range crdp.DenomsToRemove { - if !sdk.NewCoin(denom, sdk.NewInt(1)).IsValid() { + if !sdk.NewCoin(denom, math.NewInt(1)).IsValid() { return fmt.Errorf("invalid change reward denoms proposal: %s is not a valid denom", denom) } } diff --git a/x/ccv/provider/types/proposal_test.go b/x/ccv/provider/types/legacy_proposal_test.go similarity index 97% rename from x/ccv/provider/types/proposal_test.go rename to x/ccv/provider/types/legacy_proposal_test.go index 72fcfe8436..8253af35cf 100644 --- a/x/ccv/provider/types/proposal_test.go +++ b/x/ccv/provider/types/legacy_proposal_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/golang/protobuf/proto" //nolint:staticcheck // see: https://github.com/cosmos/interchain-security/issues/236 "github.com/stretchr/testify/require" @@ -15,7 +15,7 @@ import ( govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) func TestConsumerAdditionProposalValidateBasic(t *testing.T) { diff --git a/x/ccv/provider/types/msg.go b/x/ccv/provider/types/msg.go index 55e6b2fae4..d7b9d14c12 100644 --- a/x/ccv/provider/types/msg.go +++ b/x/ccv/provider/types/msg.go @@ -5,16 +5,17 @@ import ( "fmt" "strings" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" errorsmod "cosmossdk.io/errors" + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" tmtypes "github.com/cometbft/cometbft/proto/tendermint/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // provider message types @@ -25,20 +26,31 @@ const ( ) var ( - _ sdk.Msg = &MsgAssignConsumerKey{} - _ sdk.Msg = &MsgSubmitConsumerMisbehaviour{} - _ sdk.Msg = &MsgSubmitConsumerDoubleVoting{} + _ sdk.Msg = (*MsgAssignConsumerKey)(nil) + _ sdk.Msg = (*MsgConsumerAddition)(nil) + _ sdk.Msg = (*MsgConsumerRemoval)(nil) + _ sdk.Msg = (*MsgChangeRewardDenoms)(nil) + _ sdk.Msg = (*MsgSubmitConsumerMisbehaviour)(nil) + _ sdk.Msg = (*MsgSubmitConsumerDoubleVoting)(nil) + + _ sdk.HasValidateBasic = (*MsgAssignConsumerKey)(nil) + _ sdk.HasValidateBasic = (*MsgConsumerAddition)(nil) + _ sdk.HasValidateBasic = (*MsgConsumerRemoval)(nil) + _ sdk.HasValidateBasic = (*MsgChangeRewardDenoms)(nil) + _ sdk.HasValidateBasic = (*MsgSubmitConsumerMisbehaviour)(nil) + _ sdk.HasValidateBasic = (*MsgSubmitConsumerDoubleVoting)(nil) ) // NewMsgAssignConsumerKey creates a new MsgAssignConsumerKey instance. // Delegator address and validator address are the same. func NewMsgAssignConsumerKey(chainID string, providerValidatorAddress sdk.ValAddress, - consumerConsensusPubKey string, + consumerConsensusPubKey, signer string, ) (*MsgAssignConsumerKey, error) { return &MsgAssignConsumerKey{ ChainId: chainID, ProviderAddr: providerValidatorAddress.String(), ConsumerKey: consumerConsensusPubKey, + Signer: signer, }, nil } @@ -203,3 +215,118 @@ func (msg MsgSubmitConsumerDoubleVoting) GetSigners() []sdk.AccAddress { } return []sdk.AccAddress{addr} } + +// GetSigners implements the sdk.Msg interface. It returns the address(es) that +// must sign over msg.GetSignBytes(). +// If the validator address is not same as delegator's, then the validator must +// sign the msg as well. +func (msg *MsgConsumerAddition) GetSigners() []sdk.AccAddress { + valAddr, err := sdk.ValAddressFromBech32(msg.Authority) + if err != nil { + // same behavior as in cosmos-sdk + panic(err) + } + return []sdk.AccAddress{valAddr.Bytes()} +} + +// ValidateBasic implements the sdk.Msg interface. +func (msg *MsgConsumerAddition) ValidateBasic() error { + if strings.TrimSpace(msg.ChainId) == "" { + return ErrBlankConsumerChainID + } + + if strings.TrimSpace(msg.ChainId) == "" { + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "consumer chain id must not be blank") + } + + if msg.InitialHeight.IsZero() { + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "initial height cannot be zero") + } + + if len(msg.GenesisHash) == 0 { + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "genesis hash cannot be empty") + } + if len(msg.BinaryHash) == 0 { + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "binary hash cannot be empty") + } + + if msg.SpawnTime.IsZero() { + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "spawn time cannot be zero") + } + + if err := ccvtypes.ValidateStringFraction(msg.ConsumerRedistributionFraction); err != nil { + return errorsmod.Wrapf(ErrInvalidConsumerAdditionProposal, "consumer redistribution fraction is invalid: %s", err) + } + + if err := ccvtypes.ValidatePositiveInt64(msg.BlocksPerDistributionTransmission); err != nil { + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "blocks per distribution transmission cannot be < 1") + } + + if err := ccvtypes.ValidateDistributionTransmissionChannel(msg.DistributionTransmissionChannel); err != nil { + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "distribution transmission channel") + } + + if err := ccvtypes.ValidatePositiveInt64(msg.HistoricalEntries); err != nil { + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "historical entries cannot be < 1") + } + + if err := ccvtypes.ValidateDuration(msg.CcvTimeoutPeriod); err != nil { + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "ccv timeout period cannot be zero") + } + + if err := ccvtypes.ValidateDuration(msg.TransferTimeoutPeriod); err != nil { + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "transfer timeout period cannot be zero") + } + + if err := ccvtypes.ValidateDuration(msg.UnbondingPeriod); err != nil { + return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "unbonding period cannot be zero") + } + + return nil +} + +func (msg *MsgConsumerRemoval) ValidateBasic() error { + + if strings.TrimSpace(msg.ChainId) == "" { + return errorsmod.Wrap(ErrInvalidConsumerRemovalProp, "consumer chain id must not be blank") + } + + if msg.StopTime.IsZero() { + return errorsmod.Wrap(ErrInvalidConsumerRemovalProp, "spawn time cannot be zero") + } + return nil +} + +func (msg *MsgChangeRewardDenoms) ValidateBasic() error { + emptyDenomsToAdd := len(msg.DenomsToAdd) == 0 + emptyDenomsToRemove := len(msg.DenomsToRemove) == 0 + // Return error if both sets are empty or nil + if emptyDenomsToAdd && emptyDenomsToRemove { + return fmt.Errorf( + "invalid change reward denoms proposal: both denoms to add and denoms to remove are empty") + } + + // Return error if a denom is in both sets + for _, denomToAdd := range msg.DenomsToAdd { + for _, denomToRemove := range msg.DenomsToRemove { + if denomToAdd == denomToRemove { + return fmt.Errorf( + "invalid change reward denoms proposal: %s cannot be both added and removed", denomToAdd) + } + } + } + + // Return error if any denom is "invalid" + for _, denom := range msg.DenomsToAdd { + if !sdk.NewCoin(denom, math.NewInt(1)).IsValid() { + return fmt.Errorf("invalid change reward denoms proposal: %s is not a valid denom", denom) + } + } + for _, denom := range msg.DenomsToRemove { + if !sdk.NewCoin(denom, math.NewInt(1)).IsValid() { + return fmt.Errorf("invalid change reward denoms proposal: %s is not a valid denom", denom) + } + } + + return nil +} diff --git a/x/ccv/provider/types/params.go b/x/ccv/provider/types/params.go index a580e60f41..38e93bb1f9 100644 --- a/x/ccv/provider/types/params.go +++ b/x/ccv/provider/types/params.go @@ -4,14 +4,15 @@ import ( "fmt" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + "cosmossdk.io/math" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) const ( @@ -39,6 +40,9 @@ const ( ) // Reflection based keys for params subspace +// Legacy: usage of x/params for parameters is deprecated. +// Use x/ccv/provider/keeper/params instead +// [DEPRECATED] var ( KeyTemplateClient = []byte("TemplateClient") KeyTrustingPeriodFraction = []byte("TrustingPeriodFraction") @@ -102,7 +106,7 @@ func DefaultParams() Params { // Following the pattern from cosmos-sdk/staking/types/params.go sdk.Coin{ Denom: sdk.DefaultBondDenom, - Amount: sdk.NewInt(10000000), + Amount: math.NewInt(10000000), }, ) } diff --git a/x/ccv/provider/types/params_test.go b/x/ccv/provider/types/params_test.go index 1de6b6fe54..efc6f2fa82 100644 --- a/x/ccv/provider/types/params_test.go +++ b/x/ccv/provider/types/params_test.go @@ -4,14 +4,15 @@ import ( "testing" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - commitmenttypes "github.com/cosmos/ibc-go/v7/modules/core/23-commitment/types" - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + "cosmossdk.io/math" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/interchain-security/v4/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) func TestValidateParams(t *testing.T) { @@ -24,39 +25,39 @@ func TestValidateParams(t *testing.T) { {"custom valid params", types.NewParams( ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), true}, + "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), true}, {"custom invalid params", types.NewParams( ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, 0, clienttypes.Height{}, nil, []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, + "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), false}, {"blank client", types.NewParams(&ibctmtypes.ClientState{}, - "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, - {"nil client", types.NewParams(nil, "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, + "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), false}, + {"nil client", types.NewParams(nil, "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), false}, // Check if "0.00" is valid or if a zero dec TrustFraction needs to return an error {"0 trusting period fraction", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.00", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), true}, + "0.00", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), true}, {"0 ccv timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", 0, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, + "0.33", 0, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), false}, {"0 init timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, 0, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, + "0.33", time.Hour, 0, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), false}, {"0 vsc timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 0, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, + "0.33", time.Hour, time.Hour, 0, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), false}, {"0 slash meter replenish period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 24*time.Hour, 0, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, + "0.33", time.Hour, time.Hour, 24*time.Hour, 0, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), false}, {"slash meter replenish fraction over 1", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "1.5", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, + "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "1.5", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}), false}, {"invalid consumer reward denom registration fee denom", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: sdk.NewInt(10000000)}), false}, + "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: math.NewInt(10000000)}), false}, {"invalid consumer reward denom registration fee amount", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(-10000000)}), false}, + "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(-10000000)}), false}, } for _, tc := range testCases { diff --git a/x/ccv/provider/types/provider.pb.go b/x/ccv/provider/types/provider.pb.go index 41a87e69f4..77c76d941a 100644 --- a/x/ccv/provider/types/provider.pb.go +++ b/x/ccv/provider/types/provider.pb.go @@ -4,16 +4,17 @@ package types import ( + types1 "cosmossdk.io/x/evidence/types" fmt "fmt" crypto "github.com/cometbft/cometbft/proto/tendermint/crypto" + _ "github.com/cosmos/cosmos-proto" types2 "github.com/cosmos/cosmos-sdk/types" - types1 "github.com/cosmos/cosmos-sdk/x/evidence/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" - types "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - _07_tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" - types3 "github.com/cosmos/interchain-security/v4/x/ccv/types" + types "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + _07_tendermint "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + types3 "github.com/cosmos/interchain-security/v5/x/ccv/types" _ "google.golang.org/protobuf/types/known/durationpb" _ "google.golang.org/protobuf/types/known/timestamppb" io "io" @@ -39,6 +40,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // chain are expected to validate the consumer chain at spawn time or get // slashed. It is recommended that spawn time occurs after the proposal end // time. +// Deprecated: Use MsgConsumerAddition instead +// +// Deprecated: Do not use. type ConsumerAdditionProposal struct { // the title of the proposal Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` @@ -128,6 +132,9 @@ var xxx_messageInfo_ConsumerAdditionProposal proto.InternalMessageInfo // remove (and stop) a consumer chain. If it passes, all the consumer chain's // state is removed from the provider chain. The outstanding unbonding operation // funds are released. +// Deprecated: Use MsgConsumerRemoval instead +// +// Deprecated: Do not use. type ConsumerRemovalProposal struct { // the title of the proposal Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` @@ -274,6 +281,9 @@ func (m *EquivocationProposal) GetEquivocations() []*types1.Equivocation { // ChangeRewardDenomsProposal is a governance proposal on the provider chain to // mutate the set of denoms accepted by the provider as rewards. +// Deprecated: Use MsgChangeRewardDenoms instead +// +// Deprecated: Do not use. type ChangeRewardDenomsProposal struct { // the title of the proposal Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` @@ -1415,113 +1425,115 @@ func init() { } var fileDescriptor_f22ec409a72b7b72 = []byte{ - // 1694 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xcd, 0x72, 0x1b, 0xc7, - 0x11, 0xe6, 0x12, 0x20, 0x45, 0x34, 0xf8, 0xa7, 0x25, 0x6d, 0x2d, 0x15, 0x06, 0xa4, 0xd6, 0xb1, - 0xc3, 0x94, 0xcb, 0x8b, 0x90, 0x4e, 0xaa, 0x5c, 0xaa, 0xb8, 0x5c, 0x24, 0x28, 0x5b, 0x14, 0x63, - 0x8b, 0x5e, 0x32, 0x54, 0x25, 0x39, 0x6c, 0x0d, 0x66, 0x47, 0xc0, 0x14, 0x17, 0x3b, 0xab, 0x99, - 0xd9, 0x95, 0x71, 0xc9, 0x39, 0x47, 0xe7, 0xe6, 0xca, 0x25, 0x4e, 0x5e, 0x20, 0xe7, 0xbc, 0x81, - 0x8f, 0x3e, 0xe6, 0x64, 0xa7, 0xa4, 0x63, 0x5e, 0x22, 0x35, 0xb3, 0xff, 0x20, 0xa1, 0x40, 0xe5, - 0xe4, 0x36, 0xdb, 0xd3, 0xfd, 0x75, 0xcf, 0x74, 0xf7, 0xd7, 0x03, 0xc0, 0x01, 0x0d, 0x25, 0xe1, - 0x78, 0x88, 0x68, 0xe8, 0x09, 0x82, 0x63, 0x4e, 0xe5, 0xb8, 0x8b, 0x71, 0xd2, 0x8d, 0x38, 0x4b, - 0xa8, 0x4f, 0x78, 0x37, 0xd9, 0x2f, 0xd6, 0x4e, 0xc4, 0x99, 0x64, 0xe6, 0x5b, 0x37, 0xd8, 0x38, - 0x18, 0x27, 0x4e, 0xa1, 0x97, 0xec, 0xdf, 0x7d, 0x7b, 0x1a, 0x70, 0xb2, 0xdf, 0x7d, 0x4e, 0x39, - 0x49, 0xb1, 0xee, 0x6e, 0x0e, 0xd8, 0x80, 0xe9, 0x65, 0x57, 0xad, 0x32, 0xe9, 0xce, 0x80, 0xb1, - 0x41, 0x40, 0xba, 0xfa, 0xab, 0x1f, 0x3f, 0xed, 0x4a, 0x3a, 0x22, 0x42, 0xa2, 0x51, 0x94, 0x29, - 0x74, 0x26, 0x15, 0xfc, 0x98, 0x23, 0x49, 0x59, 0x98, 0x03, 0xd0, 0x3e, 0xee, 0x62, 0xc6, 0x49, - 0x17, 0x07, 0x94, 0x84, 0x52, 0x79, 0x4d, 0x57, 0x99, 0x42, 0x57, 0x29, 0x04, 0x74, 0x30, 0x94, - 0xa9, 0x58, 0x74, 0x25, 0x09, 0x7d, 0xc2, 0x47, 0x34, 0x55, 0x2e, 0xbf, 0x32, 0x83, 0xed, 0xca, - 0x3e, 0xe6, 0xe3, 0x48, 0xb2, 0xee, 0x15, 0x19, 0x8b, 0x6c, 0xf7, 0x1d, 0xcc, 0xc4, 0x88, 0x89, - 0x2e, 0x51, 0xe7, 0x0f, 0x31, 0xe9, 0x26, 0xfb, 0x7d, 0x22, 0xd1, 0x7e, 0x21, 0xc8, 0xe3, 0xce, - 0xf4, 0xfa, 0x48, 0x94, 0x3a, 0x98, 0xd1, 0x2c, 0x6e, 0xfb, 0xfb, 0x45, 0xb0, 0x7a, 0x2c, 0x14, - 0xf1, 0x88, 0xf0, 0x43, 0xdf, 0xa7, 0xea, 0x48, 0x67, 0x9c, 0x45, 0x4c, 0xa0, 0xc0, 0xdc, 0x84, - 0x05, 0x49, 0x65, 0x40, 0x2c, 0x63, 0xd7, 0xd8, 0x6b, 0xb9, 0xe9, 0x87, 0xb9, 0x0b, 0x6d, 0x9f, - 0x08, 0xcc, 0x69, 0xa4, 0x94, 0xad, 0x79, 0xbd, 0x57, 0x15, 0x99, 0x5b, 0xb0, 0x94, 0xe6, 0x81, - 0xfa, 0x56, 0x43, 0x6f, 0xdf, 0xd2, 0xdf, 0x27, 0xbe, 0xf9, 0x09, 0xac, 0xd2, 0x90, 0x4a, 0x8a, - 0x02, 0x6f, 0x48, 0xd4, 0x6d, 0x58, 0xcd, 0x5d, 0x63, 0xaf, 0x7d, 0x70, 0xd7, 0xa1, 0x7d, 0xec, - 0xa8, 0x0b, 0x74, 0xb2, 0x6b, 0x4b, 0xf6, 0x9d, 0x87, 0x5a, 0xe3, 0xa8, 0xf9, 0xcd, 0x77, 0x3b, - 0x73, 0xee, 0x4a, 0x66, 0x97, 0x0a, 0xcd, 0x7b, 0xb0, 0x3c, 0x20, 0x21, 0x11, 0x54, 0x78, 0x43, - 0x24, 0x86, 0xd6, 0xc2, 0xae, 0xb1, 0xb7, 0xec, 0xb6, 0x33, 0xd9, 0x43, 0x24, 0x86, 0xe6, 0x0e, - 0xb4, 0xfb, 0x34, 0x44, 0x7c, 0x9c, 0x6a, 0x2c, 0x6a, 0x0d, 0x48, 0x45, 0x5a, 0xa1, 0x07, 0x20, - 0x22, 0xf4, 0x3c, 0xf4, 0x54, 0xb6, 0xad, 0x5b, 0x59, 0x20, 0x69, 0xa6, 0x9d, 0x3c, 0xd3, 0xce, - 0x45, 0x5e, 0x0a, 0x47, 0x4b, 0x2a, 0x90, 0x2f, 0xbf, 0xdf, 0x31, 0xdc, 0x96, 0xb6, 0x53, 0x3b, - 0xe6, 0x67, 0xb0, 0x1e, 0x87, 0x7d, 0x16, 0xfa, 0x34, 0x1c, 0x78, 0x11, 0xe1, 0x94, 0xf9, 0xd6, - 0x92, 0x86, 0xda, 0xba, 0x06, 0x75, 0x9c, 0x15, 0x4d, 0x8a, 0xf4, 0x95, 0x42, 0x5a, 0x2b, 0x8c, - 0xcf, 0xb4, 0xad, 0xf9, 0x39, 0x98, 0x18, 0x27, 0x3a, 0x24, 0x16, 0xcb, 0x1c, 0xb1, 0x35, 0x3b, - 0xe2, 0x3a, 0xc6, 0xc9, 0x45, 0x6a, 0x9d, 0x41, 0xfe, 0x1e, 0xee, 0x48, 0x8e, 0x42, 0xf1, 0x94, - 0xf0, 0x49, 0x5c, 0x98, 0x1d, 0xf7, 0x8d, 0x1c, 0xa3, 0x0e, 0xfe, 0x10, 0x76, 0x71, 0x56, 0x40, - 0x1e, 0x27, 0x3e, 0x15, 0x92, 0xd3, 0x7e, 0xac, 0x6c, 0xbd, 0xa7, 0x1c, 0x61, 0x5d, 0x23, 0x6d, - 0x5d, 0x04, 0x9d, 0x5c, 0xcf, 0xad, 0xa9, 0x7d, 0x9c, 0x69, 0x99, 0x8f, 0xe1, 0x27, 0xfd, 0x80, - 0xe1, 0x2b, 0xa1, 0x82, 0xf3, 0x6a, 0x48, 0xda, 0xf5, 0x88, 0x0a, 0xa1, 0xd0, 0x96, 0x77, 0x8d, - 0xbd, 0x86, 0x7b, 0x2f, 0xd5, 0x3d, 0x23, 0xfc, 0xb8, 0xa2, 0x79, 0x51, 0x51, 0x34, 0xdf, 0x03, - 0x73, 0x48, 0x85, 0x64, 0x9c, 0x62, 0x14, 0x78, 0x24, 0x94, 0x9c, 0x12, 0x61, 0xad, 0x68, 0xf3, - 0xdb, 0xe5, 0xce, 0x83, 0x74, 0xc3, 0x7c, 0x04, 0xf7, 0xa6, 0x3a, 0xf5, 0xf0, 0x10, 0x85, 0x21, - 0x09, 0xac, 0x55, 0x7d, 0x94, 0x1d, 0x7f, 0x8a, 0xcf, 0x5e, 0xaa, 0x76, 0x7f, 0xe9, 0x8f, 0x5f, - 0xef, 0xcc, 0x7d, 0xf5, 0xf5, 0xce, 0x9c, 0xfd, 0x77, 0x03, 0xee, 0xf4, 0x8a, 0x83, 0x8f, 0x58, - 0x82, 0x82, 0xff, 0x67, 0x83, 0x1d, 0x42, 0x4b, 0x48, 0x16, 0xa5, 0x25, 0xdd, 0x7c, 0x8d, 0x92, - 0x5e, 0x52, 0x66, 0x6a, 0xc3, 0xfe, 0x8b, 0x01, 0x9b, 0x0f, 0x9e, 0xc5, 0x34, 0x61, 0x18, 0xfd, - 0x4f, 0xf8, 0xe0, 0x14, 0x56, 0x48, 0x05, 0x4f, 0x58, 0x8d, 0xdd, 0xc6, 0x5e, 0xfb, 0xe0, 0x6d, - 0x27, 0x25, 0x27, 0xa7, 0xe0, 0xac, 0x8c, 0xa0, 0x9c, 0xaa, 0x77, 0xb7, 0x6e, 0x7b, 0x7f, 0xde, - 0x32, 0xec, 0xbf, 0x19, 0x70, 0x57, 0xdd, 0xf4, 0x80, 0xb8, 0xe4, 0x39, 0xe2, 0xfe, 0x31, 0x09, - 0xd9, 0x48, 0xfc, 0xe0, 0x38, 0x6d, 0x58, 0xf1, 0x35, 0x92, 0x27, 0x99, 0x87, 0x7c, 0x5f, 0xc7, - 0xa9, 0x75, 0x94, 0xf0, 0x82, 0x1d, 0xfa, 0xbe, 0xb9, 0x07, 0xeb, 0xa5, 0x0e, 0x57, 0xf9, 0x54, - 0xd7, 0xac, 0xd4, 0x56, 0x73, 0x35, 0x9d, 0x65, 0x62, 0xff, 0xdb, 0x80, 0xf5, 0x4f, 0x02, 0xd6, - 0x47, 0xc1, 0x79, 0x80, 0xc4, 0x50, 0x55, 0xd9, 0x58, 0xa5, 0x87, 0x93, 0xac, 0xbd, 0x75, 0x78, - 0x33, 0xa7, 0x47, 0x99, 0x69, 0xc2, 0xf9, 0x08, 0x6e, 0x17, 0x0d, 0x57, 0x54, 0x81, 0x3e, 0xcd, - 0xd1, 0xc6, 0x8b, 0xef, 0x76, 0xd6, 0xf2, 0x62, 0xeb, 0xe9, 0x8a, 0x38, 0x76, 0xd7, 0x70, 0x4d, - 0xe0, 0x9b, 0x1d, 0x68, 0xd3, 0x3e, 0xf6, 0x04, 0x79, 0xe6, 0x85, 0xf1, 0x48, 0x17, 0x50, 0xd3, - 0x6d, 0xd1, 0x3e, 0x3e, 0x27, 0xcf, 0x3e, 0x8b, 0x47, 0xe6, 0xfb, 0xf0, 0x66, 0x3e, 0x58, 0xbd, - 0x04, 0x05, 0x9e, 0xb2, 0x57, 0xd7, 0xc1, 0x75, 0x3d, 0x2d, 0xbb, 0x1b, 0xf9, 0xee, 0x25, 0x0a, - 0x94, 0xb3, 0x43, 0xdf, 0xe7, 0xf6, 0x3f, 0x16, 0x60, 0xf1, 0x0c, 0x71, 0x34, 0x12, 0xe6, 0x05, - 0xac, 0x49, 0x32, 0x8a, 0x02, 0x24, 0x89, 0x97, 0x92, 0x79, 0x76, 0xd2, 0x77, 0x35, 0xc9, 0x57, - 0x87, 0xa0, 0x53, 0x19, 0x7b, 0xc9, 0xbe, 0xd3, 0xd3, 0xd2, 0x73, 0x89, 0x24, 0x71, 0x57, 0x73, - 0x8c, 0x54, 0x68, 0x7e, 0x00, 0x96, 0xe4, 0xb1, 0x90, 0x25, 0xcd, 0x96, 0xfc, 0x92, 0xe6, 0xf2, - 0xcd, 0x7c, 0x3f, 0x65, 0xa6, 0x82, 0x57, 0x6e, 0x66, 0xd4, 0xc6, 0x0f, 0x61, 0xd4, 0x73, 0xd8, - 0x50, 0xe3, 0x68, 0x12, 0xb3, 0x39, 0x3b, 0xe6, 0x6d, 0x65, 0x5f, 0x07, 0xfd, 0x1c, 0xcc, 0x44, - 0xe0, 0x49, 0xcc, 0x85, 0xd7, 0x88, 0x33, 0x11, 0xb8, 0x0e, 0xe9, 0xc3, 0xb6, 0x50, 0xc5, 0xe7, - 0x8d, 0x88, 0xd4, 0xfc, 0x1c, 0x05, 0x24, 0xa4, 0x62, 0x98, 0x83, 0x2f, 0xce, 0x0e, 0xbe, 0xa5, - 0x81, 0x3e, 0x55, 0x38, 0x6e, 0x0e, 0x93, 0x79, 0xe9, 0x41, 0xe7, 0x66, 0x2f, 0x45, 0x82, 0x6e, - 0xe9, 0x04, 0xfd, 0xe8, 0x06, 0x88, 0x22, 0x4b, 0x02, 0xde, 0xa9, 0xcc, 0x11, 0xd5, 0xd5, 0x9e, - 0x6e, 0x28, 0x8f, 0x93, 0x81, 0x22, 0x5b, 0x94, 0x8e, 0x14, 0x42, 0x8a, 0x59, 0x98, 0xb1, 0x87, - 0x7a, 0xda, 0x14, 0xcc, 0xd1, 0x63, 0x34, 0xcc, 0x1e, 0x0c, 0x76, 0x39, 0x6e, 0x0a, 0x8e, 0x70, - 0x2b, 0x58, 0x1f, 0x13, 0xf2, 0xa8, 0xb9, 0xb4, 0xb4, 0xde, 0xb2, 0x7f, 0x06, 0x2d, 0xdd, 0xa2, - 0x87, 0xf8, 0x4a, 0x98, 0xdb, 0xd0, 0x52, 0xb5, 0x4e, 0x84, 0x20, 0xc2, 0x32, 0x74, 0x67, 0x97, - 0x02, 0x5b, 0xc2, 0xd6, 0xb4, 0xe7, 0x92, 0x30, 0x9f, 0xc0, 0xad, 0x88, 0xe8, 0x59, 0xae, 0x0d, - 0xdb, 0x07, 0x1f, 0x3a, 0x33, 0xbc, 0x5c, 0x9d, 0x69, 0x80, 0x6e, 0x8e, 0x66, 0xf3, 0xf2, 0x91, - 0x36, 0x31, 0x42, 0x84, 0x79, 0x39, 0xe9, 0xf4, 0x57, 0xaf, 0xe5, 0x74, 0x02, 0xaf, 0xf4, 0xf9, - 0x2e, 0xb4, 0x0f, 0xd3, 0x63, 0xff, 0x9a, 0x0a, 0x79, 0xfd, 0x5a, 0x96, 0xab, 0xd7, 0xf2, 0x08, - 0x56, 0xb3, 0xc9, 0x77, 0xc1, 0x34, 0xcd, 0x98, 0x3f, 0x06, 0xc8, 0x46, 0xa6, 0xa2, 0xa7, 0x94, - 0x88, 0x5b, 0x99, 0xe4, 0xc4, 0xaf, 0x4d, 0xb0, 0xf9, 0xda, 0x04, 0xb3, 0x5d, 0x58, 0xbb, 0x14, - 0xf8, 0x37, 0xf9, 0xb3, 0xe8, 0x71, 0x24, 0xcc, 0x37, 0x60, 0x51, 0x75, 0x46, 0x06, 0xd4, 0x74, - 0x17, 0x12, 0x81, 0x4f, 0x34, 0x17, 0x97, 0x4f, 0x2f, 0x16, 0x79, 0xd4, 0x17, 0xd6, 0xfc, 0x6e, - 0x63, 0xaf, 0xe9, 0xae, 0xc6, 0xa5, 0xf9, 0x89, 0x2f, 0xec, 0xdf, 0x42, 0xbb, 0x02, 0x68, 0xae, - 0xc2, 0x7c, 0x81, 0x35, 0x4f, 0x7d, 0xf3, 0x3e, 0x6c, 0x95, 0x40, 0x75, 0x72, 0x4d, 0x11, 0x5b, - 0xee, 0x9d, 0x42, 0xa1, 0xc6, 0xaf, 0xc2, 0x7e, 0x0c, 0x9b, 0x27, 0x65, 0x2b, 0x17, 0xd4, 0x5d, - 0x3b, 0xa1, 0x51, 0x9f, 0xd1, 0xdb, 0xd0, 0x2a, 0x7e, 0x5f, 0xe8, 0xd3, 0x37, 0xdd, 0x52, 0x60, - 0x8f, 0x60, 0xfd, 0x52, 0xe0, 0x73, 0x12, 0xfa, 0x25, 0xd8, 0x94, 0x0b, 0x38, 0x9a, 0x04, 0x9a, - 0xf9, 0xfd, 0x5a, 0xba, 0x63, 0xb0, 0x75, 0x89, 0x02, 0xea, 0x23, 0xc9, 0xf8, 0x39, 0x91, 0xe9, - 0x58, 0x3d, 0x43, 0xf8, 0x8a, 0x48, 0x61, 0xba, 0xd0, 0x0c, 0xa8, 0x90, 0x59, 0x65, 0x7d, 0x30, - 0xb5, 0xb2, 0x92, 0x7d, 0x67, 0x1a, 0xc8, 0x31, 0x92, 0x28, 0xeb, 0x48, 0x8d, 0x65, 0xff, 0x14, - 0x36, 0x3e, 0x45, 0x32, 0xe6, 0xc4, 0xaf, 0xe5, 0x78, 0x1d, 0x1a, 0x2a, 0x7f, 0x86, 0xce, 0x9f, - 0x5a, 0xaa, 0x29, 0x6f, 0x3d, 0xf8, 0x22, 0x62, 0x5c, 0x12, 0xff, 0xda, 0x8d, 0xbc, 0xe2, 0x7a, - 0xaf, 0x60, 0x43, 0x5d, 0x96, 0x20, 0xa1, 0xef, 0x15, 0xe7, 0x4c, 0xf3, 0xd8, 0x3e, 0xf8, 0xe5, - 0x4c, 0xdd, 0x31, 0xe9, 0x2e, 0x3b, 0xc0, 0xed, 0x64, 0x42, 0x2e, 0xec, 0x3f, 0x19, 0x60, 0x9d, - 0x92, 0xf1, 0xa1, 0x10, 0x74, 0x10, 0x8e, 0x48, 0x28, 0x15, 0xb3, 0x21, 0x4c, 0xd4, 0xd2, 0x7c, - 0x0b, 0x56, 0x8a, 0x49, 0xaa, 0x07, 0xa8, 0xa1, 0x07, 0xe8, 0x72, 0x2e, 0x54, 0x0d, 0x66, 0xde, - 0x07, 0x88, 0x38, 0x49, 0x3c, 0xec, 0x5d, 0x91, 0x71, 0x96, 0xc5, 0xed, 0xea, 0x60, 0x4c, 0x7f, - 0xfd, 0x39, 0x67, 0x71, 0x3f, 0xa0, 0xf8, 0x94, 0x8c, 0xdd, 0x25, 0xa5, 0xdf, 0x3b, 0x25, 0x63, - 0xf5, 0xd2, 0x89, 0xd8, 0x73, 0xc2, 0xf5, 0x34, 0x6b, 0xb8, 0xe9, 0x87, 0xfd, 0x67, 0x03, 0xee, - 0x14, 0xe9, 0xc8, 0xcb, 0xf5, 0x2c, 0xee, 0x2b, 0x8b, 0x57, 0xdc, 0xdb, 0xb5, 0x68, 0xe7, 0x6f, - 0x88, 0xf6, 0x23, 0x58, 0x2e, 0x1a, 0x44, 0xc5, 0xdb, 0x98, 0x21, 0xde, 0x76, 0x6e, 0x71, 0x4a, - 0xc6, 0xf6, 0x1f, 0x2a, 0xb1, 0x1d, 0x8d, 0x2b, 0xdc, 0xc7, 0xff, 0x4b, 0x6c, 0x85, 0xdb, 0x6a, - 0x6c, 0xb8, 0x6a, 0x7f, 0xed, 0x00, 0x8d, 0xeb, 0x07, 0xb0, 0xff, 0x6a, 0xc0, 0x66, 0xd5, 0xab, - 0xb8, 0x60, 0x67, 0x3c, 0x0e, 0xc9, 0xab, 0xbc, 0x97, 0xed, 0x37, 0x5f, 0x6d, 0xbf, 0x27, 0xb0, - 0x5a, 0x0b, 0x4a, 0x64, 0xb7, 0xf1, 0xf3, 0x99, 0x6a, 0xac, 0xc2, 0xae, 0xee, 0x4a, 0xf5, 0x1c, - 0xe2, 0xe8, 0xc9, 0x37, 0x2f, 0x3a, 0xc6, 0xb7, 0x2f, 0x3a, 0xc6, 0xbf, 0x5e, 0x74, 0x8c, 0x2f, - 0x5f, 0x76, 0xe6, 0xbe, 0x7d, 0xd9, 0x99, 0xfb, 0xe7, 0xcb, 0xce, 0xdc, 0xef, 0x3e, 0x1c, 0x50, - 0x39, 0x8c, 0xfb, 0x0e, 0x66, 0xa3, 0x6e, 0xf6, 0xd3, 0xbe, 0xf4, 0xf5, 0x5e, 0xf1, 0xbf, 0x47, - 0xf2, 0x8b, 0xee, 0x17, 0xf5, 0x7f, 0x55, 0xe4, 0x38, 0x22, 0xa2, 0xbf, 0xa8, 0x59, 0xe1, 0xfd, - 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x9f, 0x08, 0x80, 0x3d, 0x86, 0x11, 0x00, 0x00, + // 1727 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xcd, 0x6f, 0x1b, 0xc7, + 0x15, 0xd7, 0x8a, 0x94, 0x2c, 0x3e, 0xea, 0xcb, 0x2b, 0x25, 0x5e, 0xa9, 0x2a, 0x45, 0x6f, 0x9a, + 0x54, 0x45, 0xe0, 0x65, 0xa5, 0x20, 0x40, 0x20, 0x34, 0x08, 0x24, 0xca, 0x89, 0x65, 0x35, 0xb1, + 0xb2, 0x52, 0x65, 0xb4, 0x3d, 0x2c, 0x86, 0xb3, 0x63, 0x72, 0xa0, 0xe5, 0xce, 0x7a, 0x66, 0x76, + 0x1d, 0x5e, 0x7a, 0xee, 0x31, 0xbd, 0x05, 0xbd, 0x34, 0xed, 0xdf, 0xd0, 0x4b, 0xef, 0x3d, 0x04, + 0x3d, 0xa5, 0xb7, 0x9e, 0xd2, 0xc2, 0x3e, 0xf6, 0x8f, 0x68, 0x31, 0xb3, 0x9f, 0xa4, 0x24, 0x87, + 0x86, 0xdb, 0xdb, 0xce, 0x9b, 0xf7, 0x7e, 0xef, 0xfb, 0xbd, 0x21, 0x61, 0x8f, 0x86, 0x92, 0x70, + 0x3c, 0x40, 0x34, 0xf4, 0x04, 0xc1, 0x31, 0xa7, 0x72, 0xd4, 0xc1, 0x38, 0xe9, 0x44, 0x9c, 0x25, + 0xd4, 0x27, 0xbc, 0x93, 0xec, 0x16, 0xdf, 0x4e, 0xc4, 0x99, 0x64, 0xe6, 0x5b, 0xd7, 0xc8, 0x38, + 0x18, 0x27, 0x4e, 0xc1, 0x97, 0xec, 0x6e, 0xbe, 0x7d, 0x13, 0x70, 0xb2, 0xdb, 0x79, 0x46, 0x39, + 0x49, 0xb1, 0x36, 0xd7, 0xfb, 0xac, 0xcf, 0xf4, 0x67, 0x47, 0x7d, 0x65, 0xd4, 0xed, 0x3e, 0x63, + 0xfd, 0x80, 0x74, 0xf4, 0xa9, 0x17, 0x3f, 0xe9, 0x48, 0x3a, 0x24, 0x42, 0xa2, 0x61, 0x94, 0x31, + 0xb4, 0x26, 0x19, 0xfc, 0x98, 0x23, 0x49, 0x59, 0x98, 0x03, 0xd0, 0x1e, 0xee, 0x60, 0xc6, 0x49, + 0x07, 0x07, 0x94, 0x84, 0x52, 0x69, 0x4d, 0xbf, 0x32, 0x86, 0x8e, 0x62, 0x08, 0x68, 0x7f, 0x20, + 0x53, 0xb2, 0xe8, 0x48, 0x12, 0xfa, 0x84, 0x0f, 0x69, 0xca, 0x5c, 0x9e, 0x32, 0x81, 0xad, 0xca, + 0x3d, 0xe6, 0xa3, 0x48, 0xb2, 0xce, 0x25, 0x19, 0x89, 0xec, 0xf6, 0x1d, 0xcc, 0xc4, 0x90, 0x89, + 0x0e, 0x51, 0xfe, 0x87, 0x98, 0x74, 0x92, 0xdd, 0x1e, 0x91, 0x68, 0xb7, 0x20, 0xe4, 0x76, 0x67, + 0x7c, 0x3d, 0x24, 0x4a, 0x1e, 0xcc, 0x68, 0x6e, 0xf7, 0x46, 0x7a, 0xef, 0xa5, 0x11, 0x49, 0x0f, + 0xe9, 0x95, 0xfd, 0x9f, 0x79, 0xb0, 0xba, 0x2c, 0x14, 0xf1, 0x90, 0xf0, 0x03, 0xdf, 0xa7, 0xca, + 0xdb, 0x53, 0xce, 0x22, 0x26, 0x50, 0x60, 0xae, 0xc3, 0x9c, 0xa4, 0x32, 0x20, 0x96, 0xd1, 0x36, + 0x76, 0x1a, 0x6e, 0x7a, 0x30, 0xdb, 0xd0, 0xf4, 0x89, 0xc0, 0x9c, 0x46, 0x8a, 0xd9, 0x9a, 0xd5, + 0x77, 0x55, 0x92, 0xb9, 0x01, 0x0b, 0x69, 0x8a, 0xa8, 0x6f, 0xd5, 0xf4, 0xf5, 0x2d, 0x7d, 0x3e, + 0xf6, 0xcd, 0x4f, 0x60, 0x99, 0x86, 0x54, 0x52, 0x14, 0x78, 0x03, 0xa2, 0x02, 0x65, 0xd5, 0xdb, + 0xc6, 0x4e, 0x73, 0x6f, 0xd3, 0xa1, 0x3d, 0xec, 0xa8, 0xd8, 0x3a, 0x59, 0x44, 0x93, 0x5d, 0xe7, + 0x81, 0xe6, 0x38, 0xac, 0x7f, 0xf3, 0xdd, 0xf6, 0x8c, 0xbb, 0x94, 0xc9, 0xa5, 0x44, 0xf3, 0x2e, + 0x2c, 0xf6, 0x49, 0x48, 0x04, 0x15, 0xde, 0x00, 0x89, 0x81, 0x35, 0xd7, 0x36, 0x76, 0x16, 0xdd, + 0x66, 0x46, 0x7b, 0x80, 0xc4, 0xc0, 0xdc, 0x86, 0x66, 0x8f, 0x86, 0x88, 0x8f, 0x52, 0x8e, 0x79, + 0xcd, 0x01, 0x29, 0x49, 0x33, 0x74, 0x01, 0x44, 0x84, 0x9e, 0x85, 0x9e, 0x2a, 0x04, 0xeb, 0x56, + 0x66, 0x48, 0x5a, 0x04, 0x4e, 0x5e, 0x04, 0xce, 0x79, 0x5e, 0x25, 0x87, 0x0b, 0xca, 0x90, 0x2f, + 0xff, 0xb9, 0x6d, 0xb8, 0x0d, 0x2d, 0xa7, 0x6e, 0xcc, 0xcf, 0x60, 0x35, 0x0e, 0x7b, 0x2c, 0xf4, + 0x69, 0xd8, 0xf7, 0x22, 0xc2, 0x29, 0xf3, 0xad, 0x05, 0x0d, 0xb5, 0x71, 0x05, 0xea, 0x28, 0xab, + 0xa7, 0x14, 0xe9, 0x2b, 0x85, 0xb4, 0x52, 0x08, 0x9f, 0x6a, 0x59, 0xf3, 0x73, 0x30, 0x31, 0x4e, + 0xb4, 0x49, 0x2c, 0x96, 0x39, 0x62, 0x63, 0x7a, 0xc4, 0x55, 0x8c, 0x93, 0xf3, 0x54, 0x3a, 0x83, + 0xfc, 0x35, 0xdc, 0x91, 0x1c, 0x85, 0xe2, 0x09, 0xe1, 0x93, 0xb8, 0x30, 0x3d, 0xee, 0x1b, 0x39, + 0xc6, 0x38, 0xf8, 0x03, 0x68, 0xe3, 0xac, 0x80, 0x3c, 0x4e, 0x7c, 0x2a, 0x24, 0xa7, 0xbd, 0x58, + 0xc9, 0x7a, 0x4f, 0x38, 0xc2, 0xba, 0x46, 0x9a, 0xba, 0x08, 0x5a, 0x39, 0x9f, 0x3b, 0xc6, 0xf6, + 0x71, 0xc6, 0x65, 0x3e, 0x82, 0x1f, 0xf5, 0x02, 0x86, 0x2f, 0x85, 0x32, 0xce, 0x1b, 0x43, 0xd2, + 0xaa, 0x87, 0x54, 0x08, 0x85, 0xb6, 0xd8, 0x36, 0x76, 0x6a, 0xee, 0xdd, 0x94, 0xf7, 0x94, 0xf0, + 0xa3, 0x0a, 0xe7, 0x79, 0x85, 0xd1, 0xbc, 0x07, 0xe6, 0x80, 0x0a, 0xc9, 0x38, 0xc5, 0x28, 0xf0, + 0x48, 0x28, 0x39, 0x25, 0xc2, 0x5a, 0xd2, 0xe2, 0xb7, 0xcb, 0x9b, 0xfb, 0xe9, 0x85, 0xf9, 0x10, + 0xee, 0xde, 0xa8, 0xd4, 0xc3, 0x03, 0x14, 0x86, 0x24, 0xb0, 0x96, 0xb5, 0x2b, 0xdb, 0xfe, 0x0d, + 0x3a, 0xbb, 0x29, 0xdb, 0xfe, 0xce, 0x6f, 0xbf, 0xde, 0x9e, 0xf9, 0xea, 0xeb, 0xed, 0x99, 0xbf, + 0xfd, 0xf9, 0xde, 0x66, 0xd6, 0x71, 0x7d, 0x96, 0x38, 0x59, 0x77, 0x3a, 0x5d, 0x16, 0x4a, 0x12, + 0x4a, 0xcb, 0xb0, 0xff, 0x6e, 0xc0, 0x9d, 0x6e, 0x11, 0x98, 0x21, 0x4b, 0x50, 0xf0, 0xff, 0x6c, + 0xc0, 0x03, 0x68, 0x08, 0xc9, 0xa2, 0xb4, 0xe4, 0xeb, 0xaf, 0x50, 0xf2, 0x0b, 0x4a, 0x4c, 0x5d, + 0xec, 0xb7, 0xbf, 0xd7, 0xa7, 0x3f, 0x18, 0xb0, 0x7e, 0xff, 0x69, 0x4c, 0x13, 0x86, 0xd1, 0xff, + 0x64, 0xa2, 0x9c, 0xc0, 0x12, 0xa9, 0xe0, 0x09, 0xab, 0xd6, 0xae, 0xed, 0x34, 0xf7, 0xde, 0x76, + 0x32, 0x33, 0x8a, 0x81, 0x98, 0xdb, 0x52, 0xd5, 0xee, 0x8e, 0xcb, 0xee, 0xcf, 0x5a, 0x86, 0xfd, + 0x57, 0x03, 0x36, 0x55, 0xae, 0xfa, 0xc4, 0x25, 0xcf, 0x10, 0xf7, 0x8f, 0x48, 0xc8, 0x86, 0xe2, + 0xb5, 0xed, 0xb4, 0x61, 0xc9, 0xd7, 0x48, 0x9e, 0x64, 0x1e, 0xf2, 0x7d, 0x6d, 0xa7, 0xe6, 0x51, + 0xc4, 0x73, 0x76, 0xe0, 0xfb, 0xe6, 0x0e, 0xac, 0x96, 0x3c, 0x5c, 0x65, 0x5c, 0x25, 0x42, 0xb1, + 0x2d, 0xe7, 0x6c, 0xba, 0x0e, 0xa6, 0x09, 0xf4, 0xbf, 0x0d, 0x58, 0xfd, 0x24, 0x60, 0x3d, 0x14, + 0x9c, 0x05, 0x48, 0x0c, 0x54, 0x25, 0x8f, 0x54, 0x8a, 0x39, 0xc9, 0x46, 0x88, 0x76, 0x60, 0xea, + 0x14, 0x2b, 0x31, 0x3d, 0xd4, 0x3e, 0x82, 0xdb, 0x45, 0x53, 0x17, 0x95, 0xa4, 0xfd, 0x3d, 0x5c, + 0x7b, 0xfe, 0xdd, 0xf6, 0x4a, 0x5e, 0xb0, 0x5d, 0x5d, 0x55, 0x47, 0xee, 0x0a, 0x1e, 0x23, 0xf8, + 0x66, 0x0b, 0x9a, 0xb4, 0x87, 0x3d, 0x41, 0x9e, 0x7a, 0x61, 0x3c, 0xd4, 0x45, 0x58, 0x77, 0x1b, + 0xb4, 0x87, 0xcf, 0xc8, 0xd3, 0xcf, 0xe2, 0xa1, 0xf9, 0x1e, 0xbc, 0x99, 0xef, 0x75, 0x2f, 0x41, + 0x81, 0xa7, 0xe4, 0x55, 0xc0, 0xb8, 0xae, 0xc9, 0x45, 0x77, 0x2d, 0xbf, 0xbd, 0x40, 0x81, 0x52, + 0x76, 0xe0, 0xfb, 0xdc, 0xfe, 0xcb, 0x1c, 0xcc, 0x9f, 0x22, 0x8e, 0x86, 0xc2, 0x3c, 0x87, 0x15, + 0x49, 0x86, 0x51, 0x80, 0x24, 0xf1, 0xd2, 0x85, 0x91, 0x79, 0xfa, 0xae, 0x5e, 0x24, 0xd5, 0x1d, + 0xec, 0x54, 0xb6, 0x6e, 0xb2, 0xeb, 0x74, 0x35, 0xf5, 0x4c, 0x22, 0x49, 0xdc, 0xe5, 0x1c, 0x23, + 0x25, 0x9a, 0x1f, 0x80, 0x25, 0x79, 0x2c, 0x64, 0x39, 0xca, 0xcb, 0x19, 0x96, 0x66, 0xfb, 0xcd, + 0xfc, 0x3e, 0x9d, 0x7e, 0xc5, 0xec, 0xba, 0x7e, 0x6a, 0xd7, 0x5e, 0x67, 0x6a, 0x9f, 0xc1, 0x9a, + 0x5a, 0x79, 0x93, 0x98, 0xf5, 0xe9, 0x31, 0x6f, 0x2b, 0xf9, 0x71, 0xd0, 0xcf, 0xc1, 0x4c, 0x04, + 0x9e, 0xc4, 0x9c, 0x7b, 0x05, 0x3b, 0x13, 0x81, 0xc7, 0x21, 0x7d, 0xd8, 0x12, 0xaa, 0xf8, 0xbc, + 0x21, 0x91, 0x7a, 0x07, 0x44, 0x01, 0x09, 0xa9, 0x18, 0xe4, 0xe0, 0xf3, 0xd3, 0x83, 0x6f, 0x68, + 0xa0, 0x4f, 0x15, 0x8e, 0x9b, 0xc3, 0x64, 0x5a, 0xba, 0xd0, 0xba, 0x5e, 0x4b, 0x91, 0xa0, 0x5b, + 0x3a, 0x41, 0x3f, 0xb8, 0x06, 0xa2, 0xc8, 0x92, 0x80, 0x77, 0x2a, 0xbb, 0x4a, 0xf5, 0xbd, 0xa7, + 0x5b, 0xce, 0xe3, 0xa4, 0xaf, 0x06, 0x3a, 0x4a, 0xd7, 0x16, 0x21, 0xc5, 0xbe, 0xcd, 0xba, 0x4f, + 0xbd, 0xac, 0x2a, 0xed, 0x47, 0xc3, 0xec, 0x51, 0x62, 0x97, 0x2b, 0xad, 0x98, 0x22, 0x6e, 0x05, + 0xeb, 0x63, 0x42, 0x1e, 0xd6, 0x17, 0x16, 0x56, 0x1b, 0xf6, 0x4f, 0xa0, 0xa1, 0x5b, 0xf4, 0x00, + 0x5f, 0x0a, 0x73, 0x0b, 0x1a, 0xaa, 0xd6, 0x89, 0x10, 0x44, 0x58, 0x86, 0xee, 0xfd, 0x92, 0x60, + 0x4b, 0xd8, 0xb8, 0xe9, 0x49, 0x26, 0xcc, 0xc7, 0x70, 0x2b, 0x22, 0xfa, 0xbd, 0xa0, 0x05, 0x9b, + 0x7b, 0x1f, 0x3a, 0x53, 0x3c, 0x9c, 0x9d, 0x9b, 0x00, 0xdd, 0x1c, 0xcd, 0xe6, 0xe5, 0x43, 0x70, + 0x62, 0x0d, 0x09, 0xf3, 0x62, 0x52, 0xe9, 0xcf, 0x5e, 0x49, 0xe9, 0x04, 0x5e, 0xa9, 0xf3, 0x5d, + 0x68, 0x1e, 0xa4, 0x6e, 0xff, 0x9c, 0x0a, 0x79, 0x35, 0x2c, 0x8b, 0xd5, 0xb0, 0x3c, 0x84, 0xe5, + 0x6c, 0xbb, 0x9e, 0x33, 0x3d, 0x66, 0xcc, 0x1f, 0x02, 0x64, 0x6b, 0x59, 0x8d, 0xa7, 0x74, 0x54, + 0x37, 0x32, 0xca, 0xb1, 0x3f, 0xb6, 0x05, 0x67, 0xc7, 0xb6, 0xa0, 0xed, 0xc2, 0xca, 0x85, 0xc0, + 0xbf, 0xc8, 0x9f, 0x5e, 0x8f, 0x22, 0x61, 0xbe, 0x01, 0xf3, 0xaa, 0x33, 0x32, 0xa0, 0xba, 0x3b, + 0x97, 0x08, 0x7c, 0xac, 0xa7, 0x75, 0xf9, 0xbc, 0x63, 0x91, 0x47, 0x7d, 0x61, 0xcd, 0xb6, 0x6b, + 0x3b, 0x75, 0x77, 0x39, 0x2e, 0xc5, 0x8f, 0x7d, 0x61, 0xff, 0x12, 0x9a, 0x15, 0x40, 0x73, 0x19, + 0x66, 0x0b, 0xac, 0x59, 0xea, 0x9b, 0xfb, 0xb0, 0x51, 0x02, 0x8d, 0x0f, 0xd7, 0x14, 0xb1, 0xe1, + 0xde, 0x29, 0x18, 0xc6, 0xe6, 0xab, 0xb0, 0x1f, 0xc1, 0xfa, 0x71, 0xd9, 0xca, 0xc5, 0xe8, 0x1e, + 0xf3, 0xd0, 0x18, 0xdf, 0xf3, 0x5b, 0xd0, 0x28, 0x7e, 0xde, 0x68, 0xef, 0xeb, 0x6e, 0x49, 0xb0, + 0x87, 0xb0, 0x7a, 0x21, 0xf0, 0x19, 0x09, 0xfd, 0x12, 0xec, 0x86, 0x00, 0x1c, 0x4e, 0x02, 0x4d, + 0xfd, 0x46, 0x2e, 0xd5, 0x31, 0xd8, 0xb8, 0x40, 0x01, 0xf5, 0x91, 0x64, 0xfc, 0x8c, 0xc8, 0x74, + 0xf1, 0x9e, 0x22, 0x7c, 0x49, 0xa4, 0x30, 0x5d, 0xa8, 0x07, 0x54, 0xc8, 0xac, 0xb2, 0x3e, 0xb8, + 0xb1, 0xb2, 0x92, 0x5d, 0xe7, 0x26, 0x90, 0x23, 0x24, 0x51, 0xd6, 0x91, 0x1a, 0xcb, 0xfe, 0x31, + 0xac, 0x7d, 0x8a, 0x64, 0xcc, 0x89, 0x3f, 0x96, 0xe3, 0x55, 0xa8, 0xa9, 0xfc, 0x19, 0x3a, 0x7f, + 0xea, 0xd3, 0xfe, 0x93, 0x01, 0xd6, 0xfd, 0x2f, 0x22, 0xc6, 0x25, 0xf1, 0xaf, 0x44, 0xe4, 0x25, + 0xe1, 0xbd, 0x84, 0x35, 0x15, 0x2c, 0x41, 0x42, 0xdf, 0x2b, 0xfc, 0x4c, 0xf3, 0xd8, 0xdc, 0x7b, + 0x7f, 0xaa, 0xee, 0x98, 0x54, 0x97, 0x39, 0x70, 0x3b, 0x99, 0xa0, 0x0b, 0xfb, 0x77, 0x06, 0x58, + 0x27, 0x64, 0x74, 0x20, 0x04, 0xed, 0x87, 0x43, 0x12, 0x4a, 0x35, 0xd9, 0x10, 0x26, 0xea, 0xd3, + 0x7c, 0x0b, 0x96, 0x8a, 0x4d, 0xaa, 0x17, 0xa8, 0xa1, 0x17, 0xe8, 0x62, 0x4e, 0x54, 0x0d, 0x66, + 0xee, 0x03, 0x44, 0x9c, 0x24, 0x1e, 0xf6, 0x2e, 0xc9, 0x28, 0xcb, 0xe2, 0x56, 0x75, 0x31, 0xa6, + 0x3f, 0x3e, 0x9d, 0xd3, 0xb8, 0x17, 0x50, 0x7c, 0x42, 0x46, 0xee, 0x82, 0xe2, 0xef, 0x9e, 0x90, + 0x91, 0x7a, 0x0b, 0x45, 0xec, 0x19, 0xe1, 0x7a, 0x9b, 0xd5, 0xdc, 0xf4, 0x60, 0xff, 0xde, 0x80, + 0x3b, 0x45, 0x3a, 0xf2, 0x72, 0x3d, 0x8d, 0x7b, 0x4a, 0xe2, 0x25, 0x71, 0xbb, 0x62, 0xed, 0xec, + 0x35, 0xd6, 0x7e, 0x04, 0x8b, 0x45, 0x83, 0x28, 0x7b, 0x6b, 0x53, 0xd8, 0xdb, 0xcc, 0x25, 0x4e, + 0xc8, 0xc8, 0xfe, 0x4d, 0xc5, 0xb6, 0xc3, 0x51, 0x65, 0xf6, 0xf1, 0xef, 0xb1, 0xad, 0x50, 0x5b, + 0xb5, 0x0d, 0x57, 0xe5, 0xaf, 0x38, 0x50, 0xbb, 0xea, 0x80, 0xfd, 0x47, 0x03, 0xd6, 0xab, 0x5a, + 0xc5, 0x39, 0x3b, 0xe5, 0x71, 0x48, 0x5e, 0xa6, 0xbd, 0x6c, 0xbf, 0xd9, 0x6a, 0xfb, 0x3d, 0x86, + 0xe5, 0x31, 0xa3, 0x44, 0x16, 0x8d, 0x9f, 0x4e, 0x55, 0x63, 0x95, 0xe9, 0xea, 0x2e, 0x55, 0xfd, + 0x10, 0x87, 0x8f, 0xbf, 0x79, 0xde, 0x32, 0xbe, 0x7d, 0xde, 0x32, 0xfe, 0xf5, 0xbc, 0x65, 0x7c, + 0xf9, 0xa2, 0x35, 0xf3, 0xed, 0x8b, 0xd6, 0xcc, 0x3f, 0x5e, 0xb4, 0x66, 0x7e, 0xf5, 0x61, 0x9f, + 0xca, 0x41, 0xdc, 0x73, 0x30, 0x1b, 0x66, 0x7f, 0x16, 0x74, 0x4a, 0x5d, 0xf7, 0x8a, 0xbf, 0x5d, + 0x92, 0xf7, 0x3b, 0x5f, 0x8c, 0xff, 0xa9, 0x23, 0x47, 0x11, 0x11, 0xbd, 0x79, 0x3d, 0x15, 0xde, + 0xfb, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf9, 0xed, 0x2b, 0xac, 0x05, 0x12, 0x00, 0x00, } func (m *ConsumerAdditionProposal) Marshal() (dAtA []byte, err error) { diff --git a/x/ccv/provider/types/query.pb.go b/x/ccv/provider/types/query.pb.go index 13f100c7ca..28e0b2b388 100644 --- a/x/ccv/provider/types/query.pb.go +++ b/x/ccv/provider/types/query.pb.go @@ -11,7 +11,7 @@ import ( grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" - types "github.com/cosmos/interchain-security/v4/x/ccv/types" + types "github.com/cosmos/interchain-security/v5/x/ccv/types" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -1187,94 +1187,94 @@ func init() { var fileDescriptor_422512d7b7586cd7 = []byte{ // 1403 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x4f, 0x73, 0x14, 0xc5, - 0x1b, 0xce, 0x24, 0x90, 0x5f, 0xd2, 0xe1, 0xdf, 0xaf, 0x89, 0x18, 0x86, 0xb8, 0x0b, 0x43, 0xa9, - 0x01, 0x74, 0x26, 0x59, 0xb4, 0xe4, 0x8f, 0x21, 0xec, 0x26, 0x80, 0x5b, 0x81, 0x22, 0x0e, 0x88, - 0x55, 0x6a, 0xb9, 0x74, 0x66, 0xda, 0xcd, 0x14, 0xb3, 0xd3, 0x43, 0x77, 0xef, 0xc2, 0x16, 0xe5, - 0x01, 0x0f, 0xca, 0x91, 0x2a, 0xf5, 0xce, 0xc5, 0x2f, 0xe0, 0xa7, 0xe0, 0x06, 0x16, 0x17, 0x4f, - 0x68, 0x05, 0x0f, 0x96, 0x27, 0xcb, 0xbb, 0x55, 0xd6, 0xf4, 0xf4, 0xcc, 0xee, 0xec, 0x4e, 0x76, - 0x67, 0x37, 0xb9, 0x65, 0xbb, 0xfb, 0x7d, 0xde, 0xe7, 0x79, 0xbb, 0xfb, 0xed, 0x67, 0x02, 0x0c, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x4f, 0x73, 0xd3, 0xc6, + 0x1b, 0x8e, 0x12, 0xc8, 0x2f, 0xd9, 0xf0, 0xef, 0xb7, 0xa4, 0x34, 0x88, 0xd4, 0x06, 0x31, 0x6d, + 0x03, 0xb4, 0x52, 0x62, 0x86, 0x29, 0x7f, 0x1a, 0x82, 0x9d, 0x00, 0xf5, 0x04, 0x86, 0x54, 0x50, + 0x3a, 0xd3, 0x76, 0x6a, 0x36, 0xd2, 0xd6, 0xd1, 0x20, 0x6b, 0xc5, 0xee, 0xda, 0xe0, 0x61, 0x7a, + 0xa0, 0x87, 0x96, 0x23, 0x33, 0x6d, 0xef, 0x5c, 0xfa, 0x05, 0xfa, 0x29, 0xb8, 0x41, 0x87, 0x4b, + 0x4f, 0xb4, 0x13, 0x7a, 0xe8, 0xf4, 0xd4, 0xe9, 0xbd, 0x33, 0x1d, 0xad, 0x56, 0xb2, 0x65, 0x2b, + 0xb6, 0xec, 0xe4, 0x16, 0xef, 0xee, 0xfb, 0xbc, 0xcf, 0xf3, 0xee, 0xee, 0xbb, 0x8f, 0x02, 0x0c, 0xc7, 0xe3, 0x98, 0x5a, 0x1b, 0xc8, 0xf1, 0x2a, 0x0c, 0x5b, 0x75, 0xea, 0xf0, 0xa6, 0x61, 0x59, - 0x0d, 0xc3, 0xa7, 0xa4, 0xe1, 0xd8, 0x98, 0x1a, 0x8d, 0x05, 0xe3, 0x6e, 0x1d, 0xd3, 0xa6, 0xee, + 0x0d, 0xc3, 0xa7, 0xa4, 0xe1, 0xd8, 0x98, 0x1a, 0x8d, 0x05, 0xe3, 0x5e, 0x1d, 0xd3, 0xa6, 0xee, 0x53, 0xc2, 0x09, 0x3c, 0x9e, 0x12, 0xa0, 0x5b, 0x56, 0x43, 0x8f, 0x02, 0xf4, 0xc6, 0x82, 0x3a, 0x5b, 0x25, 0xa4, 0xea, 0x62, 0x03, 0xf9, 0x8e, 0x81, 0x3c, 0x8f, 0x70, 0xc4, 0x1d, 0xe2, 0xb1, 0x10, 0x42, 0x9d, 0xae, 0x92, 0x2a, 0x11, 0x7f, 0x1a, 0xc1, 0x5f, 0x72, 0x34, 0x2f, 0x63, 0xc4, 0xaf, 0xf5, 0xfa, 0x57, 0x06, 0x77, 0x6a, 0x98, 0x71, 0x54, 0xf3, 0xe5, 0x82, 0x42, 0x16, 0xaa, 0x31, 0x8b, 0x30, 0x66, 0x7e, 0xab, 0x98, 0xc6, 0x82, 0xc1, 0x36, 0x10, 0xc5, 0x76, 0xc5, 0x22, - 0x1e, 0xab, 0xd7, 0xe2, 0x88, 0x37, 0x7b, 0x44, 0xdc, 0x73, 0x28, 0x96, 0xcb, 0x66, 0x39, 0xf6, - 0x6c, 0x4c, 0x6b, 0x8e, 0xc7, 0x0d, 0x8b, 0x36, 0x7d, 0x4e, 0x8c, 0x3b, 0xb8, 0x29, 0x15, 0x6a, - 0x67, 0xc0, 0x91, 0x8f, 0x83, 0x9a, 0x2d, 0x4b, 0xec, 0x2b, 0xd8, 0xc3, 0xcc, 0x61, 0x26, 0xbe, - 0x5b, 0xc7, 0x8c, 0xc3, 0xc3, 0x60, 0x22, 0x4c, 0xe0, 0xd8, 0x33, 0xca, 0x51, 0x65, 0x6e, 0xd2, - 0xfc, 0x9f, 0xf8, 0x5d, 0xb6, 0xb5, 0x07, 0x60, 0x36, 0x3d, 0x92, 0xf9, 0xc4, 0x63, 0x18, 0x7e, + 0x1e, 0xab, 0xd7, 0xe2, 0x88, 0xb7, 0x7b, 0x44, 0xdc, 0x77, 0x28, 0x96, 0xcb, 0x66, 0x39, 0xf6, + 0x6c, 0x4c, 0x6b, 0x8e, 0xc7, 0x0d, 0x8b, 0x36, 0x7d, 0x4e, 0x8c, 0xbb, 0xb8, 0x29, 0x15, 0x6a, + 0x67, 0xc1, 0x91, 0x8f, 0x83, 0x9a, 0x2d, 0x4b, 0xec, 0xab, 0xd8, 0xc3, 0xcc, 0x61, 0x26, 0xbe, + 0x57, 0xc7, 0x8c, 0xc3, 0xc3, 0x60, 0x22, 0x4c, 0xe0, 0xd8, 0x33, 0xca, 0x51, 0x65, 0x6e, 0xd2, + 0xfc, 0x9f, 0xf8, 0x5d, 0xb6, 0xb5, 0x87, 0x60, 0x36, 0x3d, 0x92, 0xf9, 0xc4, 0x63, 0x18, 0x7e, 0x0e, 0xf6, 0x56, 0xc3, 0xa1, 0x0a, 0xe3, 0x88, 0x63, 0x11, 0x3f, 0x55, 0x98, 0xd7, 0xb7, 0xda, - 0x96, 0xc6, 0x82, 0xde, 0x81, 0x75, 0x23, 0x88, 0x2b, 0xed, 0x7a, 0xfa, 0x32, 0x3f, 0x62, 0xee, + 0x96, 0xc6, 0x82, 0xde, 0x81, 0x75, 0x33, 0x88, 0x2b, 0xed, 0x7a, 0xf6, 0x2a, 0x3f, 0x62, 0xee, 0xa9, 0xb6, 0x8d, 0x69, 0xb3, 0x40, 0x4d, 0x24, 0x5f, 0x0e, 0xe0, 0x22, 0xd6, 0x1a, 0xea, 0x10, 0x15, 0xcd, 0x4a, 0x66, 0x25, 0x30, 0x2e, 0xd2, 0xb3, 0x19, 0xe5, 0xe8, 0xd8, 0xdc, 0x54, 0xe1, - 0xa4, 0x9e, 0xe1, 0xa4, 0xe8, 0x02, 0xc4, 0x94, 0x91, 0xda, 0x09, 0xf0, 0x76, 0x77, 0x8a, 0x1b, - 0x1c, 0x51, 0xbe, 0x46, 0x89, 0x4f, 0x18, 0x72, 0x63, 0x36, 0x8f, 0x14, 0x30, 0xd7, 0x7f, 0xad, - 0xe4, 0xf6, 0x05, 0x98, 0xf4, 0xa3, 0x41, 0x59, 0xb1, 0x0b, 0xd9, 0xe8, 0x49, 0xf0, 0xa2, 0x6d, - 0x3b, 0xc1, 0x11, 0x6e, 0x41, 0xb7, 0x00, 0xb5, 0x39, 0xf0, 0x56, 0x1a, 0x13, 0xe2, 0x77, 0x91, + 0xa4, 0x9e, 0xe1, 0xa4, 0xe8, 0x02, 0xc4, 0x94, 0x91, 0xda, 0x09, 0xf0, 0x6e, 0x77, 0x8a, 0x9b, + 0x1c, 0x51, 0xbe, 0x46, 0x89, 0x4f, 0x18, 0x72, 0x63, 0x36, 0x8f, 0x15, 0x30, 0xd7, 0x7f, 0xad, + 0xe4, 0xf6, 0x05, 0x98, 0xf4, 0xa3, 0x41, 0x59, 0xb1, 0x8b, 0xd9, 0xe8, 0x49, 0xf0, 0xa2, 0x6d, + 0x3b, 0xc1, 0x11, 0x6e, 0x41, 0xb7, 0x00, 0xb5, 0x39, 0xf0, 0x4e, 0x1a, 0x13, 0xe2, 0x77, 0x91, 0xfe, 0x56, 0x49, 0x17, 0x98, 0x58, 0x1a, 0xef, 0x74, 0x17, 0xe7, 0xc5, 0x81, 0x38, 0x9b, 0xb8, 0x46, 0x1a, 0xc8, 0x4d, 0xa5, 0xbc, 0x04, 0x76, 0x8b, 0xd4, 0x3d, 0x8e, 0x22, 0x3c, 0x02, 0x26, 0x2d, 0xd7, 0xc1, 0x1e, 0x0f, 0xe6, 0x46, 0xc5, 0xdc, 0x44, 0x38, 0x50, 0xb6, 0xb5, 0xef, 0x14, - 0x70, 0x4c, 0x28, 0xb9, 0x85, 0x5c, 0xc7, 0x46, 0x9c, 0xd0, 0xb6, 0x52, 0xd1, 0xfe, 0x07, 0x1d, - 0x2e, 0x82, 0x03, 0x11, 0xe9, 0x0a, 0xb2, 0x6d, 0x8a, 0x19, 0x0b, 0x93, 0x94, 0xe0, 0x3f, 0x2f, - 0xf3, 0xfb, 0x9a, 0xa8, 0xe6, 0x9e, 0xd3, 0xe4, 0x84, 0x66, 0xee, 0x8f, 0xd6, 0x16, 0xc3, 0x91, - 0x73, 0x13, 0x8f, 0x9e, 0xe4, 0x47, 0xfe, 0x7c, 0x92, 0x1f, 0xd1, 0xae, 0x03, 0xad, 0x17, 0x11, + 0x70, 0x4c, 0x28, 0xb9, 0x8d, 0x5c, 0xc7, 0x46, 0x9c, 0xd0, 0xb6, 0x52, 0xd1, 0xfe, 0x07, 0x1d, + 0x2e, 0x82, 0x03, 0x11, 0xe9, 0x0a, 0xb2, 0x6d, 0x8a, 0x19, 0x0b, 0x93, 0x94, 0xe0, 0x3f, 0xaf, + 0xf2, 0xfb, 0x9a, 0xa8, 0xe6, 0x9e, 0xd7, 0xe4, 0x84, 0x66, 0xee, 0x8f, 0xd6, 0x16, 0xc3, 0x91, + 0xf3, 0x13, 0x8f, 0x9f, 0xe6, 0x47, 0xfe, 0x7c, 0x9a, 0x1f, 0xd1, 0x6e, 0x00, 0xad, 0x17, 0x11, 0x59, 0xcd, 0x13, 0xe0, 0x40, 0x74, 0xd1, 0xe3, 0x74, 0x21, 0xa3, 0xfd, 0x56, 0xdb, 0xfa, 0x20, 0x59, 0xb7, 0xb4, 0xb5, 0xb6, 0xe4, 0xd9, 0xa4, 0x75, 0xe5, 0xea, 0x21, 0xad, 0x23, 0x7f, 0x2f, 0x69, 0x49, 0x22, 0x2d, 0x69, 0x5d, 0x95, 0x94, 0xd2, 0x3a, 0xaa, 0xa6, 0x1d, 0x01, 0x87, 0x05, - 0xe0, 0xcd, 0x0d, 0x4a, 0x38, 0x77, 0xb1, 0xb8, 0xf6, 0xd1, 0xe1, 0xfc, 0x45, 0x91, 0xd7, 0xbf, + 0xe0, 0xad, 0x0d, 0x4a, 0x38, 0x77, 0xb1, 0xb8, 0xf6, 0xd1, 0xe1, 0xfc, 0x45, 0x91, 0xd7, 0xbf, 0x63, 0x56, 0xa6, 0xc9, 0x83, 0x29, 0xe6, 0x22, 0xb6, 0x51, 0xa9, 0x61, 0x8e, 0xa9, 0xc8, 0x30, - 0x66, 0x02, 0x31, 0x74, 0x2d, 0x18, 0x81, 0x05, 0xf0, 0x5a, 0xdb, 0x82, 0x0a, 0x72, 0x5d, 0x72, - 0x0f, 0x79, 0x16, 0x16, 0xda, 0xc7, 0xcc, 0x83, 0xad, 0xa5, 0xc5, 0x68, 0x0a, 0x7e, 0x09, 0x66, - 0x3c, 0x7c, 0x9f, 0x57, 0x28, 0xf6, 0x5d, 0xec, 0x39, 0x6c, 0xa3, 0x62, 0x21, 0xcf, 0x0e, 0xc4, - 0xe2, 0x99, 0x31, 0x71, 0xe6, 0x55, 0x3d, 0x7c, 0x17, 0xf4, 0xe8, 0x5d, 0xd0, 0x6f, 0x46, 0xef, - 0x42, 0x69, 0x22, 0xe8, 0x61, 0x8f, 0x7f, 0xcb, 0x2b, 0xe6, 0xa1, 0x00, 0xc5, 0x8c, 0x40, 0x96, - 0x23, 0x0c, 0xed, 0x1d, 0x70, 0x52, 0x48, 0x32, 0x71, 0xd5, 0x61, 0x1c, 0x53, 0x6c, 0xb7, 0x6e, - 0xc7, 0x3d, 0x44, 0xed, 0x15, 0xec, 0x91, 0x5a, 0x7c, 0x3d, 0x2f, 0x81, 0x53, 0x99, 0x56, 0xcb, + 0x66, 0x02, 0x31, 0x74, 0x3d, 0x18, 0x81, 0x05, 0xf0, 0x46, 0xdb, 0x82, 0x0a, 0x72, 0x5d, 0x72, + 0x1f, 0x79, 0x16, 0x16, 0xda, 0xc7, 0xcc, 0x83, 0xad, 0xa5, 0xc5, 0x68, 0x0a, 0x7e, 0x09, 0x66, + 0x3c, 0xfc, 0x80, 0x57, 0x28, 0xf6, 0x5d, 0xec, 0x39, 0x6c, 0xa3, 0x62, 0x21, 0xcf, 0x0e, 0xc4, + 0xe2, 0x99, 0x31, 0x71, 0xe6, 0x55, 0x3d, 0x7c, 0x17, 0xf4, 0xe8, 0x5d, 0xd0, 0x6f, 0x45, 0xef, + 0x42, 0x69, 0x22, 0xe8, 0x61, 0x4f, 0x7e, 0xcb, 0x2b, 0xe6, 0xa1, 0x00, 0xc5, 0x8c, 0x40, 0x96, + 0x23, 0x0c, 0xed, 0x3d, 0x70, 0x52, 0x48, 0x32, 0x71, 0xd5, 0x61, 0x1c, 0x53, 0x6c, 0xb7, 0x6e, + 0xc7, 0x7d, 0x44, 0xed, 0x15, 0xec, 0x91, 0x5a, 0x7c, 0x3d, 0x2f, 0x83, 0x53, 0x99, 0x56, 0xcb, 0x8a, 0x1c, 0x02, 0xe3, 0xb6, 0x18, 0x11, 0x1d, 0x6f, 0xd2, 0x94, 0xbf, 0xb4, 0x9c, 0xec, 0xe1, - 0xe1, 0xcd, 0xc3, 0xb6, 0xb8, 0x69, 0xe5, 0x95, 0x38, 0xcd, 0x43, 0x05, 0xbc, 0xb1, 0xc5, 0x02, - 0x89, 0x7c, 0x1b, 0xec, 0xf3, 0xdb, 0xe7, 0xa2, 0x9e, 0x5a, 0xc8, 0xd4, 0x00, 0x12, 0xb0, 0xb2, + 0xe1, 0xcd, 0xc3, 0xb6, 0xb8, 0x69, 0xe5, 0x95, 0x38, 0xcd, 0x23, 0x05, 0xbc, 0xb5, 0xc5, 0x02, + 0x89, 0x7c, 0x07, 0xec, 0xf3, 0xdb, 0xe7, 0xa2, 0x9e, 0x5a, 0xc8, 0xd4, 0x00, 0x12, 0xb0, 0xb2, 0xd1, 0x77, 0xe0, 0x69, 0x65, 0xb0, 0x37, 0xb1, 0x0c, 0xce, 0x00, 0x79, 0x7e, 0x57, 0x92, 0xc7, 0x79, 0x05, 0xe6, 0x00, 0x88, 0x1a, 0x47, 0x79, 0x45, 0x6c, 0xe6, 0x2e, 0xb3, 0x6d, 0x44, 0xbb, - 0x0a, 0x0c, 0xa1, 0xa6, 0xe8, 0xba, 0x6b, 0xc8, 0xa1, 0xec, 0x16, 0x72, 0x97, 0x89, 0x17, 0x1c, + 0x06, 0x0c, 0xa1, 0xa6, 0xe8, 0xba, 0x6b, 0xc8, 0xa1, 0xec, 0x36, 0x72, 0x97, 0x89, 0x17, 0x1c, 0xb9, 0x52, 0xb2, 0xcf, 0x95, 0x57, 0x32, 0x3c, 0x80, 0x3f, 0x29, 0x60, 0x3e, 0x3b, 0x9c, 0xac, - 0xd7, 0x5d, 0xf0, 0x7f, 0x1f, 0x39, 0xb4, 0xd2, 0x40, 0x6e, 0xf0, 0x9e, 0x8b, 0x6b, 0x20, 0x4b, - 0x76, 0x39, 0x5b, 0xc9, 0x90, 0x43, 0x5b, 0x89, 0xe2, 0x6b, 0xe6, 0xb5, 0x0e, 0xc0, 0x3e, 0x3f, + 0xd7, 0x3d, 0xf0, 0x7f, 0x1f, 0x39, 0xb4, 0xd2, 0x40, 0x6e, 0xf0, 0x9e, 0x8b, 0x6b, 0x20, 0x4b, + 0x76, 0x25, 0x5b, 0xc9, 0x90, 0x43, 0x5b, 0x89, 0xe2, 0x6b, 0xe6, 0xb5, 0x0e, 0xc0, 0x3e, 0x3f, 0xb1, 0x44, 0xdb, 0x54, 0xc0, 0xb1, 0xbe, 0x51, 0xa9, 0x5d, 0x4e, 0xc9, 0xdc, 0xe5, 0xb6, 0xd9, - 0x49, 0xe0, 0x12, 0xd8, 0x13, 0x87, 0xdf, 0xc1, 0x4d, 0x79, 0xa3, 0x66, 0xf5, 0x96, 0x77, 0xd1, + 0x49, 0xe0, 0x12, 0xd8, 0x13, 0x87, 0xdf, 0xc5, 0x4d, 0x79, 0xa3, 0x66, 0xf5, 0x96, 0x77, 0xd1, 0x43, 0xef, 0xa2, 0xaf, 0xd5, 0xd7, 0x5d, 0xc7, 0x5a, 0xc5, 0x4d, 0x73, 0x2a, 0x8a, 0x58, 0xc5, - 0x4d, 0x6d, 0x1a, 0xc0, 0xf0, 0xa0, 0x22, 0x8a, 0x5a, 0xd7, 0xe4, 0x36, 0x38, 0x98, 0x18, 0x95, + 0x4d, 0x6d, 0x1a, 0xc0, 0xf0, 0xa0, 0x22, 0x8a, 0x5a, 0xd7, 0xe4, 0x0e, 0x38, 0x98, 0x18, 0x95, 0x9b, 0x50, 0x06, 0xe3, 0xbe, 0x18, 0x91, 0xaf, 0xd5, 0xa9, 0x8c, 0x95, 0x0f, 0x42, 0xe4, 0x29, - 0x95, 0x00, 0x85, 0x67, 0xd3, 0x60, 0xb7, 0x48, 0x01, 0x37, 0x15, 0x30, 0x9d, 0x66, 0x88, 0xe0, - 0xc5, 0x4c, 0xe8, 0x3d, 0x5c, 0x98, 0x5a, 0xdc, 0x06, 0x42, 0x28, 0x59, 0xbb, 0xf4, 0xcd, 0x8b, - 0x3f, 0xbe, 0x1f, 0x5d, 0x82, 0x8b, 0xfd, 0x6d, 0x74, 0xbc, 0x11, 0xd2, 0x71, 0x19, 0x0f, 0xa2, - 0x1b, 0xf0, 0x35, 0x7c, 0xa1, 0xc8, 0x8a, 0x26, 0xad, 0x15, 0x5c, 0x1a, 0x9c, 0x61, 0xc2, 0xb2, - 0xa9, 0x17, 0x87, 0x07, 0x90, 0x0a, 0xcf, 0x0a, 0x85, 0xa7, 0xe1, 0xc2, 0x00, 0x0a, 0x43, 0x33, - 0x07, 0x1f, 0x8e, 0x82, 0x99, 0x2d, 0x1c, 0x1a, 0x83, 0x57, 0x87, 0x64, 0x96, 0x6a, 0x06, 0xd5, - 0x6b, 0x3b, 0x84, 0x26, 0x45, 0x7f, 0x24, 0x44, 0x97, 0xe0, 0xc5, 0x41, 0x45, 0x07, 0x9e, 0x9c, - 0xf2, 0x4a, 0xec, 0xb3, 0xe0, 0xbf, 0x0a, 0x78, 0x3d, 0xdd, 0xf0, 0x31, 0xb8, 0x3a, 0x34, 0xe9, - 0x6e, 0x67, 0xa9, 0x5e, 0xdd, 0x19, 0x30, 0x59, 0x80, 0x2b, 0xa2, 0x00, 0x45, 0xb8, 0x34, 0x44, - 0x01, 0x88, 0xdf, 0xa6, 0xff, 0xef, 0xc8, 0x53, 0xa4, 0xba, 0x33, 0x78, 0x39, 0x3b, 0xeb, 0x5e, - 0x3e, 0x53, 0xbd, 0xb2, 0x6d, 0x1c, 0x29, 0xbc, 0x28, 0x84, 0x9f, 0x87, 0x67, 0x33, 0x7c, 0x17, + 0x95, 0x00, 0x85, 0xe7, 0xd3, 0x60, 0xb7, 0x48, 0x01, 0x37, 0x15, 0x30, 0x9d, 0x66, 0x88, 0xe0, + 0xa5, 0x4c, 0xe8, 0x3d, 0x5c, 0x98, 0x5a, 0xdc, 0x06, 0x42, 0x28, 0x59, 0xbb, 0xfc, 0xcd, 0xcb, + 0x3f, 0xbe, 0x1f, 0x5d, 0x82, 0x8b, 0xfd, 0x6d, 0x74, 0xbc, 0x11, 0xd2, 0x71, 0x19, 0x0f, 0xa3, + 0x1b, 0xf0, 0x35, 0x7c, 0xa9, 0xc8, 0x8a, 0x26, 0xad, 0x15, 0x5c, 0x1a, 0x9c, 0x61, 0xc2, 0xb2, + 0xa9, 0x97, 0x86, 0x07, 0x90, 0x0a, 0xcf, 0x09, 0x85, 0xa7, 0xe1, 0xc2, 0x00, 0x0a, 0x43, 0x33, + 0x07, 0x1f, 0x8d, 0x82, 0x99, 0x2d, 0x1c, 0x1a, 0x83, 0xd7, 0x86, 0x64, 0x96, 0x6a, 0x06, 0xd5, + 0xeb, 0x3b, 0x84, 0x26, 0x45, 0x7f, 0x24, 0x44, 0x97, 0xe0, 0xa5, 0x41, 0x45, 0x07, 0x9e, 0x9c, + 0xf2, 0x4a, 0xec, 0xb3, 0xe0, 0xbf, 0x0a, 0x78, 0x33, 0xdd, 0xf0, 0x31, 0xb8, 0x3a, 0x34, 0xe9, + 0x6e, 0x67, 0xa9, 0x5e, 0xdb, 0x19, 0x30, 0x59, 0x80, 0xab, 0xa2, 0x00, 0x45, 0xb8, 0x34, 0x44, + 0x01, 0x88, 0xdf, 0xa6, 0xff, 0xef, 0xc8, 0x53, 0xa4, 0xba, 0x33, 0x78, 0x25, 0x3b, 0xeb, 0x5e, + 0x3e, 0x53, 0xbd, 0xba, 0x6d, 0x1c, 0x29, 0xbc, 0x28, 0x84, 0x5f, 0x80, 0xe7, 0x32, 0x7c, 0x17, 0x47, 0x40, 0x95, 0x44, 0x8b, 0x4e, 0x91, 0xdc, 0xee, 0xda, 0x86, 0x92, 0x9c, 0xe2, 0x3f, 0x87, - 0x92, 0x9c, 0x66, 0x1f, 0x87, 0x93, 0x9c, 0x78, 0xd4, 0xe0, 0x33, 0x45, 0xbe, 0x13, 0x09, 0xe7, - 0x08, 0x2f, 0x64, 0xa7, 0x98, 0x66, 0x48, 0xd5, 0xa5, 0xa1, 0xe3, 0xa5, 0xb4, 0x33, 0x42, 0x5a, + 0x92, 0x9c, 0x66, 0x1f, 0x87, 0x93, 0x9c, 0x78, 0xd4, 0xe0, 0x73, 0x45, 0xbe, 0x13, 0x09, 0xe7, + 0x08, 0x2f, 0x66, 0xa7, 0x98, 0x66, 0x48, 0xd5, 0xa5, 0xa1, 0xe3, 0xa5, 0xb4, 0xb3, 0x42, 0x5a, 0x01, 0xce, 0xf7, 0x97, 0xc6, 0x25, 0x40, 0xf8, 0x55, 0x0d, 0x7f, 0x1c, 0x05, 0xc7, 0x33, 0x58, - 0x41, 0x78, 0x3d, 0x3b, 0xc5, 0x4c, 0x16, 0x54, 0x5d, 0xdb, 0x39, 0x40, 0x59, 0x84, 0x55, 0x51, - 0x84, 0x4b, 0x70, 0xb9, 0x7f, 0x11, 0x68, 0x8c, 0xd8, 0x3a, 0xd3, 0x54, 0x60, 0x56, 0x42, 0x6b, + 0x41, 0x78, 0x23, 0x3b, 0xc5, 0x4c, 0x16, 0x54, 0x5d, 0xdb, 0x39, 0x40, 0x59, 0x84, 0x55, 0x51, + 0x84, 0xcb, 0x70, 0xb9, 0x7f, 0x11, 0x68, 0x8c, 0xd8, 0x3a, 0xd3, 0x54, 0x60, 0x56, 0x42, 0x6b, 0x0b, 0xff, 0xea, 0xb2, 0xae, 0x49, 0x47, 0xc6, 0xe0, 0x00, 0xaf, 0xea, 0x16, 0xfe, 0x58, 0x2d, - 0x6d, 0x07, 0x42, 0xaa, 0x2e, 0x09, 0xd5, 0x1f, 0xc2, 0x73, 0xfd, 0x55, 0x47, 0xce, 0xb8, 0xd2, - 0xf9, 0x80, 0xfd, 0x30, 0x2a, 0xff, 0xc5, 0x90, 0xc1, 0x8a, 0xc2, 0x9b, 0xd9, 0x49, 0x67, 0x37, - 0xca, 0xea, 0x27, 0x3b, 0x8c, 0x2a, 0xab, 0x73, 0x5e, 0x54, 0xe7, 0x7d, 0x78, 0x7a, 0xe0, 0xfe, - 0xee, 0xd8, 0xf0, 0x67, 0x05, 0x4c, 0xb5, 0xf9, 0x3f, 0xf8, 0xc1, 0x00, 0xdb, 0xd5, 0xee, 0x23, - 0xd5, 0x33, 0x83, 0x07, 0x4a, 0xfe, 0xf3, 0x82, 0xff, 0x49, 0x38, 0x97, 0x61, 0x77, 0x43, 0x7f, - 0xf9, 0xe9, 0xd3, 0xcd, 0x9c, 0xf2, 0x7c, 0x33, 0xa7, 0xfc, 0xbe, 0x99, 0x53, 0x1e, 0xbf, 0xca, - 0x8d, 0x3c, 0x7f, 0x95, 0x1b, 0xf9, 0xf5, 0x55, 0x6e, 0xe4, 0xb3, 0xc5, 0xaa, 0xc3, 0x37, 0xea, - 0xeb, 0xba, 0x45, 0x6a, 0x86, 0x45, 0x58, 0x8d, 0xb0, 0x36, 0xd0, 0x77, 0x63, 0xd0, 0xc6, 0x7b, - 0xc6, 0xfd, 0x8e, 0x96, 0xd1, 0xf4, 0x31, 0x5b, 0x1f, 0x17, 0xdf, 0xa5, 0xa7, 0xff, 0x0b, 0x00, - 0x00, 0xff, 0xff, 0x67, 0x8a, 0xee, 0xb2, 0x49, 0x15, 0x00, 0x00, + 0x6d, 0x07, 0x42, 0xaa, 0x2e, 0x09, 0xd5, 0x1f, 0xc2, 0xf3, 0xfd, 0x55, 0x47, 0xce, 0xb8, 0xd2, + 0xf9, 0x80, 0xfd, 0x30, 0x2a, 0xff, 0xc5, 0x90, 0xc1, 0x8a, 0xc2, 0x5b, 0xd9, 0x49, 0x67, 0x37, + 0xca, 0xea, 0x27, 0x3b, 0x8c, 0x2a, 0xab, 0x73, 0x41, 0x54, 0xe7, 0x0c, 0x3c, 0x3d, 0x70, 0x7f, + 0x77, 0x6c, 0xf8, 0xb3, 0x02, 0xa6, 0xda, 0xfc, 0x1f, 0xfc, 0x60, 0x80, 0xed, 0x6a, 0xf7, 0x91, + 0xea, 0xd9, 0xc1, 0x03, 0x25, 0xff, 0x79, 0xc1, 0xff, 0x24, 0x9c, 0xcb, 0xb0, 0xbb, 0xa1, 0xbf, + 0xfc, 0xf4, 0xd9, 0x66, 0x4e, 0x79, 0xb1, 0x99, 0x53, 0x7e, 0xdf, 0xcc, 0x29, 0x4f, 0x5e, 0xe7, + 0x46, 0x5e, 0xbc, 0xce, 0x8d, 0xfc, 0xfa, 0x3a, 0x37, 0xf2, 0xd9, 0x62, 0xd5, 0xe1, 0x1b, 0xf5, + 0x75, 0xdd, 0x22, 0x35, 0xc3, 0x22, 0xac, 0x46, 0x58, 0x1b, 0xe8, 0xfb, 0x31, 0x68, 0xe3, 0x8c, + 0xf1, 0xa0, 0xa3, 0x65, 0x34, 0x7d, 0xcc, 0xd6, 0xc7, 0xc5, 0x77, 0xe9, 0xe9, 0xff, 0x02, 0x00, + 0x00, 0xff, 0xff, 0x6f, 0x69, 0x8e, 0x8e, 0x49, 0x15, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/ccv/provider/types/tx.pb.go b/x/ccv/provider/types/tx.pb.go index f72e95acb2..e0ddad16ba 100644 --- a/x/ccv/provider/types/tx.pb.go +++ b/x/ccv/provider/types/tx.pb.go @@ -9,22 +9,31 @@ import ( types "github.com/cometbft/cometbft/proto/tendermint/types" _ "github.com/cosmos/cosmos-proto" _ "github.com/cosmos/cosmos-sdk/codec/types" + _ "github.com/cosmos/cosmos-sdk/types/msgservice" + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" - _07_tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + types1 "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + _07_tendermint "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" + _ "google.golang.org/protobuf/types/known/durationpb" + _ "google.golang.org/protobuf/types/known/timestamppb" io "io" math "math" math_bits "math/bits" + time "time" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf +var _ = time.Kitchen // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. @@ -41,6 +50,8 @@ type MsgAssignConsumerKey struct { // in json string format corresponding to proto-any, ex: // `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is="}` ConsumerKey string `protobuf:"bytes,3,opt,name=consumer_key,json=consumerKey,proto3" json:"consumer_key,omitempty"` + // Tx signer address + Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgAssignConsumerKey) Reset() { *m = MsgAssignConsumerKey{} } @@ -270,6 +281,526 @@ func (m *MsgSubmitConsumerDoubleVotingResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgSubmitConsumerDoubleVotingResponse proto.InternalMessageInfo +// MsgUpdateParams is the Msg/UpdateParams request type +type MsgUpdateParams struct { + // signer is the address of the governance account. + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the x/provider parameters to update. + Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` +} + +func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } +func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParams) ProtoMessage() {} +func (*MsgUpdateParams) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{6} +} +func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParams.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParams.Merge(m, src) +} +func (m *MsgUpdateParams) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParams) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParams.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParams proto.InternalMessageInfo + +func (m *MsgUpdateParams) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +func (m *MsgUpdateParams) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +type MsgUpdateParamsResponse struct { +} + +func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse{} } +func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParamsResponse) ProtoMessage() {} +func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{7} +} +func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParamsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParamsResponse.Merge(m, src) +} +func (m *MsgUpdateParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo + +// MsgConsumerAddition defines the message used to spawn a new consumer chain using a v1 governance proposal. +// If it passes, then all validators on the provider chain are expected to validate +// the consumer chain at spawn time or get slashed. +// It is recommended that spawn time occurs after the proposal end time. +// +// Note: this replaces ConsumerAdditionProposal which is deprecated and will be removed soon +type MsgConsumerAddition struct { + // the proposed chain-id of the new consumer chain, must be different from all + // other consumer chain ids of the executing provider chain. + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // the proposed initial height of new consumer chain. + // For a completely new chain, this will be {0,1}. However, it may be + // different if this is a chain that is converting to a consumer chain. + InitialHeight types1.Height `protobuf:"bytes,2,opt,name=initial_height,json=initialHeight,proto3" json:"initial_height"` + // The hash of the consumer chain genesis state without the consumer CCV + // module genesis params. It is used for off-chain confirmation of + // genesis.json validity by validators and other parties. + GenesisHash []byte `protobuf:"bytes,3,opt,name=genesis_hash,json=genesisHash,proto3" json:"genesis_hash,omitempty"` + // The hash of the consumer chain binary that should be run by validators on + // chain initialization. It is used for off-chain confirmation of binary + // validity by validators and other parties. + BinaryHash []byte `protobuf:"bytes,4,opt,name=binary_hash,json=binaryHash,proto3" json:"binary_hash,omitempty"` + // spawn time is the time on the provider chain at which the consumer chain + // genesis is finalized and all validators will be responsible for starting + // their consumer chain validator node. + SpawnTime time.Time `protobuf:"bytes,5,opt,name=spawn_time,json=spawnTime,proto3,stdtime" json:"spawn_time"` + // Unbonding period for the consumer, + // which should be smaller than that of the provider in general. + UnbondingPeriod time.Duration `protobuf:"bytes,6,opt,name=unbonding_period,json=unbondingPeriod,proto3,stdduration" json:"unbonding_period"` + // Sent CCV related IBC packets will timeout after this duration + CcvTimeoutPeriod time.Duration `protobuf:"bytes,7,opt,name=ccv_timeout_period,json=ccvTimeoutPeriod,proto3,stdduration" json:"ccv_timeout_period"` + // Sent transfer related IBC packets will timeout after this duration + TransferTimeoutPeriod time.Duration `protobuf:"bytes,8,opt,name=transfer_timeout_period,json=transferTimeoutPeriod,proto3,stdduration" json:"transfer_timeout_period"` + // The fraction of tokens allocated to the consumer redistribution address + // during distribution events. The fraction is a string representing a + // decimal number. For example "0.75" would represent 75%. + ConsumerRedistributionFraction string `protobuf:"bytes,9,opt,name=consumer_redistribution_fraction,json=consumerRedistributionFraction,proto3" json:"consumer_redistribution_fraction,omitempty"` + // BlocksPerDistributionTransmission is the number of blocks between + // ibc-token-transfers from the consumer chain to the provider chain. On + // sending transmission event, `consumer_redistribution_fraction` of the + // accumulated tokens are sent to the consumer redistribution address. + BlocksPerDistributionTransmission int64 `protobuf:"varint,10,opt,name=blocks_per_distribution_transmission,json=blocksPerDistributionTransmission,proto3" json:"blocks_per_distribution_transmission,omitempty"` + // The number of historical info entries to persist in store. + // This param is a part of the cosmos sdk staking module. In the case of + // a ccv enabled consumer chain, the ccv module acts as the staking module. + HistoricalEntries int64 `protobuf:"varint,11,opt,name=historical_entries,json=historicalEntries,proto3" json:"historical_entries,omitempty"` + // The ID of a token transfer channel used for the Reward Distribution + // sub-protocol. If DistributionTransmissionChannel == "", a new transfer + // channel is created on top of the same connection as the CCV channel. + // Note that transfer_channel_id is the ID of the channel end on the consumer + // chain. it is most relevant for chains performing a sovereign to consumer + // changeover in order to maintan the existing ibc transfer channel + DistributionTransmissionChannel string `protobuf:"bytes,12,opt,name=distribution_transmission_channel,json=distributionTransmissionChannel,proto3" json:"distribution_transmission_channel,omitempty"` + // signer address + Authority string `protobuf:"bytes,13,opt,name=authority,proto3" json:"authority,omitempty"` +} + +func (m *MsgConsumerAddition) Reset() { *m = MsgConsumerAddition{} } +func (m *MsgConsumerAddition) String() string { return proto.CompactTextString(m) } +func (*MsgConsumerAddition) ProtoMessage() {} +func (*MsgConsumerAddition) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{8} +} +func (m *MsgConsumerAddition) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgConsumerAddition) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgConsumerAddition.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgConsumerAddition) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgConsumerAddition.Merge(m, src) +} +func (m *MsgConsumerAddition) XXX_Size() int { + return m.Size() +} +func (m *MsgConsumerAddition) XXX_DiscardUnknown() { + xxx_messageInfo_MsgConsumerAddition.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgConsumerAddition proto.InternalMessageInfo + +func (m *MsgConsumerAddition) GetChainId() string { + if m != nil { + return m.ChainId + } + return "" +} + +func (m *MsgConsumerAddition) GetInitialHeight() types1.Height { + if m != nil { + return m.InitialHeight + } + return types1.Height{} +} + +func (m *MsgConsumerAddition) GetGenesisHash() []byte { + if m != nil { + return m.GenesisHash + } + return nil +} + +func (m *MsgConsumerAddition) GetBinaryHash() []byte { + if m != nil { + return m.BinaryHash + } + return nil +} + +func (m *MsgConsumerAddition) GetSpawnTime() time.Time { + if m != nil { + return m.SpawnTime + } + return time.Time{} +} + +func (m *MsgConsumerAddition) GetUnbondingPeriod() time.Duration { + if m != nil { + return m.UnbondingPeriod + } + return 0 +} + +func (m *MsgConsumerAddition) GetCcvTimeoutPeriod() time.Duration { + if m != nil { + return m.CcvTimeoutPeriod + } + return 0 +} + +func (m *MsgConsumerAddition) GetTransferTimeoutPeriod() time.Duration { + if m != nil { + return m.TransferTimeoutPeriod + } + return 0 +} + +func (m *MsgConsumerAddition) GetConsumerRedistributionFraction() string { + if m != nil { + return m.ConsumerRedistributionFraction + } + return "" +} + +func (m *MsgConsumerAddition) GetBlocksPerDistributionTransmission() int64 { + if m != nil { + return m.BlocksPerDistributionTransmission + } + return 0 +} + +func (m *MsgConsumerAddition) GetHistoricalEntries() int64 { + if m != nil { + return m.HistoricalEntries + } + return 0 +} + +func (m *MsgConsumerAddition) GetDistributionTransmissionChannel() string { + if m != nil { + return m.DistributionTransmissionChannel + } + return "" +} + +func (m *MsgConsumerAddition) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +// MsgConsumerAdditionResponse defines response type for MsgConsumerAddition messages +type MsgConsumerAdditionResponse struct { +} + +func (m *MsgConsumerAdditionResponse) Reset() { *m = MsgConsumerAdditionResponse{} } +func (m *MsgConsumerAdditionResponse) String() string { return proto.CompactTextString(m) } +func (*MsgConsumerAdditionResponse) ProtoMessage() {} +func (*MsgConsumerAdditionResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{9} +} +func (m *MsgConsumerAdditionResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgConsumerAdditionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgConsumerAdditionResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgConsumerAdditionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgConsumerAdditionResponse.Merge(m, src) +} +func (m *MsgConsumerAdditionResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgConsumerAdditionResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgConsumerAdditionResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgConsumerAdditionResponse proto.InternalMessageInfo + +// MsgConsumerRemoval message contains a governance proposal on the provider chain to +// remove (and stop) a consumer chain. If it passes, all the consumer chain's +// state is removed from the provider chain. The outstanding unbonding operation +// funds are released. +// +// Note: this replaces ConsumerRemovalProposal which is deprecated and will be removed soon +type MsgConsumerRemoval struct { + // the chain-id of the consumer chain to be stopped + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // the time on the provider chain at which all validators are responsible to + // stop their consumer chain validator node + StopTime time.Time `protobuf:"bytes,2,opt,name=stop_time,json=stopTime,proto3,stdtime" json:"stop_time"` + // signer address + Authority string `protobuf:"bytes,3,opt,name=authority,proto3" json:"authority,omitempty"` +} + +func (m *MsgConsumerRemoval) Reset() { *m = MsgConsumerRemoval{} } +func (m *MsgConsumerRemoval) String() string { return proto.CompactTextString(m) } +func (*MsgConsumerRemoval) ProtoMessage() {} +func (*MsgConsumerRemoval) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{10} +} +func (m *MsgConsumerRemoval) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgConsumerRemoval) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgConsumerRemoval.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgConsumerRemoval) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgConsumerRemoval.Merge(m, src) +} +func (m *MsgConsumerRemoval) XXX_Size() int { + return m.Size() +} +func (m *MsgConsumerRemoval) XXX_DiscardUnknown() { + xxx_messageInfo_MsgConsumerRemoval.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgConsumerRemoval proto.InternalMessageInfo + +func (m *MsgConsumerRemoval) GetChainId() string { + if m != nil { + return m.ChainId + } + return "" +} + +func (m *MsgConsumerRemoval) GetStopTime() time.Time { + if m != nil { + return m.StopTime + } + return time.Time{} +} + +func (m *MsgConsumerRemoval) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +// MsgConsumerRemovalResponse defines response type for MsgConsumerRemoval messages +type MsgConsumerRemovalResponse struct { +} + +func (m *MsgConsumerRemovalResponse) Reset() { *m = MsgConsumerRemovalResponse{} } +func (m *MsgConsumerRemovalResponse) String() string { return proto.CompactTextString(m) } +func (*MsgConsumerRemovalResponse) ProtoMessage() {} +func (*MsgConsumerRemovalResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{11} +} +func (m *MsgConsumerRemovalResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgConsumerRemovalResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgConsumerRemovalResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgConsumerRemovalResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgConsumerRemovalResponse.Merge(m, src) +} +func (m *MsgConsumerRemovalResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgConsumerRemovalResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgConsumerRemovalResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgConsumerRemovalResponse proto.InternalMessageInfo + +// ChangeRewardDenomsProposal is a governance proposal on the provider chain to +// mutate the set of denoms accepted by the provider as rewards. +// +// Note: this replaces ChangeRewardDenomsProposal which is deprecated and will be removed soon +type MsgChangeRewardDenoms struct { + // the list of consumer reward denoms to add + DenomsToAdd []string `protobuf:"bytes,1,rep,name=denoms_to_add,json=denomsToAdd,proto3" json:"denoms_to_add,omitempty"` + // the list of consumer reward denoms to remove + DenomsToRemove []string `protobuf:"bytes,2,rep,name=denoms_to_remove,json=denomsToRemove,proto3" json:"denoms_to_remove,omitempty"` + // signer address + Authority string `protobuf:"bytes,3,opt,name=authority,proto3" json:"authority,omitempty"` +} + +func (m *MsgChangeRewardDenoms) Reset() { *m = MsgChangeRewardDenoms{} } +func (m *MsgChangeRewardDenoms) String() string { return proto.CompactTextString(m) } +func (*MsgChangeRewardDenoms) ProtoMessage() {} +func (*MsgChangeRewardDenoms) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{12} +} +func (m *MsgChangeRewardDenoms) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChangeRewardDenoms) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChangeRewardDenoms.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgChangeRewardDenoms) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChangeRewardDenoms.Merge(m, src) +} +func (m *MsgChangeRewardDenoms) XXX_Size() int { + return m.Size() +} +func (m *MsgChangeRewardDenoms) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChangeRewardDenoms.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgChangeRewardDenoms proto.InternalMessageInfo + +func (m *MsgChangeRewardDenoms) GetDenomsToAdd() []string { + if m != nil { + return m.DenomsToAdd + } + return nil +} + +func (m *MsgChangeRewardDenoms) GetDenomsToRemove() []string { + if m != nil { + return m.DenomsToRemove + } + return nil +} + +func (m *MsgChangeRewardDenoms) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +// MsgChangeRewardDenomsResponse defines response type for MsgChangeRewardDenoms messages +type MsgChangeRewardDenomsResponse struct { +} + +func (m *MsgChangeRewardDenomsResponse) Reset() { *m = MsgChangeRewardDenomsResponse{} } +func (m *MsgChangeRewardDenomsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgChangeRewardDenomsResponse) ProtoMessage() {} +func (*MsgChangeRewardDenomsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{13} +} +func (m *MsgChangeRewardDenomsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgChangeRewardDenomsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgChangeRewardDenomsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgChangeRewardDenomsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgChangeRewardDenomsResponse.Merge(m, src) +} +func (m *MsgChangeRewardDenomsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgChangeRewardDenomsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgChangeRewardDenomsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgChangeRewardDenomsResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgAssignConsumerKey)(nil), "interchain_security.ccv.provider.v1.MsgAssignConsumerKey") proto.RegisterType((*MsgAssignConsumerKeyResponse)(nil), "interchain_security.ccv.provider.v1.MsgAssignConsumerKeyResponse") @@ -277,6 +808,14 @@ func init() { proto.RegisterType((*MsgSubmitConsumerMisbehaviourResponse)(nil), "interchain_security.ccv.provider.v1.MsgSubmitConsumerMisbehaviourResponse") proto.RegisterType((*MsgSubmitConsumerDoubleVoting)(nil), "interchain_security.ccv.provider.v1.MsgSubmitConsumerDoubleVoting") proto.RegisterType((*MsgSubmitConsumerDoubleVotingResponse)(nil), "interchain_security.ccv.provider.v1.MsgSubmitConsumerDoubleVotingResponse") + proto.RegisterType((*MsgUpdateParams)(nil), "interchain_security.ccv.provider.v1.MsgUpdateParams") + proto.RegisterType((*MsgUpdateParamsResponse)(nil), "interchain_security.ccv.provider.v1.MsgUpdateParamsResponse") + proto.RegisterType((*MsgConsumerAddition)(nil), "interchain_security.ccv.provider.v1.MsgConsumerAddition") + proto.RegisterType((*MsgConsumerAdditionResponse)(nil), "interchain_security.ccv.provider.v1.MsgConsumerAdditionResponse") + proto.RegisterType((*MsgConsumerRemoval)(nil), "interchain_security.ccv.provider.v1.MsgConsumerRemoval") + proto.RegisterType((*MsgConsumerRemovalResponse)(nil), "interchain_security.ccv.provider.v1.MsgConsumerRemovalResponse") + proto.RegisterType((*MsgChangeRewardDenoms)(nil), "interchain_security.ccv.provider.v1.MsgChangeRewardDenoms") + proto.RegisterType((*MsgChangeRewardDenomsResponse)(nil), "interchain_security.ccv.provider.v1.MsgChangeRewardDenomsResponse") } func init() { @@ -284,46 +823,89 @@ func init() { } var fileDescriptor_43221a4391e9fbf4 = []byte{ - // 610 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0xcf, 0x4f, 0xd4, 0x4e, - 0x14, 0xdf, 0x42, 0xf2, 0xfd, 0xc2, 0x80, 0x26, 0x36, 0x10, 0x60, 0x83, 0x5d, 0x5d, 0xa3, 0x78, - 0xc0, 0x99, 0x80, 0x26, 0x46, 0x12, 0x0f, 0xac, 0x98, 0xf8, 0x23, 0x9b, 0x98, 0x9a, 0x60, 0xe2, - 0xc1, 0xa6, 0x9d, 0x3e, 0xba, 0x13, 0xda, 0x99, 0xcd, 0xcc, 0xb4, 0xa1, 0xff, 0x01, 0x47, 0x3d, - 0x19, 0x6f, 0xfc, 0x01, 0xfe, 0x21, 0x1e, 0x39, 0x7a, 0x32, 0x06, 0x2e, 0x9e, 0xbd, 0x78, 0x35, - 0x3b, 0x6d, 0xd9, 0x12, 0x2b, 0x10, 0xbc, 0xf5, 0xbd, 0xf7, 0x79, 0xef, 0x7d, 0x3e, 0x6f, 0x5e, - 0x1f, 0x5a, 0x65, 0x5c, 0x83, 0xa4, 0x03, 0x9f, 0x71, 0x4f, 0x01, 0x4d, 0x25, 0xd3, 0x39, 0xa1, - 0x34, 0x23, 0x43, 0x29, 0x32, 0x16, 0x82, 0x24, 0xd9, 0x1a, 0xd1, 0x7b, 0x78, 0x28, 0x85, 0x16, - 0xf6, 0xad, 0x06, 0x34, 0xa6, 0x34, 0xc3, 0x15, 0x1a, 0x67, 0x6b, 0xed, 0xb9, 0x48, 0x44, 0xc2, - 0xe0, 0xc9, 0xe8, 0xab, 0x48, 0x6d, 0x2f, 0x51, 0xa1, 0x12, 0xa1, 0xbc, 0x22, 0x50, 0x18, 0x55, - 0x28, 0x12, 0x22, 0x8a, 0x81, 0x18, 0x2b, 0x48, 0x77, 0x88, 0xcf, 0xf3, 0x32, 0x44, 0x58, 0x40, - 0x49, 0xcc, 0xa2, 0x81, 0xa6, 0x31, 0x03, 0xae, 0x15, 0xd1, 0xc0, 0x43, 0x90, 0x09, 0xe3, 0xda, - 0x30, 0x3b, 0xb1, 0xca, 0x84, 0x4e, 0x2d, 0xae, 0xf3, 0x21, 0x28, 0x02, 0x23, 0x62, 0x9c, 0x42, - 0x01, 0xe8, 0x7e, 0xb4, 0xd0, 0x5c, 0x5f, 0x45, 0x9b, 0x4a, 0xb1, 0x88, 0x3f, 0x11, 0x5c, 0xa5, - 0x09, 0xc8, 0x97, 0x90, 0xdb, 0x4b, 0x68, 0xaa, 0x10, 0xc6, 0xc2, 0x45, 0xeb, 0x86, 0x75, 0x77, - 0xda, 0xfd, 0xdf, 0xd8, 0xcf, 0x43, 0xfb, 0x21, 0xba, 0x52, 0x09, 0xf4, 0xfc, 0x30, 0x94, 0x8b, - 0x13, 0xa3, 0x78, 0xcf, 0xfe, 0xf9, 0xad, 0x73, 0x35, 0xf7, 0x93, 0x78, 0xa3, 0x3b, 0xf2, 0x82, - 0x52, 0x5d, 0x77, 0xb6, 0x02, 0x6e, 0x86, 0xa1, 0xb4, 0x6f, 0xa2, 0x59, 0x5a, 0xb6, 0xf0, 0x76, - 0x21, 0x5f, 0x9c, 0x34, 0x75, 0x67, 0xe8, 0xb8, 0xed, 0xc6, 0xd4, 0xfe, 0x41, 0xa7, 0xf5, 0xe3, - 0xa0, 0xd3, 0xea, 0x3a, 0x68, 0xb9, 0x89, 0x98, 0x0b, 0x6a, 0x28, 0xb8, 0x82, 0xee, 0x27, 0x0b, - 0x5d, 0xef, 0xab, 0xe8, 0x75, 0x1a, 0x24, 0x4c, 0x57, 0x80, 0x3e, 0x53, 0x01, 0x0c, 0xfc, 0x8c, - 0x89, 0x54, 0xda, 0xcb, 0x68, 0x5a, 0x99, 0xa8, 0x06, 0x59, 0x6a, 0x18, 0x3b, 0xec, 0x57, 0x68, - 0x36, 0xa9, 0xa1, 0x8d, 0x88, 0x99, 0xf5, 0x55, 0xcc, 0x02, 0x8a, 0xeb, 0x23, 0xc6, 0xb5, 0xa1, - 0x66, 0x6b, 0xb8, 0xde, 0xc1, 0x3d, 0x55, 0xa1, 0xc6, 0x7d, 0x05, 0xdd, 0x3e, 0x93, 0xda, 0x89, - 0x88, 0xfd, 0x89, 0x06, 0x11, 0x5b, 0x22, 0x0d, 0x62, 0xd8, 0x16, 0x9a, 0xf1, 0xe8, 0x1c, 0x11, - 0x1e, 0x5a, 0x08, 0xd3, 0x61, 0xcc, 0xa8, 0xaf, 0xc1, 0xcb, 0x84, 0x06, 0xaf, 0x7a, 0xdf, 0x52, - 0xcf, 0x4a, 0x9d, 0xbe, 0xd9, 0x00, 0xbc, 0x55, 0x25, 0x6c, 0x0b, 0x0d, 0x4f, 0x4b, 0xb8, 0x3b, - 0x1f, 0x36, 0xb9, 0xed, 0x77, 0x68, 0x81, 0xf1, 0x1d, 0xe9, 0x53, 0xcd, 0x04, 0xf7, 0x82, 0x58, - 0xd0, 0x5d, 0x6f, 0x00, 0x7e, 0x08, 0xd2, 0xbc, 0xde, 0xcc, 0xfa, 0x9d, 0xf3, 0x06, 0xf6, 0xcc, - 0xa0, 0xdd, 0xf9, 0x71, 0x99, 0xde, 0xa8, 0x4a, 0xe1, 0x3e, 0x67, 0x66, 0xf5, 0x49, 0x54, 0x33, - 0x5b, 0xff, 0x35, 0x89, 0x26, 0xfb, 0x2a, 0xb2, 0x3f, 0x58, 0xe8, 0xda, 0x9f, 0x7b, 0xfb, 0x08, - 0x5f, 0xe0, 0xa7, 0xc4, 0x4d, 0x9b, 0xd5, 0xde, 0xbc, 0x74, 0x6a, 0xc5, 0xcd, 0xfe, 0x6c, 0xa1, - 0xf6, 0x19, 0x1b, 0xd9, 0xbb, 0x68, 0x87, 0xbf, 0xd7, 0x68, 0xbf, 0xf8, 0xf7, 0x1a, 0x67, 0xd0, - 0x3d, 0xb5, 0x7b, 0x97, 0xa4, 0x5b, 0xaf, 0x71, 0x59, 0xba, 0x4d, 0x2f, 0xdf, 0x7b, 0xf3, 0xe5, - 0xc8, 0xb1, 0x0e, 0x8f, 0x1c, 0xeb, 0xfb, 0x91, 0x63, 0xbd, 0x3f, 0x76, 0x5a, 0x87, 0xc7, 0x4e, - 0xeb, 0xeb, 0xb1, 0xd3, 0x7a, 0xfb, 0x38, 0x62, 0x7a, 0x90, 0x06, 0x98, 0x8a, 0xa4, 0x3c, 0xa6, - 0x64, 0xdc, 0xf6, 0xde, 0xc9, 0x25, 0xcf, 0x1e, 0x90, 0xbd, 0xd3, 0xe7, 0xdc, 0xfc, 0x12, 0xc1, - 0x7f, 0xe6, 0x18, 0xde, 0xff, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x74, 0xf3, 0x13, 0x1f, 0xff, 0x05, - 0x00, 0x00, + // 1305 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcf, 0x8f, 0x14, 0xc5, + 0x17, 0xdf, 0x66, 0x61, 0xd9, 0xad, 0xfd, 0xc1, 0xd2, 0xb0, 0xdf, 0x9d, 0x9d, 0x2f, 0xcc, 0x2c, + 0xe3, 0x0f, 0x08, 0x42, 0xb7, 0xac, 0x3f, 0xd0, 0x8d, 0x46, 0x67, 0x59, 0x14, 0x30, 0xab, 0x6b, + 0xb3, 0x62, 0xa2, 0x89, 0x9d, 0x9a, 0xee, 0xa2, 0xbb, 0xc2, 0x74, 0xd5, 0xa4, 0xaa, 0xba, 0x61, + 0x6e, 0x86, 0x93, 0x89, 0x89, 0xc1, 0x9b, 0x47, 0x62, 0x3c, 0x6a, 0xc2, 0xc1, 0x93, 0x37, 0x6f, + 0x1c, 0x89, 0xf1, 0xe0, 0x09, 0x09, 0x1c, 0xf0, 0xec, 0x5f, 0x60, 0xea, 0x47, 0xf7, 0xf4, 0xec, + 0x0e, 0xcb, 0x30, 0x7a, 0x99, 0x74, 0xd7, 0xfb, 0xbc, 0xcf, 0xfb, 0xbc, 0xd7, 0xf5, 0x5e, 0xd5, + 0x80, 0x53, 0x98, 0x08, 0xc4, 0x82, 0x18, 0x62, 0xe2, 0x73, 0x14, 0xa4, 0x0c, 0x8b, 0xae, 0x1b, + 0x04, 0x99, 0xdb, 0x61, 0x34, 0xc3, 0x21, 0x62, 0x6e, 0x76, 0xc6, 0x15, 0x37, 0x9c, 0x0e, 0xa3, + 0x82, 0xda, 0xcf, 0x0d, 0x40, 0x3b, 0x41, 0x90, 0x39, 0x39, 0xda, 0xc9, 0xce, 0x54, 0x0f, 0xc2, + 0x04, 0x13, 0xea, 0xaa, 0x5f, 0xed, 0x57, 0x3d, 0x12, 0x51, 0x1a, 0xb5, 0x91, 0x0b, 0x3b, 0xd8, + 0x85, 0x84, 0x50, 0x01, 0x05, 0xa6, 0x84, 0x1b, 0x6b, 0xdd, 0x58, 0xd5, 0x5b, 0x2b, 0xbd, 0xea, + 0x0a, 0x9c, 0x20, 0x2e, 0x60, 0xd2, 0x31, 0x80, 0xda, 0x76, 0x40, 0x98, 0x32, 0xc5, 0x60, 0xec, + 0x4b, 0xdb, 0xed, 0x90, 0x74, 0x8d, 0xe9, 0x70, 0x44, 0x23, 0xaa, 0x1e, 0x5d, 0xf9, 0x94, 0x3b, + 0x04, 0x94, 0x27, 0x94, 0xfb, 0xda, 0xa0, 0x5f, 0x8c, 0x69, 0x51, 0xbf, 0xb9, 0x09, 0x8f, 0x64, + 0xea, 0x09, 0x8f, 0x72, 0x95, 0xb8, 0x15, 0xb8, 0x01, 0x65, 0xc8, 0x0d, 0xda, 0x18, 0x11, 0x21, + 0xad, 0xfa, 0xc9, 0x00, 0x56, 0x86, 0x29, 0x65, 0x51, 0x28, 0xed, 0xe3, 0x4a, 0xd2, 0x36, 0x8e, + 0x62, 0xa1, 0xa9, 0xb8, 0x2b, 0x10, 0x09, 0x11, 0x4b, 0xb0, 0x0e, 0xd0, 0x7b, 0xcb, 0x55, 0x94, + 0xec, 0xa2, 0xdb, 0x41, 0xdc, 0x45, 0x92, 0x8f, 0x04, 0x48, 0x03, 0x1a, 0xbf, 0x5b, 0xe0, 0xf0, + 0x06, 0x8f, 0x9a, 0x9c, 0xe3, 0x88, 0x9c, 0xa3, 0x84, 0xa7, 0x09, 0x62, 0x1f, 0xa0, 0xae, 0xbd, + 0x04, 0x26, 0xb5, 0x36, 0x1c, 0x56, 0xac, 0x65, 0xeb, 0xc4, 0x94, 0xb7, 0x5f, 0xbd, 0x5f, 0x0c, + 0xed, 0xb3, 0x60, 0x36, 0xd7, 0xe5, 0xc3, 0x30, 0x64, 0x95, 0x3d, 0xd2, 0xbe, 0x66, 0xff, 0x7d, + 0xbf, 0x3e, 0xd7, 0x85, 0x49, 0x7b, 0xb5, 0x21, 0x57, 0x11, 0xe7, 0x0d, 0x6f, 0x26, 0x07, 0x36, + 0xc3, 0x90, 0xd9, 0xc7, 0xc0, 0x4c, 0x60, 0x42, 0xf8, 0xd7, 0x50, 0xb7, 0x32, 0xae, 0x78, 0xa7, + 0x83, 0x52, 0xd8, 0x97, 0xc1, 0x84, 0x54, 0x82, 0x58, 0x65, 0xaf, 0x22, 0xad, 0xfc, 0xf6, 0xf3, + 0xe9, 0xc3, 0xa6, 0xe2, 0x4d, 0xcd, 0x7a, 0x59, 0x30, 0x4c, 0x22, 0xcf, 0xe0, 0x56, 0x0f, 0x7d, + 0x75, 0xbb, 0x3e, 0xf6, 0xd7, 0xed, 0xfa, 0xd8, 0xcd, 0xc7, 0x77, 0x4e, 0x9a, 0xc5, 0x46, 0x0d, + 0x1c, 0x19, 0x94, 0x95, 0x87, 0x78, 0x87, 0x12, 0x8e, 0x1a, 0xbf, 0x5a, 0xe0, 0xe8, 0x06, 0x8f, + 0x2e, 0xa7, 0xad, 0x04, 0x8b, 0x1c, 0xb0, 0x81, 0x79, 0x0b, 0xc5, 0x30, 0xc3, 0x34, 0x65, 0xf6, + 0xeb, 0x60, 0x8a, 0x2b, 0xab, 0x40, 0x4c, 0x17, 0x60, 0x17, 0x2d, 0x3d, 0xa8, 0xbd, 0x09, 0x66, + 0x92, 0x12, 0x8f, 0xaa, 0xcd, 0xf4, 0xca, 0x29, 0x07, 0xb7, 0x02, 0xa7, 0xfc, 0xe5, 0x9c, 0xd2, + 0xb7, 0xca, 0xce, 0x38, 0xe5, 0xd8, 0x5e, 0x1f, 0xc3, 0xea, 0xff, 0xca, 0x09, 0xf6, 0x22, 0x35, + 0x8e, 0x83, 0x17, 0x76, 0x4d, 0xa1, 0x48, 0xf6, 0xce, 0x9e, 0x01, 0xc9, 0xae, 0xd3, 0xb4, 0xd5, + 0x46, 0x57, 0xa8, 0xc0, 0x24, 0x1a, 0x39, 0x59, 0x1f, 0x2c, 0x86, 0x69, 0xa7, 0x8d, 0x03, 0x28, + 0x90, 0x9f, 0x51, 0x81, 0xfc, 0x7c, 0x7b, 0x99, 0xbc, 0x8f, 0x97, 0xd3, 0x54, 0x1b, 0xd0, 0x59, + 0xcf, 0x1d, 0xae, 0x50, 0x81, 0xce, 0x1b, 0xb8, 0xb7, 0x10, 0x0e, 0x5a, 0xb6, 0xbf, 0x00, 0x8b, + 0x98, 0x5c, 0x65, 0x30, 0x90, 0xed, 0xeb, 0xb7, 0xda, 0x34, 0xb8, 0xe6, 0xc7, 0x08, 0x86, 0x88, + 0xa9, 0xcd, 0x33, 0xbd, 0xf2, 0xe2, 0xd3, 0x0a, 0x7b, 0x41, 0xa1, 0xbd, 0x85, 0x1e, 0xcd, 0x9a, + 0x64, 0xd1, 0xcb, 0xcf, 0x54, 0xdb, 0x72, 0xc5, 0x8a, 0xda, 0xfe, 0x60, 0x81, 0x03, 0x1b, 0x3c, + 0xfa, 0xa4, 0x13, 0x42, 0x81, 0x36, 0x21, 0x83, 0x09, 0x97, 0xd5, 0x84, 0xa9, 0x88, 0xa9, 0xec, + 0xe8, 0xa7, 0x57, 0xb3, 0x80, 0xda, 0x17, 0xc1, 0x44, 0x47, 0x31, 0x98, 0xe2, 0xbd, 0xe4, 0x0c, + 0x31, 0x3f, 0x1d, 0x1d, 0x74, 0x6d, 0xef, 0xdd, 0xfb, 0xf5, 0x31, 0xcf, 0x10, 0xac, 0xce, 0xa9, + 0x7c, 0x0a, 0xea, 0xc6, 0x12, 0x58, 0xdc, 0xa6, 0xb2, 0xc8, 0xe0, 0xc1, 0x04, 0x38, 0xb4, 0xc1, + 0xa3, 0x3c, 0xcb, 0x66, 0x18, 0x62, 0x59, 0xa5, 0xdd, 0x06, 0xc0, 0xfb, 0x60, 0x0e, 0x13, 0x2c, + 0x30, 0x6c, 0xfb, 0x31, 0x92, 0xa5, 0x37, 0x82, 0xab, 0xea, 0x63, 0xc8, 0xa1, 0xe7, 0x98, 0x51, + 0xa7, 0x3e, 0x80, 0x44, 0x18, 0x7d, 0xb3, 0xc6, 0x4f, 0x2f, 0xca, 0x81, 0x10, 0x21, 0x82, 0x38, + 0xe6, 0x7e, 0x0c, 0x79, 0xac, 0xbe, 0xe9, 0x8c, 0x37, 0x6d, 0xd6, 0x2e, 0x40, 0x1e, 0xdb, 0x75, + 0x30, 0xdd, 0xc2, 0x04, 0xb2, 0xae, 0x46, 0xec, 0x55, 0x08, 0xa0, 0x97, 0x14, 0xe0, 0x1c, 0x00, + 0xbc, 0x03, 0xaf, 0x13, 0x5f, 0x1e, 0x03, 0x95, 0x7d, 0x46, 0x88, 0x1e, 0xf1, 0x4e, 0x3e, 0xe2, + 0x9d, 0xad, 0xfc, 0x8c, 0x58, 0x9b, 0x94, 0x42, 0x6e, 0xfd, 0x59, 0xb7, 0xbc, 0x29, 0xe5, 0x27, + 0x2d, 0xf6, 0x87, 0x60, 0x3e, 0x25, 0x2d, 0x4a, 0x42, 0x4c, 0x22, 0xbf, 0x83, 0x18, 0xa6, 0x61, + 0x65, 0x42, 0x51, 0x2d, 0xed, 0xa0, 0x5a, 0x37, 0xa7, 0x89, 0x66, 0xfa, 0x4e, 0x32, 0x1d, 0x28, + 0x9c, 0x37, 0x95, 0xaf, 0xfd, 0x31, 0xb0, 0x83, 0x20, 0x53, 0x92, 0x68, 0x2a, 0x72, 0xc6, 0xfd, + 0xc3, 0x33, 0xce, 0x07, 0x41, 0xb6, 0xa5, 0xbd, 0x0d, 0xe5, 0xe7, 0x60, 0x51, 0x30, 0x48, 0xf8, + 0x55, 0xc4, 0xb6, 0xf3, 0x4e, 0x0e, 0xcf, 0xbb, 0x90, 0x73, 0xf4, 0x93, 0x5f, 0x00, 0xcb, 0xc5, + 0x64, 0x66, 0x28, 0xc4, 0x5c, 0x30, 0xdc, 0x4a, 0x55, 0xd3, 0xe5, 0x6d, 0x53, 0x99, 0x52, 0x9b, + 0xa0, 0x96, 0xe3, 0xbc, 0x3e, 0xd8, 0x7b, 0x06, 0x65, 0x7f, 0x04, 0x9e, 0x57, 0x6d, 0xca, 0xa5, + 0x38, 0xbf, 0x8f, 0x49, 0x85, 0x4e, 0x30, 0xe7, 0x92, 0x0d, 0x2c, 0x5b, 0x27, 0xc6, 0xbd, 0x63, + 0x1a, 0xbb, 0x89, 0xd8, 0x7a, 0x09, 0xb9, 0x55, 0x02, 0xda, 0xa7, 0x81, 0x1d, 0x63, 0x2e, 0x28, + 0xc3, 0x01, 0x6c, 0xfb, 0x88, 0x08, 0x86, 0x11, 0xaf, 0x4c, 0x2b, 0xf7, 0x83, 0x3d, 0xcb, 0x79, + 0x6d, 0xb0, 0x2f, 0x81, 0x63, 0x4f, 0x0c, 0xea, 0x07, 0x31, 0x24, 0x04, 0xb5, 0x2b, 0x33, 0x2a, + 0x95, 0x7a, 0xf8, 0x84, 0x98, 0xe7, 0x34, 0xac, 0xbf, 0x91, 0x67, 0x87, 0x6e, 0xe4, 0x1d, 0xdd, + 0x77, 0x14, 0xfc, 0x7f, 0x40, 0x87, 0x15, 0x1d, 0xf8, 0x8b, 0x05, 0xec, 0x92, 0xdd, 0x43, 0x09, + 0xcd, 0x60, 0x7b, 0xb7, 0x06, 0x6c, 0x82, 0x29, 0x2e, 0x68, 0x47, 0x6f, 0xf9, 0x3d, 0xcf, 0xb0, + 0xe5, 0x27, 0xa5, 0x9b, 0xda, 0xf1, 0x7d, 0xb9, 0x8d, 0x8f, 0x9e, 0xdb, 0x11, 0x50, 0xdd, 0xa9, + 0xbd, 0x48, 0xed, 0x27, 0x0b, 0x2c, 0x48, 0x73, 0x0c, 0x49, 0x84, 0x3c, 0x74, 0x1d, 0xb2, 0x70, + 0x1d, 0x11, 0x9a, 0x70, 0xbb, 0x01, 0x66, 0x43, 0xf5, 0xe4, 0x0b, 0x2a, 0x6f, 0x11, 0x15, 0x6b, + 0x79, 0x5c, 0x5e, 0x06, 0xf4, 0xe2, 0x16, 0x6d, 0x86, 0xa1, 0x7d, 0x02, 0xcc, 0xf7, 0x30, 0x4c, + 0x52, 0xcb, 0x6c, 0x25, 0x6c, 0x2e, 0x87, 0xa9, 0x80, 0xff, 0x5d, 0x36, 0x75, 0x75, 0x52, 0xee, + 0x94, 0x9b, 0x27, 0xb4, 0xf2, 0xfd, 0x7e, 0x30, 0xbe, 0xc1, 0x23, 0xfb, 0x5b, 0x0b, 0x1c, 0xdc, + 0x79, 0x69, 0x7a, 0x73, 0xa8, 0x89, 0x3d, 0xe8, 0x66, 0x52, 0x6d, 0x8e, 0xec, 0x9a, 0x6b, 0xb3, + 0x7f, 0xb4, 0x40, 0x75, 0x97, 0x1b, 0xcd, 0xda, 0xb0, 0x11, 0x9e, 0xcc, 0x51, 0xbd, 0xf4, 0xef, + 0x39, 0x76, 0x91, 0xdb, 0x77, 0x27, 0x19, 0x51, 0x6e, 0x99, 0x63, 0x54, 0xb9, 0x83, 0x4e, 0x7a, + 0xfb, 0x1b, 0x0b, 0xcc, 0xef, 0x38, 0x24, 0xdf, 0x18, 0x36, 0xc0, 0x76, 0xcf, 0xea, 0xbb, 0xa3, + 0x7a, 0x16, 0x82, 0xbe, 0xb6, 0xc0, 0x81, 0xed, 0x33, 0xe3, 0xec, 0xb3, 0xb2, 0x1a, 0xc7, 0xea, + 0x3b, 0x23, 0x3a, 0x16, 0x6a, 0x6e, 0x5a, 0x60, 0xa6, 0xef, 0x16, 0xf4, 0xea, 0xb0, 0x8c, 0x65, + 0xaf, 0xea, 0x5b, 0xa3, 0x78, 0xe5, 0x22, 0xaa, 0xfb, 0xbe, 0x7c, 0x7c, 0xe7, 0xa4, 0xb5, 0xf6, + 0xe9, 0xdd, 0x87, 0x35, 0xeb, 0xde, 0xc3, 0x9a, 0xf5, 0xe0, 0x61, 0xcd, 0xba, 0xf5, 0xa8, 0x36, + 0x76, 0xef, 0x51, 0x6d, 0xec, 0x8f, 0x47, 0xb5, 0xb1, 0xcf, 0xde, 0x8e, 0xb0, 0x88, 0xd3, 0x96, + 0x13, 0xd0, 0xc4, 0xfc, 0x8f, 0x73, 0x7b, 0xf1, 0x4e, 0x17, 0x7f, 0xc3, 0xb2, 0xd7, 0xdc, 0x1b, + 0xfd, 0xff, 0xc5, 0xd4, 0xdd, 0xb5, 0x35, 0xa1, 0x86, 0xeb, 0x2b, 0xff, 0x04, 0x00, 0x00, 0xff, + 0xff, 0x3a, 0xa6, 0xa7, 0xc0, 0x07, 0x0f, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -341,6 +923,9 @@ type MsgClient interface { AssignConsumerKey(ctx context.Context, in *MsgAssignConsumerKey, opts ...grpc.CallOption) (*MsgAssignConsumerKeyResponse, error) SubmitConsumerMisbehaviour(ctx context.Context, in *MsgSubmitConsumerMisbehaviour, opts ...grpc.CallOption) (*MsgSubmitConsumerMisbehaviourResponse, error) SubmitConsumerDoubleVoting(ctx context.Context, in *MsgSubmitConsumerDoubleVoting, opts ...grpc.CallOption) (*MsgSubmitConsumerDoubleVotingResponse, error) + ConsumerAddition(ctx context.Context, in *MsgConsumerAddition, opts ...grpc.CallOption) (*MsgConsumerAdditionResponse, error) + ConsumerRemoval(ctx context.Context, in *MsgConsumerRemoval, opts ...grpc.CallOption) (*MsgConsumerRemovalResponse, error) + UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) } type msgClient struct { @@ -378,11 +963,41 @@ func (c *msgClient) SubmitConsumerDoubleVoting(ctx context.Context, in *MsgSubmi return out, nil } +func (c *msgClient) ConsumerAddition(ctx context.Context, in *MsgConsumerAddition, opts ...grpc.CallOption) (*MsgConsumerAdditionResponse, error) { + out := new(MsgConsumerAdditionResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Msg/ConsumerAddition", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) ConsumerRemoval(ctx context.Context, in *MsgConsumerRemoval, opts ...grpc.CallOption) (*MsgConsumerRemovalResponse, error) { + out := new(MsgConsumerRemovalResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Msg/ConsumerRemoval", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { + out := new(MsgUpdateParamsResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Msg/UpdateParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { AssignConsumerKey(context.Context, *MsgAssignConsumerKey) (*MsgAssignConsumerKeyResponse, error) SubmitConsumerMisbehaviour(context.Context, *MsgSubmitConsumerMisbehaviour) (*MsgSubmitConsumerMisbehaviourResponse, error) SubmitConsumerDoubleVoting(context.Context, *MsgSubmitConsumerDoubleVoting) (*MsgSubmitConsumerDoubleVotingResponse, error) + ConsumerAddition(context.Context, *MsgConsumerAddition) (*MsgConsumerAdditionResponse, error) + ConsumerRemoval(context.Context, *MsgConsumerRemoval) (*MsgConsumerRemovalResponse, error) + UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -398,6 +1013,15 @@ func (*UnimplementedMsgServer) SubmitConsumerMisbehaviour(ctx context.Context, r func (*UnimplementedMsgServer) SubmitConsumerDoubleVoting(ctx context.Context, req *MsgSubmitConsumerDoubleVoting) (*MsgSubmitConsumerDoubleVotingResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SubmitConsumerDoubleVoting not implemented") } +func (*UnimplementedMsgServer) ConsumerAddition(ctx context.Context, req *MsgConsumerAddition) (*MsgConsumerAdditionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConsumerAddition not implemented") +} +func (*UnimplementedMsgServer) ConsumerRemoval(ctx context.Context, req *MsgConsumerRemoval) (*MsgConsumerRemovalResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConsumerRemoval not implemented") +} +func (*UnimplementedMsgServer) UpdateParams(ctx context.Context, req *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -457,7 +1081,61 @@ func _Msg_SubmitConsumerDoubleVoting_Handler(srv interface{}, ctx context.Contex return interceptor(ctx, in, info, handler) } -var _Msg_serviceDesc = grpc.ServiceDesc{ +func _Msg_ConsumerAddition_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgConsumerAddition) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ConsumerAddition(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Msg/ConsumerAddition", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ConsumerAddition(ctx, req.(*MsgConsumerAddition)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_ConsumerRemoval_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgConsumerRemoval) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ConsumerRemoval(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Msg/ConsumerRemoval", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ConsumerRemoval(ctx, req.(*MsgConsumerRemoval)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Msg/UpdateParams", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "interchain_security.ccv.provider.v1.Msg", HandlerType: (*MsgServer)(nil), Methods: []grpc.MethodDesc{ @@ -473,6 +1151,18 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "SubmitConsumerDoubleVoting", Handler: _Msg_SubmitConsumerDoubleVoting_Handler, }, + { + MethodName: "ConsumerAddition", + Handler: _Msg_ConsumerAddition_Handler, + }, + { + MethodName: "ConsumerRemoval", + Handler: _Msg_ConsumerRemoval_Handler, + }, + { + MethodName: "UpdateParams", + Handler: _Msg_UpdateParams_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "interchain_security/ccv/provider/v1/tx.proto", @@ -498,6 +1188,13 @@ func (m *MsgAssignConsumerKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x22 + } if len(m.ConsumerKey) > 0 { i -= len(m.ConsumerKey) copy(dAtA[i:], m.ConsumerKey) @@ -687,141 +1384,1661 @@ func (m *MsgSubmitConsumerDoubleVotingResponse) MarshalToSizedBuffer(dAtA []byte return len(dAtA) - i, nil } -func encodeVarintTx(dAtA []byte, offset int, v uint64) int { - offset -= sovTx(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *MsgUpdateParams) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *MsgAssignConsumerKey) Size() (n int) { - if m == nil { - return 0 - } + +func (m *MsgUpdateParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.ChainId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - l = len(m.ProviderAddr) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) } - l = len(m.ConsumerKey) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + i-- + dAtA[i] = 0x12 + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *MsgAssignConsumerKeyResponse) Size() (n int) { - if m == nil { - return 0 +func (m *MsgUpdateParamsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *MsgUpdateParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - return n + return len(dAtA) - i, nil } -func (m *MsgSubmitConsumerMisbehaviour) Size() (n int) { - if m == nil { - return 0 +func (m *MsgConsumerAddition) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *MsgConsumerAddition) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgConsumerAddition) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.Submitter) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0x6a } - if m.Misbehaviour != nil { - l = m.Misbehaviour.Size() - n += 1 + l + sovTx(uint64(l)) + if len(m.DistributionTransmissionChannel) > 0 { + i -= len(m.DistributionTransmissionChannel) + copy(dAtA[i:], m.DistributionTransmissionChannel) + i = encodeVarintTx(dAtA, i, uint64(len(m.DistributionTransmissionChannel))) + i-- + dAtA[i] = 0x62 } - return n + if m.HistoricalEntries != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.HistoricalEntries)) + i-- + dAtA[i] = 0x58 + } + if m.BlocksPerDistributionTransmission != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.BlocksPerDistributionTransmission)) + i-- + dAtA[i] = 0x50 + } + if len(m.ConsumerRedistributionFraction) > 0 { + i -= len(m.ConsumerRedistributionFraction) + copy(dAtA[i:], m.ConsumerRedistributionFraction) + i = encodeVarintTx(dAtA, i, uint64(len(m.ConsumerRedistributionFraction))) + i-- + dAtA[i] = 0x4a + } + n5, err5 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.TransferTimeoutPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.TransferTimeoutPeriod):]) + if err5 != nil { + return 0, err5 + } + i -= n5 + i = encodeVarintTx(dAtA, i, uint64(n5)) + i-- + dAtA[i] = 0x42 + n6, err6 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.CcvTimeoutPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.CcvTimeoutPeriod):]) + if err6 != nil { + return 0, err6 + } + i -= n6 + i = encodeVarintTx(dAtA, i, uint64(n6)) + i-- + dAtA[i] = 0x3a + n7, err7 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingPeriod):]) + if err7 != nil { + return 0, err7 + } + i -= n7 + i = encodeVarintTx(dAtA, i, uint64(n7)) + i-- + dAtA[i] = 0x32 + n8, err8 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.SpawnTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.SpawnTime):]) + if err8 != nil { + return 0, err8 + } + i -= n8 + i = encodeVarintTx(dAtA, i, uint64(n8)) + i-- + dAtA[i] = 0x2a + if len(m.BinaryHash) > 0 { + i -= len(m.BinaryHash) + copy(dAtA[i:], m.BinaryHash) + i = encodeVarintTx(dAtA, i, uint64(len(m.BinaryHash))) + i-- + dAtA[i] = 0x22 + } + if len(m.GenesisHash) > 0 { + i -= len(m.GenesisHash) + copy(dAtA[i:], m.GenesisHash) + i = encodeVarintTx(dAtA, i, uint64(len(m.GenesisHash))) + i-- + dAtA[i] = 0x1a + } + { + size, err := m.InitialHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil } -func (m *MsgSubmitConsumerMisbehaviourResponse) Size() (n int) { - if m == nil { - return 0 +func (m *MsgConsumerAdditionResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *MsgConsumerAdditionResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgConsumerAdditionResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - return n + return len(dAtA) - i, nil } -func (m *MsgSubmitConsumerDoubleVoting) Size() (n int) { - if m == nil { - return 0 +func (m *MsgConsumerRemoval) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *MsgConsumerRemoval) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgConsumerRemoval) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.Submitter) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0x1a } - if m.DuplicateVoteEvidence != nil { - l = m.DuplicateVoteEvidence.Size() - n += 1 + l + sovTx(uint64(l)) + n10, err10 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.StopTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.StopTime):]) + if err10 != nil { + return 0, err10 } - if m.InfractionBlockHeader != nil { - l = m.InfractionBlockHeader.Size() - n += 1 + l + sovTx(uint64(l)) + i -= n10 + i = encodeVarintTx(dAtA, i, uint64(n10)) + i-- + dAtA[i] = 0x12 + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *MsgSubmitConsumerDoubleVotingResponse) Size() (n int) { - if m == nil { - return 0 +func (m *MsgConsumerRemovalResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *MsgConsumerRemovalResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgConsumerRemovalResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - return n + return len(dAtA) - i, nil } -func sovTx(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 +func (m *MsgChangeRewardDenoms) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil } -func sozTx(x uint64) (n int) { - return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) + +func (m *MsgChangeRewardDenoms) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MsgAssignConsumerKey) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { + +func (m *MsgChangeRewardDenoms) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0x1a + } + if len(m.DenomsToRemove) > 0 { + for iNdEx := len(m.DenomsToRemove) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.DenomsToRemove[iNdEx]) + copy(dAtA[i:], m.DenomsToRemove[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.DenomsToRemove[iNdEx]))) + i-- + dAtA[i] = 0x12 + } + } + if len(m.DenomsToAdd) > 0 { + for iNdEx := len(m.DenomsToAdd) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.DenomsToAdd[iNdEx]) + copy(dAtA[i:], m.DenomsToAdd[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.DenomsToAdd[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *MsgChangeRewardDenomsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgChangeRewardDenomsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgChangeRewardDenomsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgAssignConsumerKey) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProviderAddr) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ConsumerKey) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgAssignConsumerKeyResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgSubmitConsumerMisbehaviour) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Submitter) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.Misbehaviour != nil { + l = m.Misbehaviour.Size() + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgSubmitConsumerMisbehaviourResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgSubmitConsumerDoubleVoting) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Submitter) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.DuplicateVoteEvidence != nil { + l = m.DuplicateVoteEvidence.Size() + n += 1 + l + sovTx(uint64(l)) + } + if m.InfractionBlockHeader != nil { + l = m.InfractionBlockHeader.Size() + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgSubmitConsumerDoubleVotingResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgUpdateParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Params.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgUpdateParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgConsumerAddition) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.InitialHeight.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.GenesisHash) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.BinaryHash) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.SpawnTime) + n += 1 + l + sovTx(uint64(l)) + l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingPeriod) + n += 1 + l + sovTx(uint64(l)) + l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.CcvTimeoutPeriod) + n += 1 + l + sovTx(uint64(l)) + l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.TransferTimeoutPeriod) + n += 1 + l + sovTx(uint64(l)) + l = len(m.ConsumerRedistributionFraction) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.BlocksPerDistributionTransmission != 0 { + n += 1 + sovTx(uint64(m.BlocksPerDistributionTransmission)) + } + if m.HistoricalEntries != 0 { + n += 1 + sovTx(uint64(m.HistoricalEntries)) + } + l = len(m.DistributionTransmissionChannel) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgConsumerAdditionResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgConsumerRemoval) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.StopTime) + n += 1 + l + sovTx(uint64(l)) + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgConsumerRemovalResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgChangeRewardDenoms) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.DenomsToAdd) > 0 { + for _, s := range m.DenomsToAdd { + l = len(s) + n += 1 + l + sovTx(uint64(l)) + } + } + if len(m.DenomsToRemove) > 0 { + for _, s := range m.DenomsToRemove { + l = len(s) + n += 1 + l + sovTx(uint64(l)) + } + } + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgChangeRewardDenomsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgAssignConsumerKey) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgAssignConsumerKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAssignConsumerKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProviderAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerKey", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConsumerKey = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgAssignConsumerKeyResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgAssignConsumerKeyResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAssignConsumerKeyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSubmitConsumerMisbehaviour) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviour: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviour: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Submitter", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Submitter = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Misbehaviour", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Misbehaviour == nil { + m.Misbehaviour = &_07_tendermint.Misbehaviour{} + } + if err := m.Misbehaviour.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSubmitConsumerMisbehaviourResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviourResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviourResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSubmitConsumerDoubleVoting) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSubmitConsumerDoubleVoting: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSubmitConsumerDoubleVoting: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Submitter", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Submitter = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DuplicateVoteEvidence", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.DuplicateVoteEvidence == nil { + m.DuplicateVoteEvidence = &types.DuplicateVoteEvidence{} + } + if err := m.DuplicateVoteEvidence.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InfractionBlockHeader", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.InfractionBlockHeader == nil { + m.InfractionBlockHeader = &_07_tendermint.Header{} + } + if err := m.InfractionBlockHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSubmitConsumerDoubleVotingResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSubmitConsumerDoubleVotingResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSubmitConsumerDoubleVotingResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateParams) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgConsumerAddition) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx } - if iNdEx >= l { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgConsumerAddition: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgConsumerAddition: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InitialHeight", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.InitialHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GenesisHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GenesisHash = append(m.GenesisHash[:0], dAtA[iNdEx:postIndex]...) + if m.GenesisHash == nil { + m.GenesisHash = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BinaryHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BinaryHash = append(m.BinaryHash[:0], dAtA[iNdEx:postIndex]...) + if m.BinaryHash == nil { + m.BinaryHash = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpawnTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.SpawnTime, dAtA[iNdEx:postIndex]); err != nil { + return err } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MsgAssignConsumerKey: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MsgAssignConsumerKey: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + iNdEx = postIndex + case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UnbondingPeriod", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.UnbondingPeriod, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CcvTimeoutPeriod", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.CcvTimeoutPeriod, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TransferTimeoutPeriod", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.TransferTimeoutPeriod, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerRedistributionFraction", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -849,11 +3066,49 @@ func (m *MsgAssignConsumerKey) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainId = string(dAtA[iNdEx:postIndex]) + m.ConsumerRedistributionFraction = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlocksPerDistributionTransmission", wireType) + } + m.BlocksPerDistributionTransmission = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlocksPerDistributionTransmission |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HistoricalEntries", wireType) + } + m.HistoricalEntries = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.HistoricalEntries |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 12: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddr", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DistributionTransmissionChannel", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -881,11 +3136,11 @@ func (m *MsgAssignConsumerKey) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ProviderAddr = string(dAtA[iNdEx:postIndex]) + m.DistributionTransmissionChannel = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 13: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConsumerKey", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -913,7 +3168,7 @@ func (m *MsgAssignConsumerKey) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ConsumerKey = string(dAtA[iNdEx:postIndex]) + m.Authority = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -936,7 +3191,7 @@ func (m *MsgAssignConsumerKey) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgAssignConsumerKeyResponse) Unmarshal(dAtA []byte) error { +func (m *MsgConsumerAdditionResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -959,10 +3214,10 @@ func (m *MsgAssignConsumerKeyResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgAssignConsumerKeyResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgConsumerAdditionResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgAssignConsumerKeyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgConsumerAdditionResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -986,7 +3241,7 @@ func (m *MsgAssignConsumerKeyResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgSubmitConsumerMisbehaviour) Unmarshal(dAtA []byte) error { +func (m *MsgConsumerRemoval) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1009,15 +3264,15 @@ func (m *MsgSubmitConsumerMisbehaviour) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviour: wiretype end group for non-group") + return fmt.Errorf("proto: MsgConsumerRemoval: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviour: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgConsumerRemoval: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Submitter", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1045,11 +3300,11 @@ func (m *MsgSubmitConsumerMisbehaviour) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Submitter = string(dAtA[iNdEx:postIndex]) + m.ChainId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Misbehaviour", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field StopTime", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1076,13 +3331,42 @@ func (m *MsgSubmitConsumerMisbehaviour) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Misbehaviour == nil { - m.Misbehaviour = &_07_tendermint.Misbehaviour{} - } - if err := m.Misbehaviour.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.StopTime, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -1104,7 +3388,7 @@ func (m *MsgSubmitConsumerMisbehaviour) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgSubmitConsumerMisbehaviourResponse) Unmarshal(dAtA []byte) error { +func (m *MsgConsumerRemovalResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1127,10 +3411,10 @@ func (m *MsgSubmitConsumerMisbehaviourResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviourResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgConsumerRemovalResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviourResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgConsumerRemovalResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -1154,7 +3438,7 @@ func (m *MsgSubmitConsumerMisbehaviourResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgSubmitConsumerDoubleVoting) Unmarshal(dAtA []byte) error { +func (m *MsgChangeRewardDenoms) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1177,15 +3461,15 @@ func (m *MsgSubmitConsumerDoubleVoting) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgSubmitConsumerDoubleVoting: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChangeRewardDenoms: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgSubmitConsumerDoubleVoting: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChangeRewardDenoms: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Submitter", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DenomsToAdd", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1213,13 +3497,13 @@ func (m *MsgSubmitConsumerDoubleVoting) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Submitter = string(dAtA[iNdEx:postIndex]) + m.DenomsToAdd = append(m.DenomsToAdd, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DuplicateVoteEvidence", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DenomsToRemove", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -1229,33 +3513,29 @@ func (m *MsgSubmitConsumerDoubleVoting) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - if m.DuplicateVoteEvidence == nil { - m.DuplicateVoteEvidence = &types.DuplicateVoteEvidence{} - } - if err := m.DuplicateVoteEvidence.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.DenomsToRemove = append(m.DenomsToRemove, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InfractionBlockHeader", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -1265,27 +3545,23 @@ func (m *MsgSubmitConsumerDoubleVoting) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - if m.InfractionBlockHeader == nil { - m.InfractionBlockHeader = &_07_tendermint.Header{} - } - if err := m.InfractionBlockHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Authority = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -1308,7 +3584,7 @@ func (m *MsgSubmitConsumerDoubleVoting) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgSubmitConsumerDoubleVotingResponse) Unmarshal(dAtA []byte) error { +func (m *MsgChangeRewardDenomsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1331,10 +3607,10 @@ func (m *MsgSubmitConsumerDoubleVotingResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgSubmitConsumerDoubleVotingResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChangeRewardDenomsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgSubmitConsumerDoubleVotingResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChangeRewardDenomsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: diff --git a/x/ccv/types/expected_keepers.go b/x/ccv/types/expected_keepers.go index a2ef7ab465..f7456c7e3b 100644 --- a/x/ccv/types/expected_keepers.go +++ b/x/ccv/types/expected_keepers.go @@ -4,21 +4,21 @@ import ( context "context" "time" - transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - conntypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + conntypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" "cosmossdk.io/math" + storetypes "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" - auth "github.com/cosmos/cosmos-sdk/x/auth/types" - capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" + abci "github.com/cometbft/cometbft/abci/types" ) @@ -26,45 +26,45 @@ import ( // of the provider validator set. This version of the interchain-security protocol will mirror the provider chain's changes // so we do not need a registry module between the staking module and CCV. type StakingKeeper interface { - GetValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate - UnbondingCanComplete(ctx sdk.Context, id uint64) error - UnbondingTime(ctx sdk.Context) time.Duration - GetValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) (validator stakingtypes.Validator, found bool) - GetLastValidatorPower(ctx sdk.Context, operator sdk.ValAddress) (power int64) - Jail(sdk.Context, sdk.ConsAddress) // jail a validator - Slash(sdk.Context, sdk.ConsAddress, int64, int64, sdk.Dec) math.Int - SlashWithInfractionReason(sdk.Context, sdk.ConsAddress, int64, int64, sdk.Dec, stakingtypes.Infraction) math.Int - SlashUnbondingDelegation(sdk.Context, stakingtypes.UnbondingDelegation, int64, sdk.Dec) math.Int - SlashRedelegation(sdk.Context, stakingtypes.Validator, stakingtypes.Redelegation, int64, sdk.Dec) math.Int - Unjail(ctx sdk.Context, addr sdk.ConsAddress) - GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, found bool) - IterateLastValidatorPowers(ctx sdk.Context, cb func(addr sdk.ValAddress, power int64) (stop bool)) - PowerReduction(ctx sdk.Context) math.Int - PutUnbondingOnHold(ctx sdk.Context, id uint64) error - IterateValidators(ctx sdk.Context, f func(index int64, validator stakingtypes.ValidatorI) (stop bool)) - Validator(ctx sdk.Context, addr sdk.ValAddress) stakingtypes.ValidatorI - IsValidatorJailed(ctx sdk.Context, addr sdk.ConsAddress) bool - ValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) stakingtypes.ValidatorI - Delegation(ctx sdk.Context, addr sdk.AccAddress, valAddr sdk.ValAddress) stakingtypes.DelegationI - MaxValidators(ctx sdk.Context) uint32 - GetLastTotalPower(ctx sdk.Context) math.Int - GetLastValidators(ctx sdk.Context) (validators []stakingtypes.Validator) - BondDenom(ctx sdk.Context) (res string) - GetUnbondingDelegationsFromValidator(ctx sdk.Context, valAddr sdk.ValAddress) (ubds []stakingtypes.UnbondingDelegation) - GetRedelegationsFromSrcValidator(ctx sdk.Context, valAddr sdk.ValAddress) (reds []stakingtypes.Redelegation) - GetUnbondingType(ctx sdk.Context, id uint64) (unbondingType stakingtypes.UnbondingType, found bool) + GetValidatorUpdates(ctx context.Context) ([]abci.ValidatorUpdate, error) + UnbondingCanComplete(ctx context.Context, id uint64) error + UnbondingTime(ctx context.Context) (time.Duration, error) + GetValidatorByConsAddr(ctx context.Context, consAddr sdk.ConsAddress) (stakingtypes.Validator, error) + GetLastValidatorPower(ctx context.Context, operator sdk.ValAddress) (int64, error) + Jail(context.Context, sdk.ConsAddress) error // jail a validator + Slash(ctx context.Context, consAddr sdk.ConsAddress, infractionHeight, power int64, slashFactor math.LegacyDec) (math.Int, error) + SlashWithInfractionReason(ctx context.Context, consAddr sdk.ConsAddress, infractionHeight, power int64, slashFactor math.LegacyDec, infraction stakingtypes.Infraction) (math.Int, error) + SlashUnbondingDelegation(ctx context.Context, unbondingDelegation stakingtypes.UnbondingDelegation, infractionHeight int64, slashFactor math.LegacyDec) (math.Int, error) + SlashRedelegation(ctx context.Context, srcValidator stakingtypes.Validator, redelegation stakingtypes.Redelegation, infractionHeight int64, slashFactor math.LegacyDec) (math.Int, error) + Unjail(ctx context.Context, addr sdk.ConsAddress) error + GetValidator(ctx context.Context, addr sdk.ValAddress) (stakingtypes.Validator, error) + IterateLastValidatorPowers(ctx context.Context, cb func(addr sdk.ValAddress, power int64) (stop bool)) error + PowerReduction(ctx context.Context) math.Int + PutUnbondingOnHold(ctx context.Context, id uint64) error + IterateValidators(ctx context.Context, f func(index int64, validator stakingtypes.ValidatorI) (stop bool)) error + Validator(ctx context.Context, addr sdk.ValAddress) (stakingtypes.ValidatorI, error) + IsValidatorJailed(ctx context.Context, addr sdk.ConsAddress) (bool, error) + ValidatorByConsAddr(ctx context.Context, consAddr sdk.ConsAddress) (stakingtypes.ValidatorI, error) + Delegation(ctx context.Context, addr sdk.AccAddress, valAddr sdk.ValAddress) (stakingtypes.DelegationI, error) + MaxValidators(ctx context.Context) (uint32, error) + GetLastTotalPower(ctx context.Context) (math.Int, error) + GetLastValidators(ctx context.Context) ([]stakingtypes.Validator, error) + BondDenom(ctx context.Context) (string, error) + GetUnbondingDelegationsFromValidator(ctx context.Context, valAddr sdk.ValAddress) ([]stakingtypes.UnbondingDelegation, error) + GetRedelegationsFromSrcValidator(ctx context.Context, valAddr sdk.ValAddress) ([]stakingtypes.Redelegation, error) + GetUnbondingType(ctx context.Context, id uint64) (stakingtypes.UnbondingType, error) } // SlashingKeeper defines the contract expected to perform ccv slashing type SlashingKeeper interface { - JailUntil(sdk.Context, sdk.ConsAddress, time.Time) // called from provider keeper only - GetValidatorSigningInfo(ctx sdk.Context, address sdk.ConsAddress) (info slashingtypes.ValidatorSigningInfo, found bool) - SetValidatorSigningInfo(ctx sdk.Context, address sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) - DowntimeJailDuration(sdk.Context) time.Duration - SlashFractionDowntime(sdk.Context) sdk.Dec - SlashFractionDoubleSign(ctx sdk.Context) (res sdk.Dec) - Tombstone(sdk.Context, sdk.ConsAddress) - IsTombstoned(sdk.Context, sdk.ConsAddress) bool + JailUntil(context.Context, sdk.ConsAddress, time.Time) error // called from provider keeper only + GetValidatorSigningInfo(context.Context, sdk.ConsAddress) (slashingtypes.ValidatorSigningInfo, error) + SetValidatorSigningInfo(context.Context, sdk.ConsAddress, slashingtypes.ValidatorSigningInfo) error + DowntimeJailDuration(context.Context) (time.Duration, error) + SlashFractionDowntime(context.Context) (math.LegacyDec, error) + SlashFractionDoubleSign(context.Context) (math.LegacyDec, error) + Tombstone(context.Context, sdk.ConsAddress) error + IsTombstoned(context.Context, sdk.ConsAddress) bool } // ChannelKeeper defines the expected IBC channel keeper @@ -101,31 +101,31 @@ type ClientKeeper interface { GetClientState(ctx sdk.Context, clientID string) (ibcexported.ClientState, bool) GetLatestClientConsensusState(ctx sdk.Context, clientID string) (ibcexported.ConsensusState, bool) GetSelfConsensusState(ctx sdk.Context, height ibcexported.Height) (ibcexported.ConsensusState, error) - ClientStore(ctx sdk.Context, clientID string) sdk.KVStore + ClientStore(ctx sdk.Context, clientID string) storetypes.KVStore SetClientState(ctx sdk.Context, clientID string, clientState ibcexported.ClientState) GetClientConsensusState(ctx sdk.Context, clientID string, height ibcexported.Height) (ibcexported.ConsensusState, bool) } // DistributionKeeper defines the expected interface of the distribution keeper type DistributionKeeper interface { - FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error + FundCommunityPool(ctx context.Context, amount sdk.Coins, sender sdk.AccAddress) error } // ConsumerHooks event hooks for newly bonded cross-chain validators type ConsumerHooks interface { - AfterValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddresses sdk.ValAddress) error + AfterValidatorBonded(ctx context.Context, consAddr sdk.ConsAddress, valAddresses sdk.ValAddress) error } // BankKeeper defines the expected interface needed to retrieve account balances. type BankKeeper interface { - GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin - GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins - SendCoinsFromModuleToModule(ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins) error + GetBalance(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin + GetAllBalances(ctx context.Context, addr sdk.AccAddress) sdk.Coins + SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt sdk.Coins) error } // AccountKeeper defines the expected account keeper used for simulations type AccountKeeper interface { - GetModuleAccount(ctx sdk.Context, name string) auth.ModuleAccountI + GetModuleAccount(ctx context.Context, name string) sdk.ModuleAccountI } // IBCTransferKeeper defines the expected interface needed for distribution transfer @@ -148,7 +148,3 @@ type ScopedKeeper interface { AuthenticateCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) bool ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) error } - -type GovKeeper interface { - GetProposal(ctx sdk.Context, proposalID uint64) (v1.Proposal, bool) -} diff --git a/x/ccv/types/genesis.go b/x/ccv/types/genesis.go index 4189c2ec51..a7534b1289 100644 --- a/x/ccv/types/genesis.go +++ b/x/ccv/types/genesis.go @@ -1,7 +1,7 @@ package types import ( - ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" errorsmod "cosmossdk.io/errors" diff --git a/x/ccv/types/params.go b/x/ccv/types/params.go index c80e353d66..2bcbc41717 100644 --- a/x/ccv/types/params.go +++ b/x/ccv/types/params.go @@ -4,6 +4,7 @@ import ( fmt "fmt" time "time" + "cosmossdk.io/math" sdktypes "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -200,14 +201,14 @@ func ValidateSoftOptOutThreshold(i interface{}) error { if !ok { return fmt.Errorf("invalid parameter type: %T", i) } - dec, err := sdktypes.NewDecFromStr(str) + dec, err := math.LegacyNewDecFromStr(str) if err != nil { return err } if dec.IsNegative() { return fmt.Errorf("soft opt out threshold cannot be negative, got %s", str) } - if !dec.Sub(sdktypes.MustNewDecFromStr("0.2")).IsNegative() { + if !dec.Sub(math.LegacyMustNewDecFromStr("0.2")).IsNegative() { return fmt.Errorf("soft opt out threshold cannot be greater than 0.2, got %s", str) } return nil @@ -223,7 +224,7 @@ func ValidateDenoms(i interface{}) error { for _, denom := range v { coin := sdktypes.Coin{ Denom: denom, - Amount: sdktypes.NewInt(0), + Amount: math.NewInt(0), } if err := coin.Validate(); err != nil { diff --git a/x/ccv/types/shared_consumer.pb.go b/x/ccv/types/shared_consumer.pb.go index 95050192b8..425129c56c 100644 --- a/x/ccv/types/shared_consumer.pb.go +++ b/x/ccv/types/shared_consumer.pb.go @@ -9,7 +9,7 @@ import ( _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" - _07_tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + _07_tendermint "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" _ "google.golang.org/protobuf/types/known/durationpb" io "io" math "math" @@ -346,55 +346,55 @@ var fileDescriptor_d0a8be0efc64dfbc = []byte{ // 812 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x41, 0x73, 0xdc, 0x34, 0x14, 0x8e, 0xbb, 0x25, 0xdd, 0x68, 0x93, 0xa6, 0x88, 0x50, 0x4c, 0x3a, 0xb3, 0x71, 0x03, 0x87, - 0x1d, 0x98, 0xda, 0x24, 0xcd, 0x89, 0x1b, 0x49, 0x28, 0xa5, 0x87, 0x64, 0xeb, 0x84, 0x32, 0x03, - 0x07, 0x8d, 0x2c, 0xbd, 0x5d, 0x6b, 0xb0, 0x25, 0x8f, 0x24, 0x3b, 0xe4, 0x17, 0x70, 0xe5, 0xc8, - 0x4f, 0x2a, 0xb7, 0x1e, 0x39, 0x51, 0x26, 0xf9, 0x23, 0x8c, 0x65, 0x3b, 0xf1, 0x32, 0x04, 0xd2, - 0x9b, 0x9e, 0xde, 0xf7, 0x7d, 0xf6, 0xf7, 0xa4, 0xf7, 0x84, 0xbe, 0x10, 0xd2, 0x82, 0x66, 0x29, - 0x15, 0x92, 0x18, 0x60, 0xa5, 0x16, 0xf6, 0x3c, 0x62, 0xac, 0x8a, 0xaa, 0x9d, 0xc8, 0xa4, 0x54, - 0x03, 0x27, 0x4c, 0x49, 0x53, 0xe6, 0xa0, 0xc3, 0x42, 0x2b, 0xab, 0xf0, 0xe6, 0xbf, 0x30, 0x42, - 0xc6, 0xaa, 0xb0, 0xda, 0xd9, 0x7c, 0x64, 0x41, 0x72, 0xd0, 0xb9, 0x90, 0x36, 0xa2, 0x09, 0x13, - 0x91, 0x3d, 0x2f, 0xc0, 0x34, 0xc4, 0xcd, 0x48, 0x24, 0x2c, 0xca, 0xc4, 0x3c, 0xb5, 0x2c, 0x13, - 0x20, 0xad, 0x89, 0x7a, 0xe8, 0x6a, 0xa7, 0x17, 0xb5, 0x84, 0xf1, 0x5c, 0xa9, 0x79, 0x06, 0x91, - 0x8b, 0x92, 0x72, 0x16, 0xf1, 0x52, 0x53, 0x2b, 0x94, 0x6c, 0xf3, 0x1b, 0x73, 0x35, 0x57, 0x6e, - 0x19, 0xd5, 0xab, 0x66, 0x77, 0xfb, 0xed, 0x32, 0xba, 0x7f, 0xd0, 0xfe, 0xf2, 0x94, 0x6a, 0x9a, - 0x1b, 0xec, 0xa3, 0x7b, 0x20, 0x69, 0x92, 0x01, 0xf7, 0xbd, 0xc0, 0x9b, 0x0c, 0xe3, 0x2e, 0xc4, - 0xc7, 0xe8, 0xd3, 0x24, 0x53, 0xec, 0x27, 0x43, 0x0a, 0xd0, 0x84, 0x0b, 0x63, 0xb5, 0x48, 0xca, - 0xfa, 0x1b, 0xc4, 0x6a, 0x2a, 0x4d, 0x2e, 0x8c, 0x11, 0x4a, 0xfa, 0x77, 0x02, 0x6f, 0x32, 0x88, - 0x1f, 0x37, 0xd8, 0x29, 0xe8, 0xc3, 0x1e, 0xf2, 0xb4, 0x07, 0xc4, 0x2f, 0xd0, 0xe3, 0x1b, 0x55, - 0x08, 0x4b, 0xa9, 0x94, 0x90, 0xf9, 0x83, 0xc0, 0x9b, 0xac, 0xc4, 0x5b, 0xfc, 0x06, 0x91, 0x83, - 0x06, 0x86, 0xbf, 0x44, 0x9b, 0x85, 0x56, 0x95, 0xe0, 0xa0, 0xc9, 0x0c, 0x80, 0x14, 0x4a, 0x65, - 0x84, 0x72, 0xae, 0x89, 0xb1, 0xda, 0xbf, 0xeb, 0x44, 0x1e, 0x76, 0x88, 0x67, 0x00, 0x53, 0xa5, - 0xb2, 0xaf, 0x38, 0xd7, 0x27, 0x56, 0xe3, 0x97, 0x08, 0x33, 0x56, 0x11, 0x2b, 0x72, 0x50, 0xa5, - 0xad, 0xdd, 0x09, 0xc5, 0xfd, 0xf7, 0x02, 0x6f, 0x32, 0xda, 0xfd, 0x38, 0x6c, 0x0a, 0x1b, 0x76, - 0x85, 0x0d, 0x0f, 0xdb, 0xc2, 0xee, 0x0f, 0x5f, 0xff, 0xb9, 0xb5, 0xf4, 0xdb, 0xdb, 0x2d, 0x2f, - 0x7e, 0xc0, 0x58, 0x75, 0xda, 0xb0, 0xa7, 0x8e, 0x8c, 0x7f, 0x44, 0x1f, 0x39, 0x37, 0x33, 0xd0, - 0xff, 0xd4, 0x5d, 0xbe, 0xbd, 0xee, 0x87, 0x9d, 0xc6, 0xa2, 0xf8, 0x73, 0x14, 0x74, 0xf7, 0x8c, - 0x68, 0x58, 0x28, 0xe1, 0x4c, 0x53, 0x56, 0x2f, 0xfc, 0x7b, 0xce, 0xf1, 0xb8, 0xc3, 0xc5, 0x0b, - 0xb0, 0x67, 0x2d, 0x0a, 0x3f, 0x41, 0x38, 0x15, 0xc6, 0x2a, 0x2d, 0x18, 0xcd, 0x08, 0x48, 0xab, - 0x05, 0x18, 0x7f, 0xe8, 0x0e, 0xf0, 0xfd, 0xeb, 0xcc, 0xd7, 0x4d, 0x02, 0x1f, 0xa1, 0x07, 0xa5, - 0x4c, 0x94, 0xe4, 0x42, 0xce, 0x3b, 0x3b, 0x2b, 0xb7, 0xb7, 0xb3, 0x7e, 0x45, 0x6e, 0x8d, 0x3c, - 0x45, 0x0f, 0x8d, 0x9a, 0x59, 0xa2, 0x0a, 0x4b, 0xea, 0x0a, 0xd9, 0x54, 0x83, 0x49, 0x55, 0xc6, - 0x7d, 0xe4, 0x7e, 0xff, 0x83, 0x3a, 0x7b, 0x5c, 0xd8, 0xe3, 0xd2, 0x9e, 0x76, 0x29, 0xfc, 0x09, - 0x5a, 0xd3, 0x70, 0x46, 0x35, 0x27, 0x1c, 0xa4, 0xca, 0x8d, 0x3f, 0x0a, 0x06, 0x93, 0x95, 0x78, - 0xb5, 0xd9, 0x3c, 0x74, 0x7b, 0x78, 0x0f, 0x5d, 0x1d, 0x36, 0x59, 0x44, 0xaf, 0x3a, 0xf4, 0x46, - 0x97, 0x8d, 0xfb, 0xac, 0x97, 0x08, 0x6b, 0xb0, 0xfa, 0x9c, 0x70, 0xc8, 0xe8, 0x79, 0xe7, 0x70, - 0xed, 0x1d, 0x2e, 0x82, 0xa3, 0x1f, 0xd6, 0xec, 0xc6, 0xe2, 0xf6, 0xef, 0x1e, 0xda, 0xe8, 0x3a, - 0xec, 0x1b, 0x90, 0x60, 0x84, 0x39, 0xb1, 0xd4, 0x02, 0x7e, 0x8e, 0x96, 0x0b, 0xd7, 0x71, 0xae, - 0xcd, 0x46, 0xbb, 0x9f, 0x85, 0x37, 0xcf, 0x8a, 0x70, 0xb1, 0x47, 0xf7, 0xef, 0xd6, 0x1f, 0x8c, - 0x5b, 0x3e, 0x7e, 0x81, 0x86, 0x9d, 0x1b, 0xd7, 0x7b, 0xa3, 0xdd, 0xc9, 0x7f, 0x69, 0x4d, 0x5b, - 0xec, 0xb7, 0x72, 0xa6, 0x5a, 0xa5, 0x2b, 0x3e, 0x7e, 0x84, 0x56, 0x24, 0x9c, 0x11, 0xc7, 0x74, - 0xad, 0x37, 0x8c, 0x87, 0x12, 0xce, 0x0e, 0xea, 0x78, 0xfb, 0x97, 0x3b, 0x68, 0xb5, 0xcf, 0xc6, - 0x47, 0x68, 0xb5, 0x19, 0x4f, 0xc4, 0xd4, 0x9e, 0x5a, 0x27, 0x9f, 0x87, 0x22, 0x61, 0x61, 0x7f, - 0x78, 0x85, 0xbd, 0x71, 0x55, 0xbb, 0x71, 0xbb, 0xae, 0x0c, 0xf1, 0x88, 0x5d, 0x07, 0xf8, 0x7b, - 0xb4, 0x5e, 0x5f, 0x58, 0x90, 0xa6, 0x34, 0xad, 0x64, 0x63, 0x28, 0xfc, 0x5f, 0xc9, 0x8e, 0xd6, - 0xa8, 0xde, 0x67, 0x0b, 0x31, 0x3e, 0x42, 0xeb, 0x42, 0x0a, 0x2b, 0x68, 0x46, 0x2a, 0x9a, 0x11, - 0x03, 0xd6, 0x1f, 0x04, 0x83, 0xc9, 0x68, 0x37, 0xe8, 0xeb, 0xd4, 0x53, 0x38, 0x7c, 0x45, 0x33, - 0xc1, 0xa9, 0x55, 0xfa, 0xbb, 0x82, 0x53, 0x0b, 0x6d, 0x85, 0xd6, 0x5a, 0xfa, 0x2b, 0x9a, 0x9d, - 0x80, 0xdd, 0x3f, 0x7a, 0x7d, 0x31, 0xf6, 0xde, 0x5c, 0x8c, 0xbd, 0xbf, 0x2e, 0xc6, 0xde, 0xaf, - 0x97, 0xe3, 0xa5, 0x37, 0x97, 0xe3, 0xa5, 0x3f, 0x2e, 0xc7, 0x4b, 0x3f, 0xec, 0xcd, 0x85, 0x4d, - 0xcb, 0x24, 0x64, 0x2a, 0x8f, 0x98, 0x32, 0xb9, 0x32, 0xd1, 0xf5, 0x59, 0x3c, 0xb9, 0x7a, 0x35, - 0xaa, 0xbd, 0xe8, 0x67, 0xf7, 0x74, 0xb8, 0xa1, 0x9f, 0x2c, 0xbb, 0x4b, 0xf5, 0xf4, 0xef, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x04, 0x32, 0x2d, 0xba, 0x62, 0x06, 0x00, 0x00, + 0x1d, 0x98, 0xda, 0x24, 0x2d, 0x17, 0x6e, 0x24, 0xa1, 0x94, 0x1e, 0x92, 0xad, 0x13, 0xca, 0x0c, + 0x1c, 0x34, 0xb2, 0xf4, 0x76, 0xad, 0xc1, 0x96, 0x3c, 0x92, 0xec, 0x90, 0x5f, 0xc0, 0x95, 0x23, + 0x3f, 0xa9, 0xdc, 0x7a, 0xe4, 0x44, 0x99, 0xe4, 0x8f, 0x30, 0x96, 0xed, 0x8d, 0x97, 0x21, 0x50, + 0x6e, 0x7a, 0x7a, 0xdf, 0xf7, 0xd9, 0xdf, 0x93, 0xde, 0x13, 0xfa, 0x4c, 0x48, 0x0b, 0x9a, 0xa5, + 0x54, 0x48, 0x62, 0x80, 0x95, 0x5a, 0xd8, 0x8b, 0x88, 0xb1, 0x2a, 0xaa, 0xf6, 0x22, 0x93, 0x52, + 0x0d, 0x9c, 0x30, 0x25, 0x4d, 0x99, 0x83, 0x0e, 0x0b, 0xad, 0xac, 0xc2, 0xdb, 0xff, 0xc0, 0x08, + 0x19, 0xab, 0xc2, 0x6a, 0x6f, 0xfb, 0x81, 0x05, 0xc9, 0x41, 0xe7, 0x42, 0xda, 0x88, 0x26, 0x4c, + 0x44, 0xf6, 0xa2, 0x00, 0xd3, 0x10, 0xb7, 0x23, 0x91, 0xb0, 0x28, 0x13, 0xf3, 0xd4, 0xb2, 0x4c, + 0x80, 0xb4, 0x26, 0xea, 0xa1, 0xab, 0xbd, 0x5e, 0xd4, 0x12, 0xc6, 0x73, 0xa5, 0xe6, 0x19, 0x44, + 0x2e, 0x4a, 0xca, 0x59, 0xc4, 0x4b, 0x4d, 0xad, 0x50, 0xb2, 0xcd, 0x6f, 0xcd, 0xd5, 0x5c, 0xb9, + 0x65, 0x54, 0xaf, 0x9a, 0xdd, 0xdd, 0x37, 0xab, 0xe8, 0xee, 0x61, 0xfb, 0xcb, 0x53, 0xaa, 0x69, + 0x6e, 0xb0, 0x8f, 0xee, 0x80, 0xa4, 0x49, 0x06, 0xdc, 0xf7, 0x02, 0x6f, 0x32, 0x8c, 0xbb, 0x10, + 0x9f, 0xa0, 0x8f, 0x93, 0x4c, 0xb1, 0x1f, 0x0d, 0x29, 0x40, 0x13, 0x2e, 0x8c, 0xd5, 0x22, 0x29, + 0xeb, 0x6f, 0x10, 0xab, 0xa9, 0x34, 0xb9, 0x30, 0x46, 0x28, 0xe9, 0xdf, 0x0a, 0xbc, 0xc9, 0x20, + 0x7e, 0xd8, 0x60, 0xa7, 0xa0, 0x8f, 0x7a, 0xc8, 0xb3, 0x1e, 0x10, 0x3f, 0x47, 0x0f, 0x6f, 0x54, + 0x21, 0x2c, 0xa5, 0x52, 0x42, 0xe6, 0x0f, 0x02, 0x6f, 0xb2, 0x16, 0xef, 0xf0, 0x1b, 0x44, 0x0e, + 0x1b, 0x18, 0xfe, 0x02, 0x6d, 0x17, 0x5a, 0x55, 0x82, 0x83, 0x26, 0x33, 0x00, 0x52, 0x28, 0x95, + 0x11, 0xca, 0xb9, 0x26, 0xc6, 0x6a, 0xff, 0xb6, 0x13, 0xb9, 0xdf, 0x21, 0x9e, 0x02, 0x4c, 0x95, + 0xca, 0xbe, 0xe4, 0x5c, 0x9f, 0x5a, 0x8d, 0x5f, 0x20, 0xcc, 0x58, 0x45, 0xac, 0xc8, 0x41, 0x95, + 0xb6, 0x76, 0x27, 0x14, 0xf7, 0xdf, 0x09, 0xbc, 0xc9, 0x68, 0xff, 0xc3, 0xb0, 0x29, 0x6c, 0xd8, + 0x15, 0x36, 0x3c, 0x6a, 0x0b, 0x7b, 0x30, 0x7c, 0xf5, 0xc7, 0xce, 0xca, 0xaf, 0x6f, 0x76, 0xbc, + 0xf8, 0x1e, 0x63, 0xd5, 0x59, 0xc3, 0x9e, 0x3a, 0x32, 0xfe, 0x01, 0x7d, 0xe0, 0xdc, 0xcc, 0x40, + 0xff, 0x5d, 0x77, 0xf5, 0xed, 0x75, 0xdf, 0xef, 0x34, 0x96, 0xc5, 0x9f, 0xa1, 0xa0, 0xbb, 0x67, + 0x44, 0xc3, 0x52, 0x09, 0x67, 0x9a, 0xb2, 0x7a, 0xe1, 0xdf, 0x71, 0x8e, 0xc7, 0x1d, 0x2e, 0x5e, + 0x82, 0x3d, 0x6d, 0x51, 0xf8, 0x11, 0xc2, 0xa9, 0x30, 0x56, 0x69, 0xc1, 0x68, 0x46, 0x40, 0x5a, + 0x2d, 0xc0, 0xf8, 0x43, 0x77, 0x80, 0xef, 0x5e, 0x67, 0xbe, 0x6a, 0x12, 0xf8, 0x18, 0xdd, 0x2b, + 0x65, 0xa2, 0x24, 0x17, 0x72, 0xde, 0xd9, 0x59, 0x7b, 0x7b, 0x3b, 0x9b, 0x0b, 0x72, 0x6b, 0xe4, + 0x31, 0xba, 0x6f, 0xd4, 0xcc, 0x12, 0x55, 0x58, 0x52, 0x57, 0xc8, 0xa6, 0x1a, 0x4c, 0xaa, 0x32, + 0xee, 0x23, 0xf7, 0xfb, 0xef, 0xd5, 0xd9, 0x93, 0xc2, 0x9e, 0x94, 0xf6, 0xac, 0x4b, 0xe1, 0x8f, + 0xd0, 0x86, 0x86, 0x73, 0xaa, 0x39, 0xe1, 0x20, 0x55, 0x6e, 0xfc, 0x51, 0x30, 0x98, 0xac, 0xc5, + 0xeb, 0xcd, 0xe6, 0x91, 0xdb, 0xc3, 0x4f, 0xd0, 0xe2, 0xb0, 0xc9, 0x32, 0x7a, 0xdd, 0xa1, 0xb7, + 0xba, 0x6c, 0xdc, 0x67, 0xbd, 0x40, 0x58, 0x83, 0xd5, 0x17, 0x84, 0x43, 0x46, 0x2f, 0x3a, 0x87, + 0x1b, 0xff, 0xe3, 0x22, 0x38, 0xfa, 0x51, 0xcd, 0x6e, 0x2c, 0xee, 0xfe, 0xe6, 0xa1, 0xad, 0xae, + 0xc3, 0xbe, 0x06, 0x09, 0x46, 0x98, 0x53, 0x4b, 0x2d, 0xe0, 0x67, 0x68, 0xb5, 0x70, 0x1d, 0xe7, + 0xda, 0x6c, 0xb4, 0xff, 0x49, 0x78, 0xf3, 0xac, 0x08, 0x97, 0x7b, 0xf4, 0xe0, 0x76, 0xfd, 0xc1, + 0xb8, 0xe5, 0xe3, 0xe7, 0x68, 0xd8, 0xb9, 0x71, 0xbd, 0x37, 0xda, 0x9f, 0xfc, 0x9b, 0xd6, 0xb4, + 0xc5, 0x7e, 0x23, 0x67, 0xaa, 0x55, 0x5a, 0xf0, 0xf1, 0x03, 0xb4, 0x26, 0xe1, 0x9c, 0x38, 0xa6, + 0x6b, 0xbd, 0x61, 0x3c, 0x94, 0x70, 0x7e, 0x58, 0xc7, 0xbb, 0x3f, 0xdf, 0x42, 0xeb, 0x7d, 0x36, + 0x3e, 0x46, 0xeb, 0xcd, 0x78, 0x22, 0xa6, 0xf6, 0xd4, 0x3a, 0xf9, 0x34, 0x14, 0x09, 0x0b, 0xfb, + 0xc3, 0x2b, 0xec, 0x8d, 0xab, 0xda, 0x8d, 0xdb, 0x75, 0x65, 0x88, 0x47, 0xec, 0x3a, 0xc0, 0xdf, + 0xa1, 0xcd, 0xfa, 0xc2, 0x82, 0x34, 0xa5, 0x69, 0x25, 0x1b, 0x43, 0xe1, 0x7f, 0x4a, 0x76, 0xb4, + 0x46, 0xf5, 0x2e, 0x5b, 0x8a, 0xf1, 0x31, 0xda, 0x14, 0x52, 0x58, 0x41, 0x33, 0x52, 0xd1, 0x8c, + 0x18, 0xb0, 0xfe, 0x20, 0x18, 0x4c, 0x46, 0xfb, 0x41, 0x5f, 0xa7, 0x9e, 0xc2, 0xe1, 0x4b, 0x9a, + 0x09, 0x4e, 0xad, 0xd2, 0xdf, 0x16, 0x9c, 0x5a, 0x68, 0x2b, 0xb4, 0xd1, 0xd2, 0x5f, 0xd2, 0xec, + 0x14, 0xec, 0xc1, 0xf1, 0xab, 0xcb, 0xb1, 0xf7, 0xfa, 0x72, 0xec, 0xfd, 0x79, 0x39, 0xf6, 0x7e, + 0xb9, 0x1a, 0xaf, 0xbc, 0xbe, 0x1a, 0xaf, 0xfc, 0x7e, 0x35, 0x5e, 0xf9, 0xfe, 0xc9, 0x5c, 0xd8, + 0xb4, 0x4c, 0x42, 0xa6, 0xf2, 0x88, 0x29, 0x93, 0x2b, 0x13, 0x5d, 0x9f, 0xc5, 0xa3, 0xc5, 0xab, + 0x51, 0x7d, 0x1e, 0xfd, 0xe4, 0x9e, 0x0e, 0x37, 0xf4, 0x93, 0x55, 0x77, 0xa9, 0x1e, 0xff, 0x15, + 0x00, 0x00, 0xff, 0xff, 0x9a, 0xb1, 0xf7, 0x25, 0x62, 0x06, 0x00, 0x00, } func (m *ConsumerParams) Marshal() (dAtA []byte, err error) { diff --git a/x/ccv/types/shared_params.go b/x/ccv/types/shared_params.go index 566737c0b9..fa2e28c81c 100644 --- a/x/ccv/types/shared_params.go +++ b/x/ccv/types/shared_params.go @@ -4,7 +4,8 @@ import ( fmt "fmt" "time" - ibchost "github.com/cosmos/ibc-go/v7/modules/core/24-host" + "cosmossdk.io/math" + ibchost "github.com/cosmos/ibc-go/v8/modules/core/24-host" sdktypes "github.com/cosmos/cosmos-sdk/types" ) @@ -90,21 +91,21 @@ func ValidateStringFraction(i interface{}) error { if !ok { return fmt.Errorf("invalid parameter type: %T", i) } - dec, err := sdktypes.NewDecFromStr(str) + dec, err := math.LegacyNewDecFromStr(str) if err != nil { return err } if dec.IsNegative() { return fmt.Errorf("param cannot be negative, got %s", str) } - if dec.Sub(sdktypes.NewDec(1)).IsPositive() { + if dec.Sub(math.LegacyNewDec(1)).IsPositive() { return fmt.Errorf("param cannot be greater than 1, got %s", str) } return nil } func CalculateTrustPeriod(unbondingPeriod time.Duration, defaultTrustPeriodFraction string) (time.Duration, error) { - trustDec, err := sdktypes.NewDecFromStr(defaultTrustPeriodFraction) + trustDec, err := math.LegacyNewDecFromStr(defaultTrustPeriodFraction) if err != nil { return time.Duration(0), err } diff --git a/x/ccv/types/utils.go b/x/ccv/types/utils.go index ae85240256..a7030090bd 100644 --- a/x/ccv/types/utils.go +++ b/x/ccv/types/utils.go @@ -7,9 +7,9 @@ import ( "strings" "time" - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" - host "github.com/cosmos/ibc-go/v7/modules/core/24-host" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + host "github.com/cosmos/ibc-go/v8/modules/core/24-host" errorsmod "cosmossdk.io/errors" diff --git a/x/ccv/types/utils_test.go b/x/ccv/types/utils_test.go index f7ecd83197..c3b04f3460 100644 --- a/x/ccv/types/utils_test.go +++ b/x/ccv/types/utils_test.go @@ -3,14 +3,14 @@ package types_test import ( "testing" - ibctesting "github.com/cosmos/ibc-go/v7/testing" + ibctesting "github.com/cosmos/ibc-go/v8/testing" "github.com/stretchr/testify/require" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" abci "github.com/cometbft/cometbft/abci/types" - "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/x/ccv/types" ) func TestAccumulateChanges(t *testing.T) { diff --git a/x/ccv/types/wire.pb.go b/x/ccv/types/wire.pb.go index 1cdeb237a7..a0cdc795c2 100644 --- a/x/ccv/types/wire.pb.go +++ b/x/ccv/types/wire.pb.go @@ -593,60 +593,60 @@ func init() { } var fileDescriptor_8fd0dc67df6b10ed = []byte{ - // 833 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x55, 0xcd, 0x6e, 0xe3, 0x54, - 0x14, 0xb6, 0xd3, 0x6a, 0xa0, 0x37, 0x28, 0x75, 0x3d, 0x61, 0x64, 0x3c, 0x90, 0xb1, 0x2c, 0x90, - 0xa2, 0xa2, 0xb1, 0x49, 0xda, 0x15, 0x6c, 0xc8, 0x8f, 0x4b, 0x0d, 0xd3, 0x34, 0xb2, 0x93, 0x8c, - 0x86, 0x8d, 0x75, 0x63, 0xdf, 0x26, 0x57, 0x49, 0x7c, 0x2d, 0xdf, 0x1b, 0x0f, 0x79, 0x03, 0x94, - 0x15, 0x2f, 0x90, 0x15, 0x62, 0x31, 0x8f, 0xc1, 0x6e, 0x96, 0x23, 0xb1, 0x99, 0x0d, 0x23, 0xd4, - 0xbe, 0x01, 0x4f, 0x80, 0xec, 0xfc, 0x36, 0x71, 0x2b, 0x8d, 0x84, 0x04, 0x3b, 0xfb, 0xdc, 0xf3, - 0x7d, 0xf7, 0x9c, 0xef, 0x3b, 0x57, 0x07, 0x7c, 0x81, 0x7d, 0x86, 0x42, 0xb7, 0x0f, 0xb1, 0xef, - 0x50, 0xe4, 0x8e, 0x43, 0xcc, 0x26, 0xba, 0xeb, 0x46, 0x7a, 0x54, 0xd2, 0x5f, 0xe2, 0x10, 0x69, - 0x41, 0x48, 0x18, 0x11, 0xe5, 0x94, 0x34, 0xcd, 0x75, 0x23, 0x2d, 0x2a, 0xc9, 0x9f, 0xbb, 0x84, - 0x8e, 0x08, 0xd5, 0x29, 0x83, 0x03, 0xec, 0xf7, 0xf4, 0xa8, 0xd4, 0x45, 0x0c, 0x96, 0x96, 0xff, - 0x73, 0x06, 0x39, 0xdf, 0x23, 0x3d, 0x92, 0x7c, 0xea, 0xf1, 0xd7, 0x22, 0xfa, 0x98, 0x21, 0xdf, - 0x43, 0xe1, 0x08, 0xfb, 0x4c, 0x87, 0x5d, 0x17, 0xeb, 0x6c, 0x12, 0x20, 0x3a, 0x3f, 0x54, 0xdf, - 0xf2, 0xe0, 0xd3, 0x0e, 0x1c, 0x62, 0x0f, 0x32, 0x12, 0xda, 0x88, 0xd5, 0xfa, 0xd0, 0xef, 0xa1, - 0x26, 0x74, 0x07, 0x88, 0xd5, 0x21, 0x83, 0x22, 0x01, 0x47, 0xd1, 0xf2, 0xdc, 0x19, 0x07, 0x1e, - 0x64, 0x88, 0x4a, 0xbc, 0xb2, 0x57, 0xcc, 0x96, 0x15, 0x6d, 0xcd, 0xac, 0xc5, 0xcc, 0xda, 0x8a, - 0xa9, 0x9d, 0x24, 0x56, 0x95, 0xd7, 0xef, 0x9e, 0x70, 0x7f, 0xbf, 0x7b, 0x22, 0x4d, 0xe0, 0x68, - 0xf8, 0xb5, 0xba, 0x43, 0xa4, 0x5a, 0x42, 0x74, 0x1b, 0x42, 0xc5, 0x22, 0x88, 0x63, 0x14, 0xb1, - 0x45, 0x92, 0x83, 0x3d, 0x29, 0xa3, 0xf0, 0xc5, 0x7d, 0x2b, 0x37, 0x8f, 0xcf, 0x13, 0x4d, 0x4f, - 0xfc, 0x0c, 0x00, 0x3a, 0x84, 0xb4, 0xef, 0x40, 0x77, 0x40, 0xa5, 0x3d, 0x65, 0xaf, 0x78, 0x60, - 0x1d, 0x24, 0x91, 0x8a, 0x3b, 0xa0, 0xea, 0xb7, 0x20, 0xdf, 0xb1, 0x6b, 0x17, 0x90, 0x8d, 0x43, - 0xe4, 0x6d, 0x74, 0x94, 0x76, 0x01, 0x9f, 0x76, 0x81, 0xfa, 0x07, 0x0f, 0x0e, 0xed, 0x98, 0x6f, - 0x03, 0x6d, 0x81, 0x83, 0x55, 0xc9, 0x09, 0x2c, 0x5b, 0x96, 0xef, 0xd6, 0xa1, 0x2a, 0x2d, 0x14, - 0x10, 0xb6, 0x14, 0x50, 0xad, 0x35, 0xcd, 0x7b, 0xb4, 0x5c, 0x05, 0x00, 0xfb, 0x57, 0x21, 0x74, - 0x19, 0x26, 0xbe, 0xb4, 0xa7, 0xf0, 0xc5, 0x5c, 0x59, 0xd5, 0xe6, 0xc3, 0xa1, 0x2d, 0x87, 0x61, - 0x31, 0x1c, 0x9a, 0xb9, 0xca, 0xb4, 0x36, 0x50, 0xea, 0x6f, 0x19, 0x20, 0xd6, 0x88, 0x4f, 0xc7, - 0x23, 0x14, 0x6e, 0x34, 0x76, 0x06, 0xf6, 0xe3, 0xc1, 0x48, 0x7a, 0xca, 0x95, 0xcb, 0xda, 0xdd, - 0xd3, 0xa8, 0xed, 0xa2, 0x5b, 0x93, 0x00, 0x59, 0x09, 0x5e, 0x7c, 0x0e, 0x0e, 0xe9, 0x6d, 0xcd, - 0x92, 0x5e, 0xb2, 0xe5, 0x2f, 0xef, 0xa3, 0xdc, 0x92, 0xf9, 0x9c, 0xb3, 0xb6, 0x59, 0xc4, 0x2b, - 0x90, 0x8f, 0xa8, 0xbb, 0xe3, 0x67, 0xa2, 0x42, 0xb6, 0xfc, 0xd5, 0x7d, 0xec, 0x69, 0x73, 0x70, - 0xce, 0x59, 0xa9, 0x7c, 0xd5, 0x07, 0x60, 0xdf, 0x83, 0x0c, 0xaa, 0x5d, 0x70, 0x74, 0x0e, 0x7d, - 0x8f, 0xf6, 0xe1, 0x00, 0x5d, 0x20, 0x06, 0xe3, 0xa0, 0x78, 0x02, 0x1e, 0x05, 0x21, 0x89, 0xb0, - 0x87, 0x42, 0xe7, 0x0a, 0x21, 0x27, 0x20, 0x64, 0xe8, 0x40, 0xcf, 0x9b, 0xcf, 0xc2, 0x81, 0xf5, - 0x70, 0x79, 0x7a, 0x86, 0x50, 0x93, 0x90, 0x61, 0xc5, 0xf3, 0x42, 0x51, 0x02, 0x1f, 0x44, 0x28, - 0xa4, 0xb1, 0x65, 0x99, 0x24, 0x6b, 0xf9, 0xab, 0xbe, 0xca, 0x80, 0xfc, 0xae, 0x9a, 0x9d, 0xd2, - 0xbf, 0xe6, 0xc6, 0x8b, 0xbb, 0xdc, 0x78, 0xfa, 0x1e, 0x6e, 0x74, 0x4a, 0xff, 0x07, 0x3f, 0xfe, - 0xe4, 0xc1, 0xd1, 0x4e, 0x61, 0xff, 0xf1, 0x7b, 0xfc, 0x3e, 0xe5, 0x3d, 0x1e, 0xdf, 0xd7, 0xf9, - 0xfa, 0x4d, 0x26, 0x26, 0x6d, 0xa0, 0x8f, 0x7f, 0xe7, 0xc1, 0xa3, 0x74, 0x2f, 0xc5, 0x6f, 0x80, - 0x52, 0xbb, 0x6c, 0xd8, 0xed, 0x0b, 0xc3, 0x72, 0x9a, 0x95, 0xda, 0x0f, 0x46, 0xcb, 0x69, 0xbd, - 0x68, 0x1a, 0x4e, 0xbb, 0x61, 0x37, 0x8d, 0x9a, 0x79, 0x66, 0x1a, 0x75, 0x81, 0x93, 0x3f, 0x9e, - 0xce, 0x94, 0xa3, 0xb6, 0x4f, 0x03, 0xe4, 0xe2, 0x2b, 0xbc, 0xd4, 0x50, 0xd4, 0x81, 0x9c, 0x0a, - 0xb6, 0x9f, 0x55, 0xec, 0x73, 0x81, 0x97, 0x0f, 0xa7, 0x33, 0x25, 0xbb, 0x21, 0xac, 0x78, 0x02, - 0x3e, 0x49, 0x05, 0xc4, 0xae, 0x09, 0x19, 0x39, 0x3f, 0x9d, 0x29, 0x42, 0x67, 0xcb, 0x29, 0x79, - 0xff, 0xe7, 0x5f, 0x0b, 0xdc, 0xf1, 0x2b, 0x1e, 0xe4, 0x6e, 0xb7, 0x28, 0x9e, 0x82, 0xc7, 0x66, - 0xe3, 0xcc, 0xaa, 0xd4, 0x5a, 0xe6, 0x65, 0x23, 0xad, 0xec, 0x87, 0xd3, 0x99, 0x72, 0xb8, 0x06, - 0x19, 0xa3, 0x80, 0x4d, 0x44, 0x7d, 0x17, 0x55, 0xbf, 0x6c, 0x57, 0x9f, 0x19, 0x8e, 0x6d, 0x7e, - 0xd7, 0x10, 0x78, 0x39, 0x37, 0x9d, 0x29, 0xa0, 0x4e, 0xc6, 0xdd, 0x21, 0xb2, 0x71, 0xcf, 0x17, - 0x8f, 0x81, 0xb4, 0x0b, 0x78, 0xde, 0x68, 0x99, 0x17, 0x86, 0x90, 0x91, 0x3f, 0x9a, 0xce, 0x94, - 0x0f, 0xeb, 0xe4, 0xa5, 0xcf, 0xf0, 0x08, 0xcd, 0x6b, 0xad, 0x36, 0x5e, 0x5f, 0x17, 0xf8, 0x37, - 0xd7, 0x05, 0xfe, 0xaf, 0xeb, 0x02, 0xff, 0xcb, 0x4d, 0x81, 0x7b, 0x73, 0x53, 0xe0, 0xde, 0xde, - 0x14, 0xb8, 0x1f, 0x4f, 0x7b, 0x98, 0xf5, 0xc7, 0x5d, 0xcd, 0x25, 0x23, 0x7d, 0xb1, 0x78, 0xd7, - 0x96, 0x3e, 0x5d, 0xad, 0xf0, 0xe8, 0x54, 0xff, 0x29, 0xd9, 0xe3, 0xc9, 0x42, 0xed, 0x3e, 0x48, - 0x36, 0xea, 0xc9, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x4f, 0x03, 0x77, 0x3e, 0xef, 0x07, 0x00, - 0x00, + // 834 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x55, 0xcd, 0x6e, 0xdb, 0x46, + 0x10, 0x26, 0x65, 0x23, 0xad, 0x57, 0x85, 0x4c, 0x33, 0x6a, 0xc0, 0x32, 0xad, 0x42, 0x10, 0x2d, + 0x20, 0xb8, 0x08, 0x59, 0xc9, 0xe9, 0xa5, 0xbd, 0x54, 0x3f, 0x74, 0xcd, 0x36, 0x96, 0x05, 0x52, + 0x52, 0x90, 0x5e, 0x88, 0x15, 0xb9, 0x96, 0x16, 0x92, 0xb8, 0x04, 0x77, 0xc5, 0x54, 0x6f, 0x50, + 0xe8, 0xd4, 0x17, 0xd0, 0xa9, 0xe8, 0x21, 0x8f, 0xd1, 0x5b, 0x8e, 0x01, 0x7a, 0xc9, 0xa5, 0x41, + 0x61, 0xbf, 0x41, 0x9f, 0xa0, 0x20, 0xf5, 0x6b, 0x89, 0x36, 0x10, 0xa0, 0x40, 0x73, 0x23, 0x67, + 0xe7, 0xfb, 0x76, 0xe6, 0xfb, 0x66, 0x31, 0xe0, 0x0b, 0xec, 0x33, 0x14, 0xba, 0x7d, 0x88, 0x7d, + 0x87, 0x22, 0x77, 0x1c, 0x62, 0x36, 0xd1, 0x5d, 0x37, 0xd2, 0xa3, 0x92, 0xfe, 0x02, 0x87, 0x48, + 0x0b, 0x42, 0xc2, 0x88, 0x28, 0xa7, 0xa4, 0x69, 0xae, 0x1b, 0x69, 0x51, 0x49, 0xfe, 0xdc, 0x25, + 0x74, 0x44, 0xa8, 0x4e, 0x19, 0x1c, 0x60, 0xbf, 0xa7, 0x47, 0xa5, 0x2e, 0x62, 0xb0, 0xb4, 0xfc, + 0x9f, 0x33, 0xc8, 0xf9, 0x1e, 0xe9, 0x91, 0xe4, 0x53, 0x8f, 0xbf, 0x16, 0xd1, 0x87, 0x0c, 0xf9, + 0x1e, 0x0a, 0x47, 0xd8, 0x67, 0x3a, 0xec, 0xba, 0x58, 0x67, 0x93, 0x00, 0xd1, 0xf9, 0xa1, 0xfa, + 0x86, 0x07, 0x9f, 0x76, 0xe0, 0x10, 0x7b, 0x90, 0x91, 0xd0, 0x46, 0xac, 0xd6, 0x87, 0x7e, 0x0f, + 0x35, 0xa1, 0x3b, 0x40, 0xac, 0x0e, 0x19, 0x14, 0x09, 0x38, 0x8a, 0x96, 0xe7, 0xce, 0x38, 0xf0, + 0x20, 0x43, 0x54, 0xe2, 0x95, 0xbd, 0x62, 0xb6, 0xac, 0x68, 0x6b, 0x66, 0x2d, 0x66, 0xd6, 0x56, + 0x4c, 0xed, 0x24, 0xb1, 0xaa, 0xbc, 0x7a, 0xfb, 0x88, 0xfb, 0xe7, 0xed, 0x23, 0x69, 0x02, 0x47, + 0xc3, 0x6f, 0xd4, 0x1d, 0x22, 0xd5, 0x12, 0xa2, 0x9b, 0x10, 0x2a, 0x16, 0x41, 0x1c, 0xa3, 0x88, + 0x2d, 0x92, 0x1c, 0xec, 0x49, 0x19, 0x85, 0x2f, 0xee, 0x5b, 0xb9, 0x79, 0x7c, 0x9e, 0x68, 0x7a, + 0xe2, 0x67, 0x00, 0xd0, 0x21, 0xa4, 0x7d, 0x07, 0xba, 0x03, 0x2a, 0xed, 0x29, 0x7b, 0xc5, 0x03, + 0xeb, 0x20, 0x89, 0x54, 0xdc, 0x01, 0x55, 0xbf, 0x03, 0xf9, 0x8e, 0x5d, 0x3b, 0x87, 0x6c, 0x1c, + 0x22, 0x6f, 0xa3, 0xa3, 0xb4, 0x0b, 0xf8, 0xb4, 0x0b, 0xd4, 0x3f, 0x79, 0x70, 0x68, 0xc7, 0x7c, + 0x1b, 0x68, 0x0b, 0x1c, 0xac, 0x4a, 0x4e, 0x60, 0xd9, 0xb2, 0x7c, 0xbb, 0x0e, 0x55, 0x69, 0xa1, + 0x80, 0xb0, 0xa5, 0x80, 0x6a, 0xad, 0x69, 0xde, 0xa1, 0xe5, 0x2a, 0x00, 0xd8, 0xbf, 0x0c, 0xa1, + 0xcb, 0x30, 0xf1, 0xa5, 0x3d, 0x85, 0x2f, 0xe6, 0xca, 0xaa, 0x36, 0x1f, 0x0e, 0x6d, 0x39, 0x0c, + 0x8b, 0xe1, 0xd0, 0xcc, 0x55, 0xa6, 0xb5, 0x81, 0x52, 0x7f, 0xcf, 0x00, 0xb1, 0x46, 0x7c, 0x3a, + 0x1e, 0xa1, 0x70, 0xa3, 0xb1, 0x53, 0xb0, 0x1f, 0x0f, 0x46, 0xd2, 0x53, 0xae, 0x5c, 0xd6, 0x6e, + 0x9f, 0x46, 0x6d, 0x17, 0xdd, 0x9a, 0x04, 0xc8, 0x4a, 0xf0, 0xe2, 0x33, 0x70, 0x48, 0x6f, 0x6a, + 0x96, 0xf4, 0x92, 0x2d, 0x7f, 0x79, 0x17, 0xe5, 0x96, 0xcc, 0x67, 0x9c, 0xb5, 0xcd, 0x22, 0x5e, + 0x82, 0x7c, 0x44, 0xdd, 0x1d, 0x3f, 0x13, 0x15, 0xb2, 0xe5, 0xaf, 0xee, 0x62, 0x4f, 0x9b, 0x83, + 0x33, 0xce, 0x4a, 0xe5, 0xab, 0xde, 0x03, 0xfb, 0x1e, 0x64, 0x50, 0xed, 0x82, 0xa3, 0x33, 0xe8, + 0x7b, 0xb4, 0x0f, 0x07, 0xe8, 0x1c, 0x31, 0x18, 0x07, 0xc5, 0x13, 0xf0, 0x20, 0x08, 0x49, 0x84, + 0x3d, 0x14, 0x3a, 0x97, 0x08, 0x39, 0x01, 0x21, 0x43, 0x07, 0x7a, 0xde, 0x7c, 0x16, 0x0e, 0xac, + 0xfb, 0xcb, 0xd3, 0x53, 0x84, 0x9a, 0x84, 0x0c, 0x2b, 0x9e, 0x17, 0x8a, 0x12, 0xf8, 0x20, 0x42, + 0x21, 0x8d, 0x2d, 0xcb, 0x24, 0x59, 0xcb, 0x5f, 0xf5, 0x65, 0x06, 0xe4, 0x77, 0xd5, 0xec, 0x94, + 0xfe, 0x33, 0x37, 0x9e, 0xdf, 0xe6, 0xc6, 0xe3, 0x77, 0x70, 0xa3, 0x53, 0x7a, 0x1f, 0xfc, 0xf8, + 0x8b, 0x07, 0x47, 0x3b, 0x85, 0xfd, 0xcf, 0xef, 0xf1, 0x87, 0x94, 0xf7, 0x78, 0x7c, 0x57, 0xe7, + 0xeb, 0x37, 0x99, 0x98, 0xb4, 0x81, 0x3e, 0xfe, 0x83, 0x07, 0x0f, 0xd2, 0xbd, 0x14, 0xbf, 0x05, + 0x4a, 0xed, 0xa2, 0x61, 0xb7, 0xcf, 0x0d, 0xcb, 0x69, 0x56, 0x6a, 0x3f, 0x1a, 0x2d, 0xa7, 0xf5, + 0xbc, 0x69, 0x38, 0xed, 0x86, 0xdd, 0x34, 0x6a, 0xe6, 0xa9, 0x69, 0xd4, 0x05, 0x4e, 0xfe, 0x78, + 0x3a, 0x53, 0x8e, 0xda, 0x3e, 0x0d, 0x90, 0x8b, 0x2f, 0xf1, 0x52, 0x43, 0x51, 0x07, 0x72, 0x2a, + 0xd8, 0x7e, 0x5a, 0xb1, 0xcf, 0x04, 0x5e, 0x3e, 0x9c, 0xce, 0x94, 0xec, 0x86, 0xb0, 0xe2, 0x09, + 0xf8, 0x24, 0x15, 0x10, 0xbb, 0x26, 0x64, 0xe4, 0xfc, 0x74, 0xa6, 0x08, 0x9d, 0x2d, 0xa7, 0xe4, + 0xfd, 0x5f, 0x7e, 0x2b, 0x70, 0xc7, 0x2f, 0x79, 0x90, 0xbb, 0xd9, 0xa2, 0xf8, 0x04, 0x3c, 0x34, + 0x1b, 0xa7, 0x56, 0xa5, 0xd6, 0x32, 0x2f, 0x1a, 0x69, 0x65, 0xdf, 0x9f, 0xce, 0x94, 0xc3, 0x35, + 0xc8, 0x18, 0x05, 0x6c, 0x22, 0xea, 0xbb, 0xa8, 0xfa, 0x45, 0xbb, 0xfa, 0xd4, 0x70, 0x6c, 0xf3, + 0xfb, 0x86, 0xc0, 0xcb, 0xb9, 0xe9, 0x4c, 0x01, 0x75, 0x32, 0xee, 0x0e, 0x91, 0x8d, 0x7b, 0xbe, + 0x78, 0x0c, 0xa4, 0x5d, 0xc0, 0xb3, 0x46, 0xcb, 0x3c, 0x37, 0x84, 0x8c, 0xfc, 0xd1, 0x74, 0xa6, + 0x7c, 0x58, 0x27, 0x2f, 0x7c, 0x86, 0x47, 0x68, 0x5e, 0x6b, 0xb5, 0xf1, 0xea, 0xaa, 0xc0, 0xbf, + 0xbe, 0x2a, 0xf0, 0x7f, 0x5f, 0x15, 0xf8, 0x5f, 0xaf, 0x0b, 0xdc, 0xeb, 0xeb, 0x02, 0xf7, 0xe6, + 0xba, 0xc0, 0xfd, 0xf4, 0xa4, 0x87, 0x59, 0x7f, 0xdc, 0xd5, 0x5c, 0x32, 0xd2, 0x17, 0x8b, 0x77, + 0x6d, 0xe9, 0xe3, 0xd5, 0x0a, 0x8f, 0xbe, 0xd6, 0x7f, 0x4e, 0xf6, 0x78, 0xb2, 0x50, 0xbb, 0xf7, + 0x92, 0x8d, 0x7a, 0xf2, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd1, 0x80, 0xad, 0xa1, 0xef, 0x07, + 0x00, 0x00, } func (m *ValidatorSetChangePacketData) Marshal() (dAtA []byte, err error) { diff --git a/x/ccv/types/wire_test.go b/x/ccv/types/wire_test.go index ab6692912e..93512a5218 100644 --- a/x/ccv/types/wire_test.go +++ b/x/ccv/types/wire_test.go @@ -12,8 +12,8 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/cosmos/interchain-security/v4/testutil/crypto" - "github.com/cosmos/interchain-security/v4/x/ccv/types" + "github.com/cosmos/interchain-security/v5/testutil/crypto" + "github.com/cosmos/interchain-security/v5/x/ccv/types" ) func TestPacketDataValidateBasic(t *testing.T) { From 781f691e7f89b3b7d560b2dbf6fe4e92fa9cd4bd Mon Sep 17 00:00:00 2001 From: MSalopek Date: Tue, 23 Apr 2024 12:01:40 +0200 Subject: [PATCH 03/35] tests: fix broken tests (unit, integration) (#1805) * proto: update proto files (rm deprecated from non-deprecated) * test: update parts of integration tests * app: add missing addr codec registrations * tests: disable cometmock tests in GH * integration test: revert setup to main branch * integration test: fix add consumern; fix consumer key assign * integration: fix most tests; add todos * chore: add todos for fixing tests * fix packet timeout related test * fix TestRewardsDistribution test * fix val address conversion * fix democracy tests * fix TestSoftOptOut * fix historical info test * fixed TestRelayAndApplyDowntimePacket * tests: fix double voting tests * tests: update some comments * fix: switch broken UT due to addr parsing --------- Co-authored-by: stana-ethernal --- .github/workflows/test.yml | 31 --- app/provider/app.go | 12 +- app/sovereign/app.go | 8 +- .../ccv/provider/v1/provider.proto | 9 +- tests/integration/common.go | 7 +- tests/integration/democracy.go | 81 ++++--- tests/integration/distribution.go | 24 +- tests/integration/double_vote.go | 7 +- tests/integration/expired_client.go | 3 +- tests/integration/normal_operations.go | 36 +-- tests/integration/setup.go | 26 +- tests/integration/slashing.go | 105 +++++++- tests/integration/soft_opt_out.go | 4 +- tests/integration/throttle.go | 28 ++- tests/integration/throttle_retry.go | 8 +- testutil/ibc_testing/generic_setup.go | 11 +- testutil/integration/validators.go | 4 +- x/ccv/consumer/keeper/validators.go | 4 +- x/ccv/provider/keeper/relay_test.go | 6 +- x/ccv/provider/keeper/throttle.go | 3 +- x/ccv/provider/types/provider.pb.go | 226 +++++++++--------- 21 files changed, 368 insertions(+), 275 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cb6e0255b9..40bf4002c1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -229,37 +229,6 @@ jobs: run: | make test-e2e-compatibility-tests-latest - test-cometmock: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - lfs: true - - name: checkout LFS objects - run: git lfs checkout - - uses: actions/setup-go@v5 - with: - go-version: "1.21" - check-latest: true - cache: true - cache-dependency-path: go.sum - - uses: technote-space/get-diff-action@v6.1.2 - id: git_diff - with: - PATTERNS: | - **/*.go - go.mod - go.sum - **/go.mod - **/go.sum - **/Makefile - Makefile - Dockerfile* - - name: cometmock tests - if: env.GIT_DIFF - run: | - make test-e2e-short-cometmock - test-trace: runs-on: ubuntu-latest steps: diff --git a/app/provider/app.go b/app/provider/app.go index ef60ccc53b..42a3b99f90 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -343,8 +343,8 @@ func New( runtime.NewKVStoreService(keys[authtypes.StoreKey]), authtypes.ProtoBaseAccount, maccPerms, - authcodec.NewBech32Codec(sdk.Bech32MainPrefix), - sdk.Bech32MainPrefix, + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), + sdk.GetConfig().GetBech32AccountAddrPrefix(), authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) @@ -370,8 +370,8 @@ func New( app.AccountKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), - authcodec.NewBech32Codec(sdk.Bech32PrefixValAddr), - authcodec.NewBech32Codec(sdk.Bech32PrefixConsAddr), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), ) app.MintKeeper = mintkeeper.NewKeeper( appCodec, @@ -485,8 +485,8 @@ func New( app.BankKeeper, *app.GovKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), - authcodec.NewBech32Codec(sdk.Bech32PrefixValAddr), - authcodec.NewBech32Codec(sdk.Bech32PrefixConsAddr), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), authtypes.FeeCollectorName, ) diff --git a/app/sovereign/app.go b/app/sovereign/app.go index ae5a2a82f6..67386cc70a 100644 --- a/app/sovereign/app.go +++ b/app/sovereign/app.go @@ -304,8 +304,8 @@ func New( runtime.NewKVStoreService(keys[authtypes.StoreKey]), authtypes.ProtoBaseAccount, maccPerms, - authcodec.NewBech32Codec(sdk.Bech32MainPrefix), - sdk.Bech32MainPrefix, + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), + sdk.GetConfig().GetBech32AccountAddrPrefix(), authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) @@ -338,8 +338,8 @@ func New( app.AccountKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), - authcodec.NewBech32Codec(sdk.Bech32PrefixValAddr), - authcodec.NewBech32Codec(sdk.Bech32PrefixConsAddr), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), ) app.MintKeeper = mintkeeper.NewKeeper( diff --git a/proto/interchain_security/ccv/provider/v1/provider.proto b/proto/interchain_security/ccv/provider/v1/provider.proto index 936a7eeb5b..3784c2cc13 100644 --- a/proto/interchain_security/ccv/provider/v1/provider.proto +++ b/proto/interchain_security/ccv/provider/v1/provider.proto @@ -25,9 +25,8 @@ import "cosmos_proto/cosmos.proto"; // chain are expected to validate the consumer chain at spawn time or get // slashed. It is recommended that spawn time occurs after the proposal end // time. -// Deprecated: Use MsgConsumerAddition instead +// Use MsgConsumerAddition to submit this proposal type. message ConsumerAdditionProposal { - option deprecated = true; option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_stringer) = false; option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; @@ -93,9 +92,8 @@ message ConsumerAdditionProposal { // remove (and stop) a consumer chain. If it passes, all the consumer chain's // state is removed from the provider chain. The outstanding unbonding operation // funds are released. -// Deprecated: Use MsgConsumerRemoval instead +// Use MsgConsumerRemoval to submit this proposal type. message ConsumerRemovalProposal { - option deprecated = true; option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; // the title of the proposal @@ -128,9 +126,8 @@ message EquivocationProposal { // ChangeRewardDenomsProposal is a governance proposal on the provider chain to // mutate the set of denoms accepted by the provider as rewards. -// Deprecated: Use MsgChangeRewardDenoms instead +// Use MsgChangeRewardDenoms to submit this proposal type. message ChangeRewardDenomsProposal { - option deprecated = true; option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content"; // the title of the proposal diff --git a/tests/integration/common.go b/tests/integration/common.go index 4858c376e2..195326e8ff 100644 --- a/tests/integration/common.go +++ b/tests/integration/common.go @@ -275,7 +275,7 @@ func relayAllCommittedPackets( s.Require().Equal( expectedPackets, len(commitments), - fmt.Sprintf("actual number of packet commitments does not match expectation; %s", msgAndArgs...), + fmt.Sprintf("actual number of packet commitments does not match expectation; expected: %d - got: %d", expectedPackets, len(commitments)), ) // relay all packets from srcChain to counterparty @@ -290,7 +290,7 @@ func relayAllCommittedPackets( err := path.RelayPacket(packet) s.Require().NoError( err, - fmt.Sprintf("error while relaying packets; %s", msgAndArgs...), + fmt.Sprintf("error while relaying packets; %v", err), ) } } @@ -371,10 +371,9 @@ func checkRedelegationEntryCompletionTime( } func getStakingUnbondingDelegationEntry(ctx sdk.Context, k testutil.TestStakingKeeper, id uint64) (stakingUnbondingOp stakingtypes.UnbondingDelegationEntry, found bool) { - found := false stakingUbd, err := k.GetUnbondingDelegationByUnbondingID(ctx, id) if err != nil { - return found + return } for _, entry := range stakingUbd.Entries { diff --git a/tests/integration/democracy.go b/tests/integration/democracy.go index 63ca348bf8..100018879d 100644 --- a/tests/integration/democracy.go +++ b/tests/integration/democracy.go @@ -30,7 +30,7 @@ type ConsumerDemocracyTestSuite struct { setupCallback DemocSetupCallback } -// NewCCVTestSuite returns a new instance of ConsumerDemocracyTestSuite, +// NewConsumerDemocracyTestSuite returns a new instance of ConsumerDemocracyTestSuite, // ready to be tested against using suite.Run(). func NewConsumerDemocracyTestSuite[T testutil.DemocConsumerApp]( democConsumerAppIniter icstestingutils.ValSetAppIniter, @@ -80,41 +80,53 @@ func (s *ConsumerDemocracyTestSuite) TestDemocracyRewardsDistribution() { bondDenom, err := stakingKeeper.BondDenom(s.consumerCtx()) s.Require().NoError(err) - currentRepresentativesRewards := map[string]math.LegacyDec{} + previousRepresentativesRewards := map[string]math.LegacyDec{} nextRepresentativesRewards := map[string]math.LegacyDec{} representativesTokens := map[string]math.Int{} representatives, err := stakingKeeper.GetAllValidators(s.consumerCtx()) s.Require().NoError(err) for _, representative := range representatives { - currentRepresentativesRewards[representative.OperatorAddress] = math.LegacyNewDec(0) + previousRepresentativesRewards[representative.OperatorAddress] = math.LegacyNewDec(0) nextRepresentativesRewards[representative.OperatorAddress] = math.LegacyNewDec(0) representativesTokens[representative.OperatorAddress] = representative.GetTokens() } distrModuleAccount := distrKeeper.GetDistributionAccount(s.consumerCtx()) providerRedistributeAccount := accountKeeper.GetModuleAccount(s.consumerCtx(), consumertypes.ConsumerToSendToProviderName) - // balance of consumer redistribute address will always be 0 when checked between 2 NextBlock() calls + consumerRedistributeAccount := accountKeeper.GetModuleAccount(s.consumerCtx(), consumertypes.ConsumerRedistributeName) dk, ok := distrKeeper.(sdkdistrkeeper.Keeper) s.Require().True(ok) - feePool, err := dk.FeePool.Get(s.consumerCtx().Context()) + feePool, err := dk.FeePool.Get(s.consumerCtx()) s.Require().NoError(err) s.Require().NotEmpty(feePool) - currentDistrModuleAccountBalance := math.LegacyNewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), distrModuleAccount.GetAddress(), bondDenom).Amount) - currentProviderFeeAccountBalance := math.LegacyNewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), providerRedistributeAccount.GetAddress(), bondDenom).Amount) - currentCommunityPoolBalance := feePool.GetCommunityPool().AmountOf(bondDenom) - for key := range currentRepresentativesRewards { + + // take balance of relevant accounts before advancing to the next block + previousDistrModuleAccountBalance := math.LegacyNewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), distrModuleAccount.GetAddress(), bondDenom).Amount) + previousProviderFeeAccountBalance := math.LegacyNewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), providerRedistributeAccount.GetAddress(), bondDenom).Amount) + previousConsumerRedistributeBalance := math.LegacyNewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), consumerRedistributeAccount.GetAddress(), bondDenom).Amount) + previousCommunityPoolBalance := feePool.GetCommunityPool().AmountOf(bondDenom) + for key := range previousRepresentativesRewards { representativeAddr, _ := sdk.ValAddressFromBech32(key) representativeReward, err := distrKeeper.GetValidatorOutstandingRewards(s.consumerCtx(), representativeAddr) s.Require().NoError(err) - currentRepresentativesRewards[key] = representativeReward.Rewards.AmountOf(bondDenom) + previousRepresentativesRewards[key] = representativeReward.Rewards.AmountOf(bondDenom) } + // NextBlock will call the begin block and end block, respectively. Democracy module in the begin blocker sends the tokens from + // the consumer redistribute address to the distribution module, giving representatives and community fee pool its portion of rewards. + // Consumer module in endblocker, sends the fees from fee collector(auth module) to the consumer redistribute address and to + // provider rewards address s.consumerChain.NextBlock() + // take balance of relevant accounts after new block is created nextDistrModuleAccountBalance := math.LegacyNewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), distrModuleAccount.GetAddress(), bondDenom).Amount) nextProviderFeeAccountBalance := math.LegacyNewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), providerRedistributeAccount.GetAddress(), bondDenom).Amount) + nextConsumerRedistributeBalance := math.LegacyNewDecFromInt(bankKeeper.GetBalance(s.consumerCtx(), consumerRedistributeAccount.GetAddress(), bondDenom).Amount) + feePool, err = dk.FeePool.Get(s.consumerCtx()) + s.Require().NoError(err) + s.Require().NotEmpty(feePool) nextCommunityPoolBalance := feePool.GetCommunityPool().AmountOf(bondDenom) for key := range nextRepresentativesRewards { representativeAddr, _ := sdk.ValAddressFromBech32(key) @@ -123,41 +135,44 @@ func (s *ConsumerDemocracyTestSuite) TestDemocracyRewardsDistribution() { nextRepresentativesRewards[key] = representativeReward.Rewards.AmountOf(bondDenom) } - distrModuleDifference := nextDistrModuleAccountBalance.Sub(currentDistrModuleAccountBalance) - providerDifference := nextProviderFeeAccountBalance.Sub(currentProviderFeeAccountBalance) - communityPoolDifference := nextCommunityPoolBalance.Sub(currentCommunityPoolBalance) + distrModuleDifference := nextDistrModuleAccountBalance.Sub(previousDistrModuleAccountBalance) + providerDifference := nextProviderFeeAccountBalance.Sub(previousProviderFeeAccountBalance) + communityPoolDifference := nextCommunityPoolBalance.Sub(previousCommunityPoolBalance) representativeDifference := map[string]math.LegacyDec{} - consumerRedistributeDifference := communityPoolDifference - - for key, currentReward := range currentRepresentativesRewards { - representativeDifference[key] = nextRepresentativesRewards[key].Sub(currentReward) - consumerRedistributeDifference = consumerRedistributeDifference.Add(representativeDifference[key]) + totalRepresentativeDifference := math.LegacyZeroDec() + for key, currentReward := range previousRepresentativesRewards { + diff := nextRepresentativesRewards[key].Sub(currentReward) + representativeDifference[key] = diff + totalRepresentativeDifference = totalRepresentativeDifference.Add(diff) } + // confirm endblocker changes: consumer module distributes fees from fee collector to consumer redistribute address + // and address aimed for provider rewards consumerRedistributionFraction := math.LegacyMustNewDecFromStr(s.consumerApp.GetConsumerKeeper().GetConsumerRedistributionFrac(s.consumerCtx())) - - // confirm that the total amount given to the community pool plus all representatives is equal to the total amount taken out of distribution - s.Require().Equal(distrModuleDifference, consumerRedistributeDifference) + // since we cannot know the balance of the fee collector when the consumer module transfers the fees, we can only calculate the total fees + // as a sum of the provider and consumer rewards and check if the reward is distributed in the expected proportion + totalFees := nextConsumerRedistributeBalance.Add(providerDifference) + s.Require().Equal(totalFees.Mul(consumerRedistributionFraction), nextConsumerRedistributeBalance) + + // confirm begin blocker changes: democracy module distributes the fees from c onsumer redistribute address to representatives + // and community fee pool + // distribution module got tokens from previous consumer redistribute balance + s.Require().Equal(distrModuleDifference, previousConsumerRedistributeBalance) // confirm that the percentage given to the community pool is equal to the configured community tax percentage. tax, err := distrKeeper.GetCommunityTax(s.consumerCtx()) s.Require().NoError(err) - s.Require().Equal(communityPoolDifference.Quo(consumerRedistributeDifference), tax) - // check that the fraction actually kept by the consumer is the correct fraction. using InEpsilon because the math code uses truncations - s.Require().InEpsilon(distrModuleDifference.Quo( - providerDifference.Add(distrModuleDifference)).MustFloat64(), - consumerRedistributionFraction.MustFloat64(), float64(0.0001)) - // check that the fraction actually kept by the provider is the correct fraction. using InEpsilon because the math code uses truncations - s.Require().InEpsilon(providerDifference.Quo( - providerDifference.Add(distrModuleDifference)).MustFloat64(), - math.LegacyNewDec(1).Sub(consumerRedistributionFraction).MustFloat64(), float64(0.0001)) + s.Require().Equal(communityPoolDifference.Quo(previousConsumerRedistributeBalance), tax) + // confirm that the total amount given to the community pool plus all representatives is equal to the previous consumer redistribute balance + s.Require().Equal(previousConsumerRedistributeBalance, communityPoolDifference.Add(totalRepresentativeDifference)) + + // check that each representative has gotten the correct amount of rewards totalRepresentativePower, err := stakingKeeper.GetValidatorSet().TotalBondedTokens(s.consumerCtx()) s.Require().NoError(err) - // check that each representative has gotten the correct amount of rewards for key, representativeTokens := range representativesTokens { powerFraction := math.LegacyNewDecFromInt(representativeTokens).QuoTruncate(math.LegacyNewDecFromInt(totalRepresentativePower)) - s.Require().Equal(powerFraction, representativeDifference[key].Quo(consumerRedistributeDifference.Sub(communityPoolDifference))) + s.Require().Equal(powerFraction, representativeDifference[key].Quo(previousConsumerRedistributeBalance.Sub(communityPoolDifference))) } } @@ -203,7 +218,6 @@ func (s *ConsumerDemocracyTestSuite) TestDemocracyGovernanceWhitelisting() { // set current header time to be equal or later than voting end time in order to process proposal from active queue, // once the proposal is added to the chain s.consumerChain.CurrentHeader.Time = s.consumerChain.CurrentHeader.Time.Add(*params.VotingPeriod) - s.consumerChain.NextBlock() // at this moment, proposal is added, but not yet executed. we are saving old param values for comparison oldAuthParamValue := accountKeeper.GetParams(s.consumerCtx()).MaxMemoCharacters oldMintParams, err := mintKeeper.Params.Get(s.consumerCtx()) @@ -227,7 +241,6 @@ func (s *ConsumerDemocracyTestSuite) TestDemocracyGovernanceWhitelisting() { err = submitProposalWithDepositAndVote(govKeeper, s.consumerCtx(), []sdk.Msg{msg_1}, votingAccounts, proposer.GetAddress(), depositAmount) s.Assert().NoError(err) s.consumerChain.CurrentHeader.Time = s.consumerChain.CurrentHeader.Time.Add(*params.VotingPeriod) - s.consumerChain.NextBlock() oldMintParam, err := mintKeeper.Params.Get(s.consumerCtx()) s.Require().NoError(err) oldMintParamValue = oldMintParam.InflationMax diff --git a/tests/integration/distribution.go b/tests/integration/distribution.go index c33ddada0a..13bf150938 100644 --- a/tests/integration/distribution.go +++ b/tests/integration/distribution.go @@ -36,8 +36,7 @@ func (s *CCVTestSuite) TestRewardsDistribution() { relayAllCommittedPackets(s, s.providerChain, s.path, ccv.ProviderPortID, s.path.EndpointB.ChannelID, 1) // reward for the provider chain will be sent after each 2 blocks - consumerParams := s.consumerApp.GetSubspace(consumertypes.ModuleName) - consumerParams.Set(s.consumerCtx(), ccv.KeyBlocksPerDistributionTransmission, int64(2)) + s.consumerApp.GetConsumerKeeper().SetBlocksPerDistributionTransmission(s.consumerCtx(), 2) s.consumerChain.NextBlock() consumerAccountKeeper := s.consumerApp.GetTestAccountKeeper() @@ -85,6 +84,7 @@ func (s *CCVTestSuite) TestRewardsDistribution() { rewardCoins := providerBankKeeper.GetAllBalances(s.providerCtx(), rewardPool) ibcCoinIndex := -1 + for i, coin := range rewardCoins { if strings.HasPrefix(coin.Denom, "ibc") { ibcCoinIndex = i @@ -93,6 +93,7 @@ func (s *CCVTestSuite) TestRewardsDistribution() { // Check that we found an ibc denom in the reward pool s.Require().Greater(ibcCoinIndex, -1) + ibcDenom := rewardCoins[ibcCoinIndex].Denom // Check that the coins got into the ConsumerRewardsPool s.Require().True(rewardCoins[ibcCoinIndex].Amount.Equal(providerExpectedRewards[0].Amount)) @@ -103,13 +104,20 @@ func (s *CCVTestSuite) TestRewardsDistribution() { s.Require().True(rewardCoins[ibcCoinIndex].Amount.Equal(providerExpectedRewards[0].Amount)) // Set the consumer reward denom. This would be done by a governance proposal in prod - s.providerApp.GetProviderKeeper().SetConsumerRewardDenom(s.providerCtx(), rewardCoins[ibcCoinIndex].Denom) + s.providerApp.GetProviderKeeper().SetConsumerRewardDenom(s.providerCtx(), ibcDenom) s.providerChain.NextBlock() - // Check that the reward pool has no more coins because they were transferred to the fee pool + // Check that the reward pool has no more coins because they were transferred to the fee collector rewardCoins = providerBankKeeper.GetAllBalances(s.providerCtx(), rewardPool) s.Require().Equal(0, len(rewardCoins)) + feeCollectorIbcCoin := providerBankKeeper.GetBalance(s.providerCtx(), authtypes.NewModuleAddress(authtypes.FeeCollectorName), ibcDenom) + s.Require().True(feeCollectorIbcCoin.Amount.Equal(providerExpectedRewards[0].Amount)) + + // Advance a block and check that the coins are transfered from fee collector to fee pool + s.providerChain.NextBlock() + feeCollectorIbcCoin = providerBankKeeper.GetBalance(s.providerCtx(), authtypes.NewModuleAddress(authtypes.FeeCollectorName), ibcDenom) + s.Require().Equal(math.ZeroInt(), feeCollectorIbcCoin.Amount) // check that the fee pool has the expected amount of coins testDistKeeper := s.providerApp.GetTestDistributionKeeper() @@ -118,7 +126,7 @@ func (s *CCVTestSuite) TestRewardsDistribution() { s.Require().True(ok) s.Require().NotEmpty(sdkDistKeeper) - feePool, err := sdkDistKeeper.FeePool.Get(s.consumerCtx().Context()) + feePool, err := sdkDistKeeper.FeePool.Get(s.providerCtx()) s.Require().NoError(err) s.Require().NotEmpty(feePool) @@ -150,8 +158,7 @@ func (s *CCVTestSuite) TestSendRewardsRetries() { consumerKeeper := s.consumerApp.GetConsumerKeeper() // reward for the provider chain will be sent after each 1000 blocks - consumerParams := s.consumerApp.GetSubspace(consumertypes.ModuleName) - consumerParams.Set(s.consumerCtx(), ccv.KeyBlocksPerDistributionTransmission, int64(1000)) + s.consumerApp.GetConsumerKeeper().SetBlocksPerDistributionTransmission(s.consumerCtx(), 1000) // fill fee pool fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100))) @@ -280,8 +287,7 @@ func (s *CCVTestSuite) TestEndBlockRD() { consumerBankKeeper := s.consumerApp.GetTestBankKeeper() // reward for the provider chain will be sent after each 1000 blocks - consumerParams := s.consumerApp.GetSubspace(consumertypes.ModuleName) - consumerParams.Set(s.consumerCtx(), ccv.KeyBlocksPerDistributionTransmission, int64(1000)) + s.consumerApp.GetConsumerKeeper().SetBlocksPerDistributionTransmission(s.consumerCtx(), 1000) // fill fee pool fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100))) diff --git a/tests/integration/double_vote.go b/tests/integration/double_vote.go index 9ebd4b727f..f8a0f7f25d 100644 --- a/tests/integration/double_vote.go +++ b/tests/integration/double_vote.go @@ -264,6 +264,8 @@ func (s *CCVTestSuite) TestHandleConsumerDoubleVotingSlashesUndelegationsAndRele // required to have the consumer client revision height greater than 0 s.SendEmptyVSCPacket() + providerKeeper := s.providerApp.GetProviderKeeper() + // create signing info for all validators for _, v := range s.providerChain.Vals.Validators { s.setDefaultValSigningInfo(*v) @@ -349,7 +351,7 @@ func (s *CCVTestSuite) TestHandleConsumerDoubleVotingSlashesUndelegationsAndRele s.Require().NotZero(shares) // undelegate 1/2 of the bound amount - valAddr, err := sdk.ValAddressFromHex(validator.GetOperator()) + valAddr, err := providerKeeper.ValidatorAddressCodec().StringToBytes(validator.GetOperator()) s.Require().NoError(err) undelegate(s, delAddr, valAddr, shares.Quo(math.LegacyNewDec(4))) undelegate(s, delAddr, valAddr, shares.Quo(math.LegacyNewDec(4))) @@ -361,7 +363,8 @@ func (s *CCVTestSuite) TestHandleConsumerDoubleVotingSlashesUndelegationsAndRele // save the delegation shares of the validator to redelegate to // Note this shares should not be slashed! - valAddr2, err := sdk.ValAddressFromHex(validator2.GetOperator()) + valAddr2, err := providerKeeper.ValidatorAddressCodec().StringToBytes(validator2.GetOperator()) + s.Require().NoError(err) del, err := s.providerApp.GetTestStakingKeeper().Delegation(s.providerCtx(), delAddr, valAddr2) s.Require().NoError(err) delShares := del.GetShares() diff --git a/tests/integration/expired_client.go b/tests/integration/expired_client.go index 249283ce9f..253f37c9fd 100644 --- a/tests/integration/expired_client.go +++ b/tests/integration/expired_client.go @@ -1,4 +1,4 @@ -gpackage integration +package integration import ( "time" @@ -291,4 +291,5 @@ func upgradeExpiredClient(s *CCVTestSuite, clientTo ChainType) { res, err := hostChain.App.GetIBCKeeper().RecoverClient(hostChain.GetContext(), recoverMsg) s.Require().NoError(err) + s.Require().NotNil(res) } diff --git a/tests/integration/normal_operations.go b/tests/integration/normal_operations.go index 61f7507793..fc71fec247 100644 --- a/tests/integration/normal_operations.go +++ b/tests/integration/normal_operations.go @@ -35,14 +35,16 @@ func (k CCVTestSuite) TestHistoricalInfo() { //nolint:govet // this is a test so // testsetup create 2 validators and then call track historical info with header block height // increased by HistoricalEntries in order to prune the historical info less or equal to the current block height - // Note that historical info containing the created validators are stored during the next block BeginBlocker - // and thus are indexed with the respective block heights InitHeight+1 and InitHeight+2 + // Note that historical info containing the created validators were stored during the BeginBlocker of the current block + // at the moment of creation and thus are indexed with the respective block heights InitHeight and InitHeight+1 + // Last saved historical info was in the last commited block k.consumerChain.GetContext().BlockHeight(), meaning that + // if we want to prune old entries we need to start from the last saved historical info which is k.consumerChain.GetContext().BlockHeight() - 1 testSetup := []func(CCVTestSuite){ createVal, createVal, func(k CCVTestSuite) { //nolint:govet // this is a test so we can copy locks historicalEntries := k.consumerApp.GetConsumerKeeper().GetHistoricalEntries(k.consumerCtx()) - newHeight := k.consumerChain.GetContext().BlockHeight() + historicalEntries + newHeight := k.consumerChain.GetContext().BlockHeight() - 1 + historicalEntries header := tmproto.Header{ ChainID: "HelloChain", Height: newHeight, @@ -59,31 +61,31 @@ func (k CCVTestSuite) TestHistoricalInfo() { //nolint:govet // this is a test so // test cases verify that historical info entries are pruned when their height // is below CurrentHeight - HistoricalEntries, and check that their valset gets updated testCases := []struct { - height int64 - found bool - expLen int + height int64 + expectsError bool + expLen int }{ { - height: initHeight + 1, - found: false, - expLen: 0, + height: initHeight, + expectsError: true, + expLen: 0, }, { - height: initHeight + 2, - found: false, - expLen: 0, + height: initHeight + 1, + expectsError: true, + expLen: 0, }, { - height: initHeight + ccvtypes.DefaultHistoricalEntries + 2, - found: true, - expLen: initValsetLen + 2, + height: initHeight + ccvtypes.DefaultHistoricalEntries + 1, + expectsError: false, + expLen: initValsetLen + 2, }, } for _, tc := range testCases { cCtx().WithBlockHeight(tc.height) - hi, found := consumerKeeper.GetHistoricalInfo(cCtx().WithBlockHeight(tc.height), tc.height) - k.Require().Equal(tc.found, found) + hi, err := consumerKeeper.GetHistoricalInfo(cCtx().WithBlockHeight(tc.height), tc.height) + k.Require().Equal(tc.expectsError, err != nil) k.Require().Len(hi.Valset, tc.expLen) } } diff --git a/tests/integration/setup.go b/tests/integration/setup.go index 0cd23d2a3e..393ebf2c24 100644 --- a/tests/integration/setup.go +++ b/tests/integration/setup.go @@ -21,6 +21,7 @@ import ( icstestingutils "github.com/cosmos/interchain-security/v5/testutil/ibc_testing" testutil "github.com/cosmos/interchain-security/v5/testutil/integration" consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) @@ -125,6 +126,21 @@ func (suite *CCVTestSuite) SetupTest() { suite.registerPacketSniffer(suite.providerChain) providerKeeper := suite.providerApp.GetProviderKeeper() + // re-assign all validator keys for the first consumer chain + // this has to be done before: + // 1. the consumer chain is added to the coordinator + // 2. MakeGenesis is called on the provider chain + // 3. ibc/testing sets the tendermint header for the consumer chain app + providerKeeper.SetPendingConsumerAdditionProp(suite.providerCtx(), &types.ConsumerAdditionProposal{ + ChainId: icstestingutils.FirstConsumerChainID, + }) + ps := providerKeeper.GetAllPendingConsumerAdditionProps(suite.providerCtx()) + preProposalKeyAssignment(suite, icstestingutils.FirstConsumerChainID) + + // remove props so they don't interfere with the rest of the setup + // if not removed here, setupConsumerCallback will have 2 proposals for adding the first consumer chain + providerKeeper.DeletePendingConsumerAdditionProps(suite.providerCtx(), ps...) + // start consumer chains numConsumers := 5 suite.consumerBundles = make(map[string]*icstestingutils.ConsumerBundle) @@ -132,11 +148,6 @@ func (suite *CCVTestSuite) SetupTest() { bundle := suite.setupConsumerCallback(&suite.Suite, suite.coordinator, i) suite.consumerBundles[bundle.Chain.ChainID] = bundle suite.registerPacketSniffer(bundle.Chain) - - // re-assign all validator keys for the first consumer chain - if i == 0 { - consumerKeyAssignment(suite, icstestingutils.FirstConsumerChainID) - } } // initialize each consumer chain with it's corresponding genesis state @@ -146,6 +157,7 @@ func (suite *CCVTestSuite) SetupTest() { suite.providerCtx(), chainID, ) + suite.Require().True(found, "consumer genesis not found") genesisState := consumertypes.GenesisState{ Params: consumerGenesisState.Params, @@ -353,10 +365,10 @@ func (s CCVTestSuite) validateEndpointsClientConfig(consumerBundle icstestinguti ) } -// consumerKeyAssignmentt assigns keys to all provider validators for +// preProposalKeyAssignment assigns keys to all provider validators for // the consumer with chainID before the chain is registered, i.e., // before a client to the consumer is created -func consumerKeyAssignment(s *CCVTestSuite, chainID string) { +func preProposalKeyAssignment(s *CCVTestSuite, chainID string) { providerKeeper := s.providerApp.GetProviderKeeper() for _, val := range s.providerChain.Vals.Validators { diff --git a/tests/integration/slashing.go b/tests/integration/slashing.go index e1f6fe4cbc..5b4cc3ccb9 100644 --- a/tests/integration/slashing.go +++ b/tests/integration/slashing.go @@ -1,6 +1,7 @@ package integration import ( + "context" "fmt" "time" @@ -9,10 +10,12 @@ import ( "cosmossdk.io/core/comet" "cosmossdk.io/math" + "cosmossdk.io/x/evidence/types" evidencetypes "cosmossdk.io/x/evidence/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkaddress "github.com/cosmos/cosmos-sdk/types/address" + slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -20,6 +23,7 @@ import ( "github.com/cometbft/cometbft/crypto/ed25519" tmtypes "github.com/cometbft/cometbft/types" + "github.com/cosmos/interchain-security/v5/testutil/integration" keepertestutil "github.com/cosmos/interchain-security/v5/testutil/keeper" providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" @@ -122,11 +126,11 @@ func (s *CCVTestSuite) TestRelayAndApplyDowntimePacket() { relayAllCommittedPackets(s, s.providerChain, bundle.Path, ccv.ProviderPortID, bundle.Path.EndpointB.ChannelID, 1) - // check that each consumer updated its VSC ID for the subsequent block + // check that each consumer updated its VSC ID for the subsequent not commited block ctx.BlockHeight() consumerKeeper := bundle.GetKeeper() ctx := bundle.GetCtx() actualValsetUpdateID := consumerKeeper.GetHeightValsetUpdateID( - ctx, uint64(ctx.BlockHeight())+1) + ctx, uint64(ctx.BlockHeight())) s.Require().Equal(expectedSentValsetUpdateId, actualValsetUpdateID) // check that jailed validator was removed from each consumer validator set @@ -582,14 +586,19 @@ func (suite *CCVTestSuite) TestValidatorDoubleSigning() { ) expCommit := suite.commitSlashPacket(ctx, *packetData) - // expect to send slash packet when handling double-sign evidence - // NOTE: using IBCKeeper Authority as msg submitter (equal to gov module addr) + suite.consumerChain.NextBlock() + // // expect to send slash packet when handling double-sign evidence + // // NOTE: using IBCKeeper Authority as msg submitter (equal to gov module addr) addr, err := sdk.AccAddressFromBech32(suite.consumerApp.GetIBCKeeper().GetAuthority()) suite.Require().NoError(err) evidenceMsg, err := evidencetypes.NewMsgSubmitEvidence(addr, e) suite.Require().NoError(err) suite.Require().NotEmpty(evidenceMsg) - suite.consumerApp.GetTestEvidenceKeeper().SubmitEvidence(ctx, e) + + // this was previously done using suite.consumerApp.GetTestEvidenceKeeper().HandleEquivocationEvidence(ctx, e) + // HandleEquivocationEvidence is not exposed in the evidencekeeper interface starting cosmos-sdk v0.50.x + // suite.consumerApp.GetTestEvidenceKeeper().SubmitEvidence(ctx, e) + handleEquivocationEvidence(ctx, suite.consumerApp, e) // check slash packet is queued pendingPackets := suite.consumerApp.GetConsumerKeeper().GetPendingPackets(ctx) @@ -740,3 +749,89 @@ func (suite *CCVTestSuite) TestCISBeforeCCVEstablished() { _, found = consumerKeeper.GetSlashRecord(suite.consumerCtx()) suite.Require().True(found) } + +// copy of the function from slashing/keeper.go +// in cosmos-sdk v0.50.x the function HandleEquivocationEvidence is not exposed (it was exposed for versions <= v0.47.x) +// https://github.com/cosmos/cosmos-sdk/blob/v0.50.4/x/evidence/keeper/infraction.go#L27 +func handleEquivocationEvidence(ctx context.Context, k integration.ConsumerApp, evidence *types.Equivocation) error { + sdkCtx := sdk.UnwrapSDKContext(ctx) + slashingKeeper := k.GetTestSlashingKeeper().(slashingkeeper.Keeper) + evidenceKeeper := k.GetTestEvidenceKeeper() + consAddr := evidence.GetConsensusAddress(k.GetConsumerKeeper().ConsensusAddressCodec()) + + validator, err := k.GetConsumerKeeper().ValidatorByConsAddr(ctx, consAddr) + if err != nil { + return err + } + if validator == nil || validator.IsUnbonded() { + return nil + } + + if len(validator.GetOperator()) != 0 { + if _, err := slashingKeeper.GetPubkey(ctx, consAddr.Bytes()); err != nil { + return nil + } + } + + // calculate the age of the evidence + infractionHeight := evidence.GetHeight() + infractionTime := evidence.GetTime() + ageDuration := sdkCtx.BlockHeader().Time.Sub(infractionTime) + ageBlocks := sdkCtx.BlockHeader().Height - infractionHeight + + // Reject evidence if the double-sign is too old. Evidence is considered stale + // if the difference in time and number of blocks is greater than the allowed + // parameters defined. + cp := sdkCtx.ConsensusParams() + if cp.Evidence != nil { + if ageDuration > cp.Evidence.MaxAgeDuration && ageBlocks > cp.Evidence.MaxAgeNumBlocks { + return nil + } + } + + if ok := slashingKeeper.HasValidatorSigningInfo(ctx, consAddr); !ok { + panic(fmt.Sprintf("expected signing info for validator %s but not found", consAddr)) + } + + // ignore if the validator is already tombstoned + if slashingKeeper.IsTombstoned(ctx, consAddr) { + return nil + } + + distributionHeight := infractionHeight - sdk.ValidatorUpdateDelay + slashFractionDoubleSign, err := slashingKeeper.SlashFractionDoubleSign(ctx) + if err != nil { + return err + } + + err = slashingKeeper.SlashWithInfractionReason( + ctx, + consAddr, + slashFractionDoubleSign, + evidence.GetValidatorPower(), distributionHeight, + stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN, + ) + if err != nil { + return err + } + + // Jail the validator if not already jailed. This will begin unbonding the + // validator if not already unbonding (tombstoned). + if !validator.IsJailed() { + err = slashingKeeper.Jail(ctx, consAddr) + if err != nil { + return err + } + } + + err = slashingKeeper.JailUntil(ctx, consAddr, types.DoubleSignJailEndTime) + if err != nil { + return err + } + + err = slashingKeeper.Tombstone(ctx, consAddr) + if err != nil { + return err + } + return evidenceKeeper.Evidences.Set(ctx, evidence.Hash(), evidence) +} diff --git a/tests/integration/soft_opt_out.go b/tests/integration/soft_opt_out.go index 58eb6cea84..193f209783 100644 --- a/tests/integration/soft_opt_out.go +++ b/tests/integration/soft_opt_out.go @@ -88,7 +88,7 @@ func (suite *CCVTestSuite) TestSoftOptOut() { minSigned, err := sk.MinSignedPerWindow(suite.consumerCtx()) suite.Require().NoError(err) - blocksToDowntime = blocksToDowntime - minSigned + 1 + blocksToDowntime = blocksToDowntime - minSigned slashingBeginBlocker(suite, votes, blocksToDowntime) // Increase the power of this validator (to bring it in the top 95%) @@ -133,7 +133,7 @@ func (suite *CCVTestSuite) TestSoftOptOut() { minSigned, err := sk.MinSignedPerWindow(suite.consumerCtx()) suite.Require().NoError(err) - blocksToDowntime = blocksToDowntime - minSigned + 1 + blocksToDowntime = blocksToDowntime - minSigned slashingBeginBlocker(suite, votes, blocksToDowntime) // Increase the power of this validator (to bring it in the top 95%) diff --git a/tests/integration/throttle.go b/tests/integration/throttle.go index ed7ce779d2..f56228c56f 100644 --- a/tests/integration/throttle.go +++ b/tests/integration/throttle.go @@ -67,6 +67,7 @@ func (s *CCVTestSuite) TestBasicSlashPacketThrottling() { s.SetupAllCCVChannels() s.setupValidatorPowers([]int64{1000, 1000, 1000, 1000}) + providerKeeper := s.providerApp.GetProviderKeeper() providerStakingKeeper := s.providerApp.GetTestStakingKeeper() // Use default params (incl replenish period), but set replenish fraction to tc value. @@ -101,7 +102,7 @@ func (s *CCVTestSuite) TestBasicSlashPacketThrottling() { s.Require().NoError(err) slashedVal := vals[0] s.Require().True(slashedVal.IsJailed()) - slashedValOperator, err := sdk.ValAddressFromHex(slashedVal.GetOperator()) + slashedValOperator, err := providerKeeper.ValidatorAddressCodec().StringToBytes(slashedVal.GetOperator()) s.Require().NoError(err) lastValPower, err := providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), slashedValOperator) s.Require().NoError(err) @@ -183,7 +184,7 @@ func (s *CCVTestSuite) TestBasicSlashPacketThrottling() { // Assert validator 2 has no power, this should be apparent next block, // since the staking endblocker runs before the ccv endblocker. s.providerChain.NextBlock() - slashedValOperator, err = sdk.ValAddressFromHex(slashedVal.GetOperator()) + slashedValOperator, err = providerKeeper.ValidatorAddressCodec().StringToBytes(slashedVal.GetOperator()) s.Require().NoError(err) lastValPower, err = providerStakingKeeper.GetLastValidatorPower(cacheCtx, slashedValOperator) s.Require().NoError(err) @@ -446,7 +447,7 @@ func (s *CCVTestSuite) TestDoubleSignDoesNotAffectThrottling() { s.Require().NoError(err) s.Require().Equal(int64(1000), power) stakingVal, err := stakingKeeper.GetValidatorByConsAddr(s.providerCtx(), sdk.ConsAddress(val.Address)) - s.Require().Error(err) + s.Require().NoError(err) s.Require().False(stakingVal.Jailed) // 4th validator should have no slash log, all the others do @@ -464,6 +465,7 @@ func (s *CCVTestSuite) TestDoubleSignDoesNotAffectThrottling() { // power can be handled by the provider chain in a non-throttled manner. func (s *CCVTestSuite) TestSlashingSmallValidators() { s.SetupAllCCVChannels() + providerKeeper := s.providerApp.GetProviderKeeper() // Setup first val with 1000 power and the rest with 10 power. delAddr := s.providerChain.SenderAccount.GetAddress() @@ -508,24 +510,26 @@ func (s *CCVTestSuite) TestSlashingSmallValidators() { vals, err = providerStakingKeeper.GetAllValidators(s.providerCtx()) s.Require().NoError(err) - val0Operator, err := sdk.ValAddressFromHex(vals[0].GetOperator()) + val0Operator, err := providerKeeper.ValidatorAddressCodec().StringToBytes(vals[0].GetOperator()) + s.Require().NoError(err) power, err := providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), val0Operator) s.Require().NoError(err) s.Require().Equal(int64(1000), power) - val1Operator, err := sdk.ValAddressFromHex(vals[1].GetOperator()) - power, err = providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), val1Operator) + val1Operator, err := providerKeeper.ValidatorAddressCodec().StringToBytes(vals[1].GetOperator()) s.Require().NoError(err) + power, err = providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), val1Operator) s.Require().NoError(err) s.Require().Equal(int64(0), power) - val2Operator, err := sdk.ValAddressFromHex(vals[2].GetOperator()) - power, err = providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), val2Operator) + val2Operator, err := providerKeeper.ValidatorAddressCodec().StringToBytes(vals[2].GetOperator()) s.Require().NoError(err) + power, err = providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), val2Operator) s.Require().NoError(err) s.Require().Equal(int64(0), power) - val3Operator, err := sdk.ValAddressFromHex(vals[3].GetOperator()) + val3Operator, err := providerKeeper.ValidatorAddressCodec().StringToBytes(vals[3].GetOperator()) + s.Require().NoError(err) power, err = providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), val3Operator) s.Require().NoError(err) s.Require().Equal(int64(0), power) @@ -622,13 +626,14 @@ func (s CCVTestSuite) TestSlashAllValidators() { //nolint:govet // this is a tes } func (s *CCVTestSuite) confirmValidatorJailed(tmVal tmtypes.Validator, checkPower bool) { + providerKeeper := s.providerApp.GetProviderKeeper() sdkVal, err := s.providerApp.GetTestStakingKeeper().GetValidator( s.providerCtx(), sdk.ValAddress(tmVal.Address)) s.Require().NoError(err) s.Require().True(sdkVal.IsJailed()) if checkPower { - valOperator, err := sdk.ValAddressFromHex(sdkVal.GetOperator()) + valOperator, err := providerKeeper.ValidatorAddressCodec().StringToBytes(sdkVal.GetOperator()) s.Require().NoError(err) valPower, err := s.providerApp.GetTestStakingKeeper().GetLastValidatorPower( s.providerCtx(), valOperator) @@ -638,10 +643,11 @@ func (s *CCVTestSuite) confirmValidatorJailed(tmVal tmtypes.Validator, checkPowe } func (s *CCVTestSuite) confirmValidatorNotJailed(tmVal tmtypes.Validator, expectedPower int64) { + providerKeeper := s.providerApp.GetProviderKeeper() sdkVal, err := s.providerApp.GetTestStakingKeeper().GetValidator( s.providerCtx(), sdk.ValAddress(tmVal.Address)) s.Require().NoError(err) - valOperator, err := sdk.ValAddressFromHex(sdkVal.GetOperator()) + valOperator, err := providerKeeper.ValidatorAddressCodec().StringToBytes(sdkVal.GetOperator()) s.Require().NoError(err) valPower, err := s.providerApp.GetTestStakingKeeper().GetLastValidatorPower( s.providerCtx(), valOperator) diff --git a/tests/integration/throttle_retry.go b/tests/integration/throttle_retry.go index cde17014cf..fcc795bb27 100644 --- a/tests/integration/throttle_retry.go +++ b/tests/integration/throttle_retry.go @@ -5,7 +5,6 @@ import ( channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" - sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" @@ -93,7 +92,7 @@ func (s *CCVTestSuite) TestSlashRetries() { // Default slash meter replenish fraction is 0.05, so packet should be handled on provider. stakingVal1 := s.mustGetStakingValFromTmVal(*tmval1) s.Require().True(stakingVal1.IsJailed()) - stakingVal1Addr, err := sdk.ValAddressFromHex(stakingVal1.GetOperator()) + stakingVal1Addr, err := providerKeeper.ValidatorAddressCodec().StringToBytes(stakingVal1.GetOperator()) s.Require().NoError(err) stakingVal1LastPower, err := s.providerApp.GetTestStakingKeeper().GetLastValidatorPower(s.providerCtx(), stakingVal1Addr) s.Require().NoError(err) @@ -156,7 +155,7 @@ func (s *CCVTestSuite) TestSlashRetries() { // Val 2 shouldn't be jailed on provider. Slash packet should have been bounced. stakingVal2 := s.mustGetStakingValFromTmVal(*tmval2) s.Require().False(stakingVal2.IsJailed()) - stakingVal2Addr, err := sdk.ValAddressFromHex(stakingVal2.GetOperator()) + stakingVal2Addr, err := providerKeeper.ValidatorAddressCodec().StringToBytes(stakingVal2.GetOperator()) s.Require().NoError(err) stakingVal2LastPower, err := providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), stakingVal2Addr) s.Require().Equal(int64(1000), stakingVal2LastPower) @@ -210,8 +209,7 @@ func (s *CCVTestSuite) TestSlashRetries() { // Provider should have now jailed val 2 stakingVal2 = s.mustGetStakingValFromTmVal(*tmval2) s.Require().True(stakingVal2.IsJailed()) - s.Require().False(stakingVal2.IsJailed()) - stakingVal2Addr, err = sdk.ValAddressFromHex(stakingVal2.GetOperator()) + stakingVal2Addr, err = providerKeeper.ValidatorAddressCodec().StringToBytes(stakingVal2.GetOperator()) s.Require().NoError(err) stakingVal2LastPower, err = providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), stakingVal2Addr) s.Require().Equal(int64(0), stakingVal2LastPower) diff --git a/testutil/ibc_testing/generic_setup.go b/testutil/ibc_testing/generic_setup.go index 92f185b80c..39b23f0da4 100644 --- a/testutil/ibc_testing/generic_setup.go +++ b/testutil/ibc_testing/generic_setup.go @@ -136,8 +136,8 @@ func AddConsumer[Tp testutil.ProviderApp, Tc testutil.ConsumerApp]( // using time.Now() could set the spawn time to be too far in the past or too far in the future SpawnTime: coordinator.CurrentTime, UnbondingPeriod: ccvtypes.DefaultConsumerUnbondingPeriod, - CcvTimeoutPeriod: ccvtypes.DefaultBlocksPerDistributionTransmission, - TransferTimeoutPeriod: ccvtypes.DefaultCCVTimeoutPeriod, + CcvTimeoutPeriod: ccvtypes.DefaultCCVTimeoutPeriod, + TransferTimeoutPeriod: ccvtypes.DefaultTransferTimeoutPeriod, ConsumerRedistributionFraction: ccvtypes.DefaultConsumerRedistributeFrac, BlocksPerDistributionTransmission: ccvtypes.DefaultBlocksPerDistributionTransmission, HistoricalEntries: ccvtypes.DefaultHistoricalEntries, @@ -145,8 +145,8 @@ func AddConsumer[Tp testutil.ProviderApp, Tc testutil.ConsumerApp]( } providerKeeper.SetPendingConsumerAdditionProp(providerChain.GetContext(), &prop) - propsToExecute := providerKeeper.GetConsumerAdditionPropsToExecute(providerChain.GetContext()) - s.Require().Len(propsToExecute, 1, "props to execute is incorrect length") + props := providerKeeper.GetAllPendingConsumerAdditionProps(providerChain.GetContext()) + s.Require().Len(props, 1, "unexpected len consumer addition proposals in AddConsumer") // commit the state on the provider chain coordinator.CommitBlock(providerChain) @@ -156,7 +156,8 @@ func AddConsumer[Tp testutil.ProviderApp, Tc testutil.ConsumerApp]( providerChain.GetContext(), chainID, ) - s.Require().True(found, "consumer genesis not found") + + s.Require().True(found, "consumer genesis not found in AddConsumer") // use InitialValSet as the valset on the consumer var valz []*tmtypes.Validator diff --git a/testutil/integration/validators.go b/testutil/integration/validators.go index 2fca9e5390..4d8f59b2f8 100644 --- a/testutil/integration/validators.go +++ b/testutil/integration/validators.go @@ -1,8 +1,6 @@ package integration import ( - "github.com/cosmos/cosmos-sdk/testutil/mock" - "github.com/cometbft/cometbft/abci/types" tmencoding "github.com/cometbft/cometbft/crypto/encoding" tmtypes "github.com/cometbft/cometbft/types" @@ -17,7 +15,7 @@ func CreateValidators(n int) ( signersByAddress = make(map[string]tmtypes.PrivValidator, n) ) for i := 0; i < n; i++ { - privVal := mock.NewPV() + privVal := tmtypes.NewMockPV() pubKey, err := privVal.GetPubKey() if err != nil { return nil, nil, nil, err diff --git a/x/ccv/consumer/keeper/validators.go b/x/ccv/consumer/keeper/validators.go index 7bc86ded38..de53bdd1db 100644 --- a/x/ccv/consumer/keeper/validators.go +++ b/x/ccv/consumer/keeper/validators.go @@ -288,8 +288,8 @@ func (k Keeper) TrackHistoricalInfo(goCtx context.Context) error { // to be stored correctly in ApplyCCValidatorChanges. panic(err) } - // NOTE: @MSalopek -> double check pk.Address().String() - val, err := stakingtypes.NewValidator(pk.Address().String(), pk, stakingtypes.Description{}) + + val, err := stakingtypes.NewValidator(sdk.ValAddress(pk.Address()).String(), pk, stakingtypes.Description{}) if err != nil { // This should never happen as the pubkey is assumed // to be stored correctly in ApplyCCValidatorChanges. diff --git a/x/ccv/provider/keeper/relay_test.go b/x/ccv/provider/keeper/relay_test.go index 61b770c320..9ae66aedf1 100644 --- a/x/ccv/provider/keeper/relay_test.go +++ b/x/ccv/provider/keeper/relay_test.go @@ -148,9 +148,9 @@ func TestOnRecvDowntimeSlashPacket(t *testing.T) { calls := []*gomock.Call{ mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, providerAddr.ToSdkConsAddr()). Return(stakingtypes.Validator{ - // must be a hex string so it can be properly decoded by sdktypes.ValAddressFromHex(val.GetOperator()) - // empty string is fine, as it's not used in this test - OperatorAddress: "557D5BD0FA991DAB8EED2B9DCF98AC1B3200D43D", + // provided address must be valid so it can be processed correctly + // by k.ValidatorAddressCodec().StringToBytes(val.GetOperator()) call in GetEffectiveValPower() + OperatorAddress: sdk.ValAddress(packetData.Validator.Address).String(), }, nil).Times(1), mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(ctx, gomock.Any()). Return(int64(2), nil).Times(1), diff --git a/x/ccv/provider/keeper/throttle.go b/x/ccv/provider/keeper/throttle.go index 5e23f7857f..7be82d4eaa 100644 --- a/x/ccv/provider/keeper/throttle.go +++ b/x/ccv/provider/keeper/throttle.go @@ -27,8 +27,7 @@ func (k Keeper) GetEffectiveValPower(ctx sdktypes.Context, return math.ZeroInt() } else { // Otherwise, return the staking keeper's LastValidatorPower value. - // NOTE: @MSalopek double check this conversion and see if it's necessary - valAddr, err := sdktypes.ValAddressFromHex(val.GetOperator()) + valAddr, err := k.ValidatorAddressCodec().StringToBytes(val.GetOperator()) if err != nil { return math.ZeroInt() } diff --git a/x/ccv/provider/types/provider.pb.go b/x/ccv/provider/types/provider.pb.go index 77c76d941a..cc3cbcbca8 100644 --- a/x/ccv/provider/types/provider.pb.go +++ b/x/ccv/provider/types/provider.pb.go @@ -40,9 +40,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // chain are expected to validate the consumer chain at spawn time or get // slashed. It is recommended that spawn time occurs after the proposal end // time. -// Deprecated: Use MsgConsumerAddition instead -// -// Deprecated: Do not use. +// Use MsgConsumerAddition to submit this proposal type. type ConsumerAdditionProposal struct { // the title of the proposal Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` @@ -132,9 +130,7 @@ var xxx_messageInfo_ConsumerAdditionProposal proto.InternalMessageInfo // remove (and stop) a consumer chain. If it passes, all the consumer chain's // state is removed from the provider chain. The outstanding unbonding operation // funds are released. -// Deprecated: Use MsgConsumerRemoval instead -// -// Deprecated: Do not use. +// Use MsgConsumerRemoval to submit this proposal type. type ConsumerRemovalProposal struct { // the title of the proposal Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` @@ -281,9 +277,7 @@ func (m *EquivocationProposal) GetEquivocations() []*types1.Equivocation { // ChangeRewardDenomsProposal is a governance proposal on the provider chain to // mutate the set of denoms accepted by the provider as rewards. -// Deprecated: Use MsgChangeRewardDenoms instead -// -// Deprecated: Do not use. +// Use MsgChangeRewardDenoms to submit this proposal type. type ChangeRewardDenomsProposal struct { // the title of the proposal Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` @@ -1425,115 +1419,115 @@ func init() { } var fileDescriptor_f22ec409a72b7b72 = []byte{ - // 1727 bytes of a gzipped FileDescriptorProto + // 1726 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xcd, 0x6f, 0x1b, 0xc7, - 0x15, 0xd7, 0x8a, 0x94, 0x2c, 0x3e, 0xea, 0xcb, 0x2b, 0x25, 0x5e, 0xa9, 0x2a, 0x45, 0x6f, 0x9a, - 0x54, 0x45, 0xe0, 0x65, 0xa5, 0x20, 0x40, 0x20, 0x34, 0x08, 0x24, 0xca, 0x89, 0x65, 0x35, 0xb1, + 0x15, 0xd7, 0x8a, 0x94, 0x2c, 0x3e, 0xea, 0xcb, 0x2b, 0x25, 0x5e, 0xa9, 0x2a, 0x25, 0x6f, 0x1a, + 0x57, 0x45, 0xe0, 0x65, 0xa5, 0x20, 0x40, 0x20, 0x34, 0x08, 0x24, 0xca, 0x89, 0x65, 0x35, 0xb1, 0xb2, 0x52, 0x65, 0xb4, 0x3d, 0x2c, 0x86, 0xb3, 0x63, 0x72, 0xa0, 0xe5, 0xce, 0x7a, 0x66, 0x76, - 0x1d, 0x5e, 0x7a, 0xee, 0x31, 0xbd, 0x05, 0xbd, 0x34, 0xed, 0xdf, 0xd0, 0x4b, 0xef, 0x3d, 0x04, - 0x3d, 0xa5, 0xb7, 0x9e, 0xd2, 0xc2, 0x3e, 0xf6, 0x8f, 0x68, 0x31, 0xb3, 0x9f, 0xa4, 0x24, 0x87, - 0x86, 0xdb, 0xdb, 0xce, 0x9b, 0xf7, 0x7e, 0xef, 0xfb, 0xbd, 0x21, 0x61, 0x8f, 0x86, 0x92, 0x70, - 0x3c, 0x40, 0x34, 0xf4, 0x04, 0xc1, 0x31, 0xa7, 0x72, 0xd4, 0xc1, 0x38, 0xe9, 0x44, 0x9c, 0x25, - 0xd4, 0x27, 0xbc, 0x93, 0xec, 0x16, 0xdf, 0x4e, 0xc4, 0x99, 0x64, 0xe6, 0x5b, 0xd7, 0xc8, 0x38, - 0x18, 0x27, 0x4e, 0xc1, 0x97, 0xec, 0x6e, 0xbe, 0x7d, 0x13, 0x70, 0xb2, 0xdb, 0x79, 0x46, 0x39, - 0x49, 0xb1, 0x36, 0xd7, 0xfb, 0xac, 0xcf, 0xf4, 0x67, 0x47, 0x7d, 0x65, 0xd4, 0xed, 0x3e, 0x63, - 0xfd, 0x80, 0x74, 0xf4, 0xa9, 0x17, 0x3f, 0xe9, 0x48, 0x3a, 0x24, 0x42, 0xa2, 0x61, 0x94, 0x31, - 0xb4, 0x26, 0x19, 0xfc, 0x98, 0x23, 0x49, 0x59, 0x98, 0x03, 0xd0, 0x1e, 0xee, 0x60, 0xc6, 0x49, - 0x07, 0x07, 0x94, 0x84, 0x52, 0x69, 0x4d, 0xbf, 0x32, 0x86, 0x8e, 0x62, 0x08, 0x68, 0x7f, 0x20, - 0x53, 0xb2, 0xe8, 0x48, 0x12, 0xfa, 0x84, 0x0f, 0x69, 0xca, 0x5c, 0x9e, 0x32, 0x81, 0xad, 0xca, - 0x3d, 0xe6, 0xa3, 0x48, 0xb2, 0xce, 0x25, 0x19, 0x89, 0xec, 0xf6, 0x1d, 0xcc, 0xc4, 0x90, 0x89, - 0x0e, 0x51, 0xfe, 0x87, 0x98, 0x74, 0x92, 0xdd, 0x1e, 0x91, 0x68, 0xb7, 0x20, 0xe4, 0x76, 0x67, - 0x7c, 0x3d, 0x24, 0x4a, 0x1e, 0xcc, 0x68, 0x6e, 0xf7, 0x46, 0x7a, 0xef, 0xa5, 0x11, 0x49, 0x0f, - 0xe9, 0x95, 0xfd, 0x9f, 0x79, 0xb0, 0xba, 0x2c, 0x14, 0xf1, 0x90, 0xf0, 0x03, 0xdf, 0xa7, 0xca, - 0xdb, 0x53, 0xce, 0x22, 0x26, 0x50, 0x60, 0xae, 0xc3, 0x9c, 0xa4, 0x32, 0x20, 0x96, 0xd1, 0x36, - 0x76, 0x1a, 0x6e, 0x7a, 0x30, 0xdb, 0xd0, 0xf4, 0x89, 0xc0, 0x9c, 0x46, 0x8a, 0xd9, 0x9a, 0xd5, - 0x77, 0x55, 0x92, 0xb9, 0x01, 0x0b, 0x69, 0x8a, 0xa8, 0x6f, 0xd5, 0xf4, 0xf5, 0x2d, 0x7d, 0x3e, - 0xf6, 0xcd, 0x4f, 0x60, 0x99, 0x86, 0x54, 0x52, 0x14, 0x78, 0x03, 0xa2, 0x02, 0x65, 0xd5, 0xdb, - 0xc6, 0x4e, 0x73, 0x6f, 0xd3, 0xa1, 0x3d, 0xec, 0xa8, 0xd8, 0x3a, 0x59, 0x44, 0x93, 0x5d, 0xe7, - 0x81, 0xe6, 0x38, 0xac, 0x7f, 0xf3, 0xdd, 0xf6, 0x8c, 0xbb, 0x94, 0xc9, 0xa5, 0x44, 0xf3, 0x2e, - 0x2c, 0xf6, 0x49, 0x48, 0x04, 0x15, 0xde, 0x00, 0x89, 0x81, 0x35, 0xd7, 0x36, 0x76, 0x16, 0xdd, - 0x66, 0x46, 0x7b, 0x80, 0xc4, 0xc0, 0xdc, 0x86, 0x66, 0x8f, 0x86, 0x88, 0x8f, 0x52, 0x8e, 0x79, - 0xcd, 0x01, 0x29, 0x49, 0x33, 0x74, 0x01, 0x44, 0x84, 0x9e, 0x85, 0x9e, 0x2a, 0x04, 0xeb, 0x56, - 0x66, 0x48, 0x5a, 0x04, 0x4e, 0x5e, 0x04, 0xce, 0x79, 0x5e, 0x25, 0x87, 0x0b, 0xca, 0x90, 0x2f, - 0xff, 0xb9, 0x6d, 0xb8, 0x0d, 0x2d, 0xa7, 0x6e, 0xcc, 0xcf, 0x60, 0x35, 0x0e, 0x7b, 0x2c, 0xf4, - 0x69, 0xd8, 0xf7, 0x22, 0xc2, 0x29, 0xf3, 0xad, 0x05, 0x0d, 0xb5, 0x71, 0x05, 0xea, 0x28, 0xab, - 0xa7, 0x14, 0xe9, 0x2b, 0x85, 0xb4, 0x52, 0x08, 0x9f, 0x6a, 0x59, 0xf3, 0x73, 0x30, 0x31, 0x4e, - 0xb4, 0x49, 0x2c, 0x96, 0x39, 0x62, 0x63, 0x7a, 0xc4, 0x55, 0x8c, 0x93, 0xf3, 0x54, 0x3a, 0x83, - 0xfc, 0x35, 0xdc, 0x91, 0x1c, 0x85, 0xe2, 0x09, 0xe1, 0x93, 0xb8, 0x30, 0x3d, 0xee, 0x1b, 0x39, - 0xc6, 0x38, 0xf8, 0x03, 0x68, 0xe3, 0xac, 0x80, 0x3c, 0x4e, 0x7c, 0x2a, 0x24, 0xa7, 0xbd, 0x58, - 0xc9, 0x7a, 0x4f, 0x38, 0xc2, 0xba, 0x46, 0x9a, 0xba, 0x08, 0x5a, 0x39, 0x9f, 0x3b, 0xc6, 0xf6, - 0x71, 0xc6, 0x65, 0x3e, 0x82, 0x1f, 0xf5, 0x02, 0x86, 0x2f, 0x85, 0x32, 0xce, 0x1b, 0x43, 0xd2, - 0xaa, 0x87, 0x54, 0x08, 0x85, 0xb6, 0xd8, 0x36, 0x76, 0x6a, 0xee, 0xdd, 0x94, 0xf7, 0x94, 0xf0, - 0xa3, 0x0a, 0xe7, 0x79, 0x85, 0xd1, 0xbc, 0x07, 0xe6, 0x80, 0x0a, 0xc9, 0x38, 0xc5, 0x28, 0xf0, - 0x48, 0x28, 0x39, 0x25, 0xc2, 0x5a, 0xd2, 0xe2, 0xb7, 0xcb, 0x9b, 0xfb, 0xe9, 0x85, 0xf9, 0x10, - 0xee, 0xde, 0xa8, 0xd4, 0xc3, 0x03, 0x14, 0x86, 0x24, 0xb0, 0x96, 0xb5, 0x2b, 0xdb, 0xfe, 0x0d, - 0x3a, 0xbb, 0x29, 0xdb, 0xfe, 0xce, 0x6f, 0xbf, 0xde, 0x9e, 0xf9, 0xea, 0xeb, 0xed, 0x99, 0xbf, - 0xfd, 0xf9, 0xde, 0x66, 0xd6, 0x71, 0x7d, 0x96, 0x38, 0x59, 0x77, 0x3a, 0x5d, 0x16, 0x4a, 0x12, - 0x4a, 0xcb, 0xb0, 0xff, 0x6e, 0xc0, 0x9d, 0x6e, 0x11, 0x98, 0x21, 0x4b, 0x50, 0xf0, 0xff, 0x6c, - 0xc0, 0x03, 0x68, 0x08, 0xc9, 0xa2, 0xb4, 0xe4, 0xeb, 0xaf, 0x50, 0xf2, 0x0b, 0x4a, 0x4c, 0x5d, - 0xec, 0xb7, 0xbf, 0xd7, 0xa7, 0x3f, 0x18, 0xb0, 0x7e, 0xff, 0x69, 0x4c, 0x13, 0x86, 0xd1, 0xff, - 0x64, 0xa2, 0x9c, 0xc0, 0x12, 0xa9, 0xe0, 0x09, 0xab, 0xd6, 0xae, 0xed, 0x34, 0xf7, 0xde, 0x76, - 0x32, 0x33, 0x8a, 0x81, 0x98, 0xdb, 0x52, 0xd5, 0xee, 0x8e, 0xcb, 0xee, 0xcf, 0x5a, 0x86, 0xfd, - 0x57, 0x03, 0x36, 0x55, 0xae, 0xfa, 0xc4, 0x25, 0xcf, 0x10, 0xf7, 0x8f, 0x48, 0xc8, 0x86, 0xe2, - 0xb5, 0xed, 0xb4, 0x61, 0xc9, 0xd7, 0x48, 0x9e, 0x64, 0x1e, 0xf2, 0x7d, 0x6d, 0xa7, 0xe6, 0x51, - 0xc4, 0x73, 0x76, 0xe0, 0xfb, 0xe6, 0x0e, 0xac, 0x96, 0x3c, 0x5c, 0x65, 0x5c, 0x25, 0x42, 0xb1, - 0x2d, 0xe7, 0x6c, 0xba, 0x0e, 0xa6, 0x09, 0xf4, 0xbf, 0x0d, 0x58, 0xfd, 0x24, 0x60, 0x3d, 0x14, - 0x9c, 0x05, 0x48, 0x0c, 0x54, 0x25, 0x8f, 0x54, 0x8a, 0x39, 0xc9, 0x46, 0x88, 0x76, 0x60, 0xea, - 0x14, 0x2b, 0x31, 0x3d, 0xd4, 0x3e, 0x82, 0xdb, 0x45, 0x53, 0x17, 0x95, 0xa4, 0xfd, 0x3d, 0x5c, - 0x7b, 0xfe, 0xdd, 0xf6, 0x4a, 0x5e, 0xb0, 0x5d, 0x5d, 0x55, 0x47, 0xee, 0x0a, 0x1e, 0x23, 0xf8, - 0x66, 0x0b, 0x9a, 0xb4, 0x87, 0x3d, 0x41, 0x9e, 0x7a, 0x61, 0x3c, 0xd4, 0x45, 0x58, 0x77, 0x1b, - 0xb4, 0x87, 0xcf, 0xc8, 0xd3, 0xcf, 0xe2, 0xa1, 0xf9, 0x1e, 0xbc, 0x99, 0xef, 0x75, 0x2f, 0x41, - 0x81, 0xa7, 0xe4, 0x55, 0xc0, 0xb8, 0xae, 0xc9, 0x45, 0x77, 0x2d, 0xbf, 0xbd, 0x40, 0x81, 0x52, - 0x76, 0xe0, 0xfb, 0xdc, 0xfe, 0xcb, 0x1c, 0xcc, 0x9f, 0x22, 0x8e, 0x86, 0xc2, 0x3c, 0x87, 0x15, - 0x49, 0x86, 0x51, 0x80, 0x24, 0xf1, 0xd2, 0x85, 0x91, 0x79, 0xfa, 0xae, 0x5e, 0x24, 0xd5, 0x1d, - 0xec, 0x54, 0xb6, 0x6e, 0xb2, 0xeb, 0x74, 0x35, 0xf5, 0x4c, 0x22, 0x49, 0xdc, 0xe5, 0x1c, 0x23, - 0x25, 0x9a, 0x1f, 0x80, 0x25, 0x79, 0x2c, 0x64, 0x39, 0xca, 0xcb, 0x19, 0x96, 0x66, 0xfb, 0xcd, - 0xfc, 0x3e, 0x9d, 0x7e, 0xc5, 0xec, 0xba, 0x7e, 0x6a, 0xd7, 0x5e, 0x67, 0x6a, 0x9f, 0xc1, 0x9a, - 0x5a, 0x79, 0x93, 0x98, 0xf5, 0xe9, 0x31, 0x6f, 0x2b, 0xf9, 0x71, 0xd0, 0xcf, 0xc1, 0x4c, 0x04, - 0x9e, 0xc4, 0x9c, 0x7b, 0x05, 0x3b, 0x13, 0x81, 0xc7, 0x21, 0x7d, 0xd8, 0x12, 0xaa, 0xf8, 0xbc, - 0x21, 0x91, 0x7a, 0x07, 0x44, 0x01, 0x09, 0xa9, 0x18, 0xe4, 0xe0, 0xf3, 0xd3, 0x83, 0x6f, 0x68, - 0xa0, 0x4f, 0x15, 0x8e, 0x9b, 0xc3, 0x64, 0x5a, 0xba, 0xd0, 0xba, 0x5e, 0x4b, 0x91, 0xa0, 0x5b, - 0x3a, 0x41, 0x3f, 0xb8, 0x06, 0xa2, 0xc8, 0x92, 0x80, 0x77, 0x2a, 0xbb, 0x4a, 0xf5, 0xbd, 0xa7, - 0x5b, 0xce, 0xe3, 0xa4, 0xaf, 0x06, 0x3a, 0x4a, 0xd7, 0x16, 0x21, 0xc5, 0xbe, 0xcd, 0xba, 0x4f, - 0xbd, 0xac, 0x2a, 0xed, 0x47, 0xc3, 0xec, 0x51, 0x62, 0x97, 0x2b, 0xad, 0x98, 0x22, 0x6e, 0x05, - 0xeb, 0x63, 0x42, 0x1e, 0xd6, 0x17, 0x16, 0x56, 0x1b, 0xf6, 0x4f, 0xa0, 0xa1, 0x5b, 0xf4, 0x00, - 0x5f, 0x0a, 0x73, 0x0b, 0x1a, 0xaa, 0xd6, 0x89, 0x10, 0x44, 0x58, 0x86, 0xee, 0xfd, 0x92, 0x60, - 0x4b, 0xd8, 0xb8, 0xe9, 0x49, 0x26, 0xcc, 0xc7, 0x70, 0x2b, 0x22, 0xfa, 0xbd, 0xa0, 0x05, 0x9b, - 0x7b, 0x1f, 0x3a, 0x53, 0x3c, 0x9c, 0x9d, 0x9b, 0x00, 0xdd, 0x1c, 0xcd, 0xe6, 0xe5, 0x43, 0x70, - 0x62, 0x0d, 0x09, 0xf3, 0x62, 0x52, 0xe9, 0xcf, 0x5e, 0x49, 0xe9, 0x04, 0x5e, 0xa9, 0xf3, 0x5d, - 0x68, 0x1e, 0xa4, 0x6e, 0xff, 0x9c, 0x0a, 0x79, 0x35, 0x2c, 0x8b, 0xd5, 0xb0, 0x3c, 0x84, 0xe5, - 0x6c, 0xbb, 0x9e, 0x33, 0x3d, 0x66, 0xcc, 0x1f, 0x02, 0x64, 0x6b, 0x59, 0x8d, 0xa7, 0x74, 0x54, - 0x37, 0x32, 0xca, 0xb1, 0x3f, 0xb6, 0x05, 0x67, 0xc7, 0xb6, 0xa0, 0xed, 0xc2, 0xca, 0x85, 0xc0, - 0xbf, 0xc8, 0x9f, 0x5e, 0x8f, 0x22, 0x61, 0xbe, 0x01, 0xf3, 0xaa, 0x33, 0x32, 0xa0, 0xba, 0x3b, - 0x97, 0x08, 0x7c, 0xac, 0xa7, 0x75, 0xf9, 0xbc, 0x63, 0x91, 0x47, 0x7d, 0x61, 0xcd, 0xb6, 0x6b, - 0x3b, 0x75, 0x77, 0x39, 0x2e, 0xc5, 0x8f, 0x7d, 0x61, 0xff, 0x12, 0x9a, 0x15, 0x40, 0x73, 0x19, - 0x66, 0x0b, 0xac, 0x59, 0xea, 0x9b, 0xfb, 0xb0, 0x51, 0x02, 0x8d, 0x0f, 0xd7, 0x14, 0xb1, 0xe1, - 0xde, 0x29, 0x18, 0xc6, 0xe6, 0xab, 0xb0, 0x1f, 0xc1, 0xfa, 0x71, 0xd9, 0xca, 0xc5, 0xe8, 0x1e, - 0xf3, 0xd0, 0x18, 0xdf, 0xf3, 0x5b, 0xd0, 0x28, 0x7e, 0xde, 0x68, 0xef, 0xeb, 0x6e, 0x49, 0xb0, - 0x87, 0xb0, 0x7a, 0x21, 0xf0, 0x19, 0x09, 0xfd, 0x12, 0xec, 0x86, 0x00, 0x1c, 0x4e, 0x02, 0x4d, - 0xfd, 0x46, 0x2e, 0xd5, 0x31, 0xd8, 0xb8, 0x40, 0x01, 0xf5, 0x91, 0x64, 0xfc, 0x8c, 0xc8, 0x74, - 0xf1, 0x9e, 0x22, 0x7c, 0x49, 0xa4, 0x30, 0x5d, 0xa8, 0x07, 0x54, 0xc8, 0xac, 0xb2, 0x3e, 0xb8, - 0xb1, 0xb2, 0x92, 0x5d, 0xe7, 0x26, 0x90, 0x23, 0x24, 0x51, 0xd6, 0x91, 0x1a, 0xcb, 0xfe, 0x31, - 0xac, 0x7d, 0x8a, 0x64, 0xcc, 0x89, 0x3f, 0x96, 0xe3, 0x55, 0xa8, 0xa9, 0xfc, 0x19, 0x3a, 0x7f, - 0xea, 0xd3, 0xfe, 0x93, 0x01, 0xd6, 0xfd, 0x2f, 0x22, 0xc6, 0x25, 0xf1, 0xaf, 0x44, 0xe4, 0x25, - 0xe1, 0xbd, 0x84, 0x35, 0x15, 0x2c, 0x41, 0x42, 0xdf, 0x2b, 0xfc, 0x4c, 0xf3, 0xd8, 0xdc, 0x7b, - 0x7f, 0xaa, 0xee, 0x98, 0x54, 0x97, 0x39, 0x70, 0x3b, 0x99, 0xa0, 0x0b, 0xfb, 0x77, 0x06, 0x58, - 0x27, 0x64, 0x74, 0x20, 0x04, 0xed, 0x87, 0x43, 0x12, 0x4a, 0x35, 0xd9, 0x10, 0x26, 0xea, 0xd3, - 0x7c, 0x0b, 0x96, 0x8a, 0x4d, 0xaa, 0x17, 0xa8, 0xa1, 0x17, 0xe8, 0x62, 0x4e, 0x54, 0x0d, 0x66, - 0xee, 0x03, 0x44, 0x9c, 0x24, 0x1e, 0xf6, 0x2e, 0xc9, 0x28, 0xcb, 0xe2, 0x56, 0x75, 0x31, 0xa6, - 0x3f, 0x3e, 0x9d, 0xd3, 0xb8, 0x17, 0x50, 0x7c, 0x42, 0x46, 0xee, 0x82, 0xe2, 0xef, 0x9e, 0x90, - 0x91, 0x7a, 0x0b, 0x45, 0xec, 0x19, 0xe1, 0x7a, 0x9b, 0xd5, 0xdc, 0xf4, 0x60, 0xff, 0xde, 0x80, - 0x3b, 0x45, 0x3a, 0xf2, 0x72, 0x3d, 0x8d, 0x7b, 0x4a, 0xe2, 0x25, 0x71, 0xbb, 0x62, 0xed, 0xec, - 0x35, 0xd6, 0x7e, 0x04, 0x8b, 0x45, 0x83, 0x28, 0x7b, 0x6b, 0x53, 0xd8, 0xdb, 0xcc, 0x25, 0x4e, - 0xc8, 0xc8, 0xfe, 0x4d, 0xc5, 0xb6, 0xc3, 0x51, 0x65, 0xf6, 0xf1, 0xef, 0xb1, 0xad, 0x50, 0x5b, - 0xb5, 0x0d, 0x57, 0xe5, 0xaf, 0x38, 0x50, 0xbb, 0xea, 0x80, 0xfd, 0x47, 0x03, 0xd6, 0xab, 0x5a, - 0xc5, 0x39, 0x3b, 0xe5, 0x71, 0x48, 0x5e, 0xa6, 0xbd, 0x6c, 0xbf, 0xd9, 0x6a, 0xfb, 0x3d, 0x86, - 0xe5, 0x31, 0xa3, 0x44, 0x16, 0x8d, 0x9f, 0x4e, 0x55, 0x63, 0x95, 0xe9, 0xea, 0x2e, 0x55, 0xfd, - 0x10, 0x87, 0x8f, 0xbf, 0x79, 0xde, 0x32, 0xbe, 0x7d, 0xde, 0x32, 0xfe, 0xf5, 0xbc, 0x65, 0x7c, - 0xf9, 0xa2, 0x35, 0xf3, 0xed, 0x8b, 0xd6, 0xcc, 0x3f, 0x5e, 0xb4, 0x66, 0x7e, 0xf5, 0x61, 0x9f, - 0xca, 0x41, 0xdc, 0x73, 0x30, 0x1b, 0x66, 0x7f, 0x16, 0x74, 0x4a, 0x5d, 0xf7, 0x8a, 0xbf, 0x5d, - 0x92, 0xf7, 0x3b, 0x5f, 0x8c, 0xff, 0xa9, 0x23, 0x47, 0x11, 0x11, 0xbd, 0x79, 0x3d, 0x15, 0xde, - 0xfb, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf9, 0xed, 0x2b, 0xac, 0x05, 0x12, 0x00, 0x00, + 0x1d, 0x5e, 0x7a, 0xee, 0x31, 0xbd, 0x05, 0xbd, 0x34, 0xed, 0xdf, 0xd0, 0x4b, 0xaf, 0x3d, 0x05, + 0xbd, 0x34, 0xc7, 0x9e, 0xd2, 0x42, 0x3e, 0xf6, 0x6f, 0x28, 0x50, 0xcc, 0xec, 0x27, 0x29, 0xc9, + 0xa6, 0xe1, 0xf6, 0xb6, 0xf3, 0xe6, 0xbd, 0xdf, 0xfb, 0x7e, 0x6f, 0x48, 0xd8, 0xa5, 0xa1, 0x24, + 0x1c, 0xf7, 0x11, 0x0d, 0x3d, 0x41, 0x70, 0xcc, 0xa9, 0x1c, 0xb6, 0x31, 0x4e, 0xda, 0x11, 0x67, + 0x09, 0xf5, 0x09, 0x6f, 0x27, 0x3b, 0xc5, 0xb7, 0x13, 0x71, 0x26, 0x99, 0xf9, 0xce, 0x35, 0x32, + 0x0e, 0xc6, 0x89, 0x53, 0xf0, 0x25, 0x3b, 0xeb, 0xef, 0xde, 0x04, 0x9c, 0xec, 0xb4, 0x9f, 0x53, + 0x4e, 0x52, 0xac, 0xf5, 0xd5, 0x1e, 0xeb, 0x31, 0xfd, 0xd9, 0x56, 0x5f, 0x19, 0x75, 0xb3, 0xc7, + 0x58, 0x2f, 0x20, 0x6d, 0x7d, 0xea, 0xc6, 0x4f, 0xdb, 0x92, 0x0e, 0x88, 0x90, 0x68, 0x10, 0x65, + 0x0c, 0xad, 0x71, 0x06, 0x3f, 0xe6, 0x48, 0x52, 0x16, 0xe6, 0x00, 0xb4, 0x8b, 0xdb, 0x98, 0x71, + 0xd2, 0xc6, 0x01, 0x25, 0xa1, 0x54, 0x5a, 0xd3, 0xaf, 0x8c, 0xa1, 0xad, 0x18, 0x02, 0xda, 0xeb, + 0xcb, 0x94, 0x2c, 0xda, 0x92, 0x84, 0x3e, 0xe1, 0x03, 0x9a, 0x32, 0x97, 0xa7, 0x4c, 0x60, 0xa3, + 0x72, 0x8f, 0xf9, 0x30, 0x92, 0xac, 0x7d, 0x41, 0x86, 0x22, 0xbb, 0xbd, 0x87, 0x99, 0x18, 0x30, + 0xd1, 0x26, 0xca, 0xff, 0x10, 0x93, 0x76, 0xb2, 0xd3, 0x25, 0x12, 0xed, 0x14, 0x84, 0xdc, 0xee, + 0x8c, 0xaf, 0x8b, 0x44, 0xc9, 0x83, 0x19, 0xcd, 0xed, 0x5e, 0x4b, 0xef, 0xbd, 0x34, 0x22, 0xe9, + 0x21, 0xbd, 0xb2, 0xff, 0x33, 0x0b, 0x56, 0x87, 0x85, 0x22, 0x1e, 0x10, 0xbe, 0xef, 0xfb, 0x54, + 0x79, 0x7b, 0xc2, 0x59, 0xc4, 0x04, 0x0a, 0xcc, 0x55, 0x98, 0x91, 0x54, 0x06, 0xc4, 0x32, 0xb6, + 0x8c, 0xed, 0x86, 0x9b, 0x1e, 0xcc, 0x2d, 0x68, 0xfa, 0x44, 0x60, 0x4e, 0x23, 0xc5, 0x6c, 0x4d, + 0xeb, 0xbb, 0x2a, 0xc9, 0x5c, 0x83, 0xb9, 0x34, 0x45, 0xd4, 0xb7, 0x6a, 0xfa, 0xfa, 0x96, 0x3e, + 0x1f, 0xf9, 0xe6, 0xa7, 0xb0, 0x48, 0x43, 0x2a, 0x29, 0x0a, 0xbc, 0x3e, 0x51, 0x81, 0xb2, 0xea, + 0x5b, 0xc6, 0x76, 0x73, 0x77, 0xdd, 0xa1, 0x5d, 0xec, 0xa8, 0xd8, 0x3a, 0x59, 0x44, 0x93, 0x1d, + 0xe7, 0xa1, 0xe6, 0x38, 0xa8, 0x7f, 0xfb, 0xfd, 0xe6, 0x94, 0xbb, 0x90, 0xc9, 0xa5, 0x44, 0xf3, + 0x2e, 0xcc, 0xf7, 0x48, 0x48, 0x04, 0x15, 0x5e, 0x1f, 0x89, 0xbe, 0x35, 0xb3, 0x65, 0x6c, 0xcf, + 0xbb, 0xcd, 0x8c, 0xf6, 0x10, 0x89, 0xbe, 0xb9, 0x09, 0xcd, 0x2e, 0x0d, 0x11, 0x1f, 0xa6, 0x1c, + 0xb3, 0x9a, 0x03, 0x52, 0x92, 0x66, 0xe8, 0x00, 0x88, 0x08, 0x3d, 0x0f, 0x3d, 0x55, 0x08, 0xd6, + 0xad, 0xcc, 0x90, 0xb4, 0x08, 0x9c, 0xbc, 0x08, 0x9c, 0xb3, 0xbc, 0x4a, 0x0e, 0xe6, 0x94, 0x21, + 0x5f, 0xfd, 0x73, 0xd3, 0x70, 0x1b, 0x5a, 0x4e, 0xdd, 0x98, 0x9f, 0xc3, 0x72, 0x1c, 0x76, 0x59, + 0xe8, 0xd3, 0xb0, 0xe7, 0x45, 0x84, 0x53, 0xe6, 0x5b, 0x73, 0x1a, 0x6a, 0xed, 0x0a, 0xd4, 0x61, + 0x56, 0x4f, 0x29, 0xd2, 0xd7, 0x0a, 0x69, 0xa9, 0x10, 0x3e, 0xd1, 0xb2, 0xe6, 0x17, 0x60, 0x62, + 0x9c, 0x68, 0x93, 0x58, 0x2c, 0x73, 0xc4, 0xc6, 0xe4, 0x88, 0xcb, 0x18, 0x27, 0x67, 0xa9, 0x74, + 0x06, 0xf9, 0x6b, 0xb8, 0x23, 0x39, 0x0a, 0xc5, 0x53, 0xc2, 0xc7, 0x71, 0x61, 0x72, 0xdc, 0xb7, + 0x72, 0x8c, 0x51, 0xf0, 0x87, 0xb0, 0x85, 0xb3, 0x02, 0xf2, 0x38, 0xf1, 0xa9, 0x90, 0x9c, 0x76, + 0x63, 0x25, 0xeb, 0x3d, 0xe5, 0x08, 0xeb, 0x1a, 0x69, 0xea, 0x22, 0x68, 0xe5, 0x7c, 0xee, 0x08, + 0xdb, 0x27, 0x19, 0x97, 0xf9, 0x18, 0x7e, 0xd4, 0x0d, 0x18, 0xbe, 0x10, 0xca, 0x38, 0x6f, 0x04, + 0x49, 0xab, 0x1e, 0x50, 0x21, 0x14, 0xda, 0xfc, 0x96, 0xb1, 0x5d, 0x73, 0xef, 0xa6, 0xbc, 0x27, + 0x84, 0x1f, 0x56, 0x38, 0xcf, 0x2a, 0x8c, 0xe6, 0x7d, 0x30, 0xfb, 0x54, 0x48, 0xc6, 0x29, 0x46, + 0x81, 0x47, 0x42, 0xc9, 0x29, 0x11, 0xd6, 0x82, 0x16, 0xbf, 0x5d, 0xde, 0x3c, 0x48, 0x2f, 0xcc, + 0x47, 0x70, 0xf7, 0x46, 0xa5, 0x1e, 0xee, 0xa3, 0x30, 0x24, 0x81, 0xb5, 0xa8, 0x5d, 0xd9, 0xf4, + 0x6f, 0xd0, 0xd9, 0x49, 0xd9, 0xf6, 0xee, 0xfd, 0xf6, 0x9b, 0xcd, 0xa9, 0xaf, 0xbf, 0xd9, 0x9c, + 0xfa, 0xdb, 0x9f, 0xef, 0xaf, 0x67, 0x1d, 0xd7, 0x63, 0x89, 0x93, 0x75, 0xa7, 0xd3, 0x61, 0xa1, + 0x24, 0xa1, 0xb4, 0xff, 0x6e, 0xc0, 0x9d, 0x4e, 0x11, 0x96, 0x01, 0x4b, 0x50, 0xf0, 0xff, 0x6c, + 0xbf, 0x7d, 0x68, 0x08, 0xc9, 0xa2, 0xb4, 0xe0, 0xeb, 0xaf, 0x51, 0xf0, 0x73, 0x4a, 0x4c, 0x5d, + 0xec, 0xb5, 0x5e, 0xe1, 0xd1, 0x1f, 0x0c, 0x58, 0x7d, 0xf0, 0x2c, 0xa6, 0x09, 0xc3, 0xe8, 0x7f, + 0x32, 0x4d, 0x8e, 0x61, 0x81, 0x54, 0xf0, 0x84, 0x55, 0xdb, 0xaa, 0x6d, 0x37, 0x77, 0xdf, 0x75, + 0x32, 0x23, 0x8a, 0x61, 0x98, 0x5b, 0x52, 0xd5, 0xee, 0x8e, 0xca, 0xee, 0x4d, 0x5b, 0x86, 0xfd, + 0x57, 0x03, 0xd6, 0x55, 0x9e, 0x7a, 0xc4, 0x25, 0xcf, 0x11, 0xf7, 0x0f, 0x49, 0xc8, 0x06, 0xe2, + 0x8d, 0xed, 0xb4, 0x61, 0xc1, 0xd7, 0x48, 0x9e, 0x64, 0x1e, 0xf2, 0x7d, 0x6d, 0xa7, 0xe6, 0x51, + 0xc4, 0x33, 0xb6, 0xef, 0xfb, 0xe6, 0x36, 0x2c, 0x97, 0x3c, 0x5c, 0xe5, 0x5b, 0xa5, 0x41, 0xb1, + 0x2d, 0xe6, 0x6c, 0xba, 0x0a, 0x5e, 0x1d, 0xe6, 0x7f, 0x1b, 0xb0, 0xfc, 0x69, 0xc0, 0xba, 0x28, + 0x38, 0x0d, 0x90, 0xe8, 0xab, 0x1a, 0x1e, 0xaa, 0xf4, 0x72, 0x92, 0x0d, 0x0f, 0x6d, 0xfe, 0xc4, + 0xe9, 0x55, 0x62, 0x7a, 0x9c, 0x7d, 0x0c, 0xb7, 0x8b, 0x76, 0x2e, 0xaa, 0x48, 0x7b, 0x7b, 0xb0, + 0x72, 0xf9, 0xfd, 0xe6, 0x52, 0x5e, 0xac, 0x1d, 0x5d, 0x51, 0x87, 0xee, 0x12, 0x1e, 0x21, 0xf8, + 0x66, 0x0b, 0x9a, 0xb4, 0x8b, 0x3d, 0x41, 0x9e, 0x79, 0x61, 0x3c, 0xd0, 0x05, 0x58, 0x77, 0x1b, + 0xb4, 0x8b, 0x4f, 0xc9, 0xb3, 0xcf, 0xe3, 0x81, 0xf9, 0x3e, 0xbc, 0x9d, 0x6f, 0x74, 0x2f, 0x41, + 0x81, 0xa7, 0xe4, 0x55, 0xb8, 0xb8, 0xae, 0xc7, 0x79, 0x77, 0x25, 0xbf, 0x3d, 0x47, 0x81, 0x52, + 0xb6, 0xef, 0xfb, 0xdc, 0xfe, 0xcb, 0x0c, 0xcc, 0x9e, 0x20, 0x8e, 0x06, 0xc2, 0x3c, 0x83, 0x25, + 0x49, 0x06, 0x51, 0x80, 0x24, 0xf1, 0xd2, 0x55, 0x91, 0x79, 0xfa, 0x9e, 0x5e, 0x21, 0xd5, 0xed, + 0xeb, 0x54, 0xf6, 0x6d, 0xb2, 0xe3, 0x74, 0x34, 0xf5, 0x54, 0x22, 0x49, 0xdc, 0xc5, 0x1c, 0x23, + 0x25, 0x9a, 0x1f, 0x82, 0x25, 0x79, 0x2c, 0x64, 0x39, 0xc4, 0xcb, 0xe9, 0x95, 0xe6, 0xfa, 0xed, + 0xfc, 0x3e, 0x9d, 0x7b, 0xc5, 0xd4, 0xba, 0x7e, 0x5e, 0xd7, 0xde, 0x64, 0x5e, 0x9f, 0xc2, 0x8a, + 0x5a, 0x76, 0xe3, 0x98, 0xf5, 0xc9, 0x31, 0x6f, 0x2b, 0xf9, 0x51, 0xd0, 0x2f, 0xc0, 0x4c, 0x04, + 0x1e, 0xc7, 0x9c, 0x79, 0x0d, 0x3b, 0x13, 0x81, 0x47, 0x21, 0x7d, 0xd8, 0x10, 0xaa, 0xf8, 0xbc, + 0x01, 0x91, 0x7a, 0xfa, 0x47, 0x01, 0x09, 0xa9, 0xe8, 0xe7, 0xe0, 0xb3, 0x93, 0x83, 0xaf, 0x69, + 0xa0, 0xcf, 0x14, 0x8e, 0x9b, 0xc3, 0x64, 0x5a, 0x3a, 0xd0, 0xba, 0x5e, 0x4b, 0x91, 0xa0, 0x5b, + 0x3a, 0x41, 0x3f, 0xb8, 0x06, 0xa2, 0xc8, 0x92, 0x80, 0x7b, 0x95, 0x2d, 0xa5, 0xba, 0xde, 0xd3, + 0x0d, 0xe7, 0x71, 0xd2, 0x53, 0xa3, 0x1c, 0xa5, 0x0b, 0x8b, 0x90, 0x62, 0xd3, 0x66, 0xbd, 0xa7, + 0xde, 0x54, 0x95, 0xe6, 0xa3, 0x61, 0xf6, 0x1c, 0xb1, 0xcb, 0x65, 0x56, 0xcc, 0x10, 0xb7, 0x82, + 0xf5, 0x09, 0x21, 0x8f, 0xea, 0x73, 0x73, 0xcb, 0x0d, 0xfb, 0x27, 0xd0, 0xd0, 0x2d, 0xba, 0x8f, + 0x2f, 0x84, 0xb9, 0x01, 0x0d, 0x55, 0xeb, 0x44, 0x08, 0x22, 0x2c, 0x43, 0x77, 0x7e, 0x49, 0xb0, + 0x25, 0xac, 0xdd, 0xf4, 0x18, 0x13, 0xe6, 0x13, 0xb8, 0x15, 0x11, 0xfd, 0x52, 0xd0, 0x82, 0xcd, + 0xdd, 0x8f, 0x9c, 0x09, 0x9e, 0xcc, 0xce, 0x4d, 0x80, 0x6e, 0x8e, 0x66, 0xf3, 0xf2, 0x09, 0x38, + 0xb6, 0x82, 0x84, 0x79, 0x3e, 0xae, 0xf4, 0x67, 0xaf, 0xa5, 0x74, 0x0c, 0xaf, 0xd4, 0xf9, 0x1e, + 0x34, 0xf7, 0x53, 0xb7, 0x7f, 0x4e, 0x85, 0xbc, 0x1a, 0x96, 0xf9, 0x6a, 0x58, 0x1e, 0xc1, 0x62, + 0xb6, 0x57, 0xcf, 0x98, 0x1e, 0x33, 0xe6, 0x0f, 0x01, 0xb2, 0x85, 0xac, 0xc6, 0x53, 0x3a, 0xa8, + 0x1b, 0x19, 0xe5, 0xc8, 0x1f, 0xd9, 0x80, 0xd3, 0x23, 0x1b, 0xd0, 0x76, 0x61, 0xe9, 0x5c, 0xe0, + 0x5f, 0xe4, 0x8f, 0xae, 0xc7, 0x91, 0x30, 0xdf, 0x82, 0x59, 0xd5, 0x19, 0x19, 0x50, 0xdd, 0x9d, + 0x49, 0x04, 0x3e, 0xd2, 0xb3, 0xba, 0x7c, 0xd8, 0xb1, 0xc8, 0xa3, 0xbe, 0xb0, 0xa6, 0xb7, 0x6a, + 0xdb, 0x75, 0x77, 0x31, 0x2e, 0xc5, 0x8f, 0x7c, 0x61, 0xff, 0x12, 0x9a, 0x15, 0x40, 0x73, 0x11, + 0xa6, 0x0b, 0xac, 0x69, 0xea, 0x9b, 0x7b, 0xb0, 0x56, 0x02, 0x8d, 0x0e, 0xd7, 0x14, 0xb1, 0xe1, + 0xde, 0x29, 0x18, 0x46, 0xe6, 0xab, 0xb0, 0x1f, 0xc3, 0xea, 0x51, 0xd9, 0xca, 0xc5, 0xe8, 0x1e, + 0xf1, 0xd0, 0x18, 0xdd, 0xf1, 0x1b, 0xd0, 0x28, 0x7e, 0xd8, 0x68, 0xef, 0xeb, 0x6e, 0x49, 0xb0, + 0x07, 0xb0, 0x7c, 0x2e, 0xf0, 0x29, 0x09, 0xfd, 0x12, 0xec, 0x86, 0x00, 0x1c, 0x8c, 0x03, 0x4d, + 0xfc, 0x3a, 0x2e, 0xd5, 0x31, 0x58, 0x3b, 0x47, 0x01, 0xf5, 0x91, 0x64, 0xfc, 0x94, 0xc8, 0x74, + 0xed, 0x9e, 0x20, 0x7c, 0x41, 0xa4, 0x30, 0x5d, 0xa8, 0x07, 0x54, 0xc8, 0xac, 0xb2, 0x3e, 0xbc, + 0xb1, 0xb2, 0x92, 0x1d, 0xe7, 0x26, 0x90, 0x43, 0x24, 0x51, 0xd6, 0x91, 0x1a, 0xcb, 0xfe, 0x31, + 0xac, 0x7c, 0x86, 0x64, 0xcc, 0x89, 0x3f, 0x92, 0xe3, 0x65, 0xa8, 0xa9, 0xfc, 0x19, 0x3a, 0x7f, + 0xea, 0xd3, 0xfe, 0x93, 0x01, 0xd6, 0x83, 0x2f, 0x23, 0xc6, 0x25, 0xf1, 0xaf, 0x44, 0xe4, 0x25, + 0xe1, 0xbd, 0x80, 0x15, 0x15, 0x2c, 0x41, 0x42, 0xdf, 0x2b, 0xfc, 0x4c, 0xf3, 0xd8, 0xdc, 0xfd, + 0x60, 0xa2, 0xee, 0x18, 0x57, 0x97, 0x39, 0x70, 0x3b, 0x19, 0xa3, 0x0b, 0xfb, 0x77, 0x06, 0x58, + 0xc7, 0x64, 0xb8, 0x2f, 0x04, 0xed, 0x85, 0x03, 0x12, 0x4a, 0x35, 0xd9, 0x10, 0x26, 0xea, 0xd3, + 0x7c, 0x07, 0x16, 0x8a, 0x4d, 0xaa, 0x17, 0xa8, 0xa1, 0x17, 0xe8, 0x7c, 0x4e, 0x54, 0x0d, 0x66, + 0xee, 0x01, 0x44, 0x9c, 0x24, 0x1e, 0xf6, 0x2e, 0xc8, 0x30, 0xcb, 0xe2, 0x46, 0x75, 0x31, 0xa6, + 0x3f, 0x3b, 0x9d, 0x93, 0xb8, 0x1b, 0x50, 0x7c, 0x4c, 0x86, 0xee, 0x9c, 0xe2, 0xef, 0x1c, 0x93, + 0xa1, 0x7a, 0x09, 0x45, 0xec, 0x39, 0xe1, 0x7a, 0x9b, 0xd5, 0xdc, 0xf4, 0x60, 0xff, 0xde, 0x80, + 0x3b, 0x45, 0x3a, 0xf2, 0x72, 0x3d, 0x89, 0xbb, 0x4a, 0xe2, 0x25, 0x71, 0xbb, 0x62, 0xed, 0xf4, + 0x35, 0xd6, 0x7e, 0x0c, 0xf3, 0x45, 0x83, 0x28, 0x7b, 0x6b, 0x13, 0xd8, 0xdb, 0xcc, 0x25, 0x8e, + 0xc9, 0xd0, 0xfe, 0x4d, 0xc5, 0xb6, 0x83, 0x61, 0x65, 0xf6, 0xf1, 0x57, 0xd8, 0x56, 0xa8, 0xad, + 0xda, 0x86, 0xab, 0xf2, 0x57, 0x1c, 0xa8, 0x5d, 0x75, 0xc0, 0xfe, 0xa3, 0x01, 0xab, 0x55, 0xad, + 0xe2, 0x8c, 0x9d, 0xf0, 0x38, 0x24, 0x2f, 0xd3, 0x5e, 0xb6, 0xdf, 0x74, 0xb5, 0xfd, 0x9e, 0xc0, + 0xe2, 0x88, 0x51, 0x22, 0x8b, 0xc6, 0x4f, 0x27, 0xaa, 0xb1, 0xca, 0x74, 0x75, 0x17, 0xaa, 0x7e, + 0x88, 0x83, 0x27, 0xdf, 0x5e, 0xb6, 0x8c, 0xef, 0x2e, 0x5b, 0xc6, 0xbf, 0x2e, 0x5b, 0xc6, 0x57, + 0x2f, 0x5a, 0x53, 0xdf, 0xbd, 0x68, 0x4d, 0xfd, 0xe3, 0x45, 0x6b, 0xea, 0x57, 0x1f, 0xf5, 0xa8, + 0xec, 0xc7, 0x5d, 0x07, 0xb3, 0x41, 0xf6, 0x37, 0x41, 0xbb, 0xd4, 0x75, 0xbf, 0xf8, 0xc3, 0x25, + 0xf9, 0xa0, 0xfd, 0xe5, 0xe8, 0xdf, 0x39, 0x72, 0x18, 0x11, 0xd1, 0x9d, 0xd5, 0x53, 0xe1, 0xfd, + 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0xd4, 0xd2, 0x8c, 0xdc, 0xff, 0x11, 0x00, 0x00, } func (m *ConsumerAdditionProposal) Marshal() (dAtA []byte, err error) { From 506e4523aa9b5adfd1cbb0de56d7869b8aed4bf0 Mon Sep 17 00:00:00 2001 From: MSalopek Date: Tue, 23 Apr 2024 13:21:00 +0200 Subject: [PATCH 04/35] post-merge: update provider module --- x/ccv/provider/keeper/legacy_params.go | 7 +++++ x/ccv/provider/keeper/params.go | 5 ++-- x/ccv/provider/keeper/relay.go | 6 ++++- x/ccv/provider/keeper/validator_set_update.go | 18 +++++++++---- x/ccv/provider/migrations/migrator.go | 12 +++++---- x/ccv/provider/migrations/v4/migrations.go | 18 +------------ x/ccv/provider/migrations/v5/migrations.go | 22 +++++++++++++++ x/ccv/provider/module.go | 9 ++++--- x/ccv/provider/types/genesis_test.go | 27 ++++++++++--------- x/ccv/provider/types/params_test.go | 25 ++++++++--------- 10 files changed, 90 insertions(+), 59 deletions(-) create mode 100644 x/ccv/provider/migrations/v5/migrations.go diff --git a/x/ccv/provider/keeper/legacy_params.go b/x/ccv/provider/keeper/legacy_params.go index bea628e4ed..def88809ac 100644 --- a/x/ccv/provider/keeper/legacy_params.go +++ b/x/ccv/provider/keeper/legacy_params.go @@ -70,6 +70,12 @@ func getConsumerRewardDenomRegistrationFee(ctx sdk.Context, paramSpace paramtype return c } +func getBlocksPerEpoch(ctx sdk.Context, paramSpace paramtypes.Subspace) int64 { + var b int64 + paramSpace.Get(ctx, types.KeyBlocksPerEpoch, &b) + return b +} + // Legacy: Only for migration purposes. GetParamsLegacy returns the paramset for the provider // module from a given param subspace func GetParamsLegacy(ctx sdk.Context, paramspace paramtypes.Subspace) types.Params { @@ -82,5 +88,6 @@ func GetParamsLegacy(ctx sdk.Context, paramspace paramtypes.Subspace) types.Para getSlashMeterReplenishPeriod(ctx, paramspace), getSlashMeterReplenishFraction(ctx, paramspace), getConsumerRewardDenomRegistrationFee(ctx, paramspace), + getBlocksPerEpoch(ctx, paramspace), ) } diff --git a/x/ccv/provider/keeper/params.go b/x/ccv/provider/keeper/params.go index 1183a3feb4..9c1d276d4f 100644 --- a/x/ccv/provider/keeper/params.go +++ b/x/ccv/provider/keeper/params.go @@ -74,9 +74,8 @@ func (k Keeper) GetConsumerRewardDenomRegistrationFee(ctx sdk.Context) sdk.Coin // GetBlocksPerEpoch returns the number of blocks that constitute an epoch func (k Keeper) GetBlocksPerEpoch(ctx sdk.Context) int64 { - var b int64 - k.paramSpace.Get(ctx, types.KeyBlocksPerEpoch, &b) - return b + params := k.GetParams(ctx) + return params.BlocksPerEpoch } // GetParams returns the paramset for the provider module diff --git a/x/ccv/provider/keeper/relay.go b/x/ccv/provider/keeper/relay.go index 8f5702cfbe..7dcf568a5f 100644 --- a/x/ccv/provider/keeper/relay.go +++ b/x/ccv/provider/keeper/relay.go @@ -215,11 +215,15 @@ func (k Keeper) SendVSCPacketsToChain(ctx sdk.Context, chainID, channelID string } // QueueVSCPackets queues latest validator updates for every registered consumer chain +// failing to GetLastValidators will cause a panic in EndBlock func (k Keeper) QueueVSCPackets(ctx sdk.Context) { valUpdateID := k.GetValidatorSetUpdateId(ctx) // current valset update ID // get the bonded validators from the staking module - bondedValidators := k.stakingKeeper.GetLastValidators(ctx) + bondedValidators, err := k.stakingKeeper.GetLastValidators(ctx) + if err != nil { + panic(fmt.Errorf("failed to get last validators: %w", err)) + } for _, chain := range k.GetAllConsumerChains(ctx) { currentValidators := k.GetConsumerValSet(ctx, chain.ChainId) diff --git a/x/ccv/provider/keeper/validator_set_update.go b/x/ccv/provider/keeper/validator_set_update.go index d13b4b2b86..8cf3fe6d28 100644 --- a/x/ccv/provider/keeper/validator_set_update.go +++ b/x/ccv/provider/keeper/validator_set_update.go @@ -3,6 +3,7 @@ package keeper import ( "fmt" + storetypes "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -43,7 +44,7 @@ func (k Keeper) DeleteConsumerValSet( ) { store := ctx.KVStore(k.storeKey) key := types.ChainIdWithLenKey(types.ConsumerValidatorBytePrefix, chainID) - iterator := sdk.KVStorePrefixIterator(store, key) + iterator := storetypes.KVStorePrefixIterator(store, key) var keysToDel [][]byte defer iterator.Close() @@ -73,7 +74,7 @@ func (k Keeper) GetConsumerValSet( ) (validators []types.ConsumerValidator) { store := ctx.KVStore(k.storeKey) key := types.ChainIdWithLenKey(types.ConsumerValidatorBytePrefix, chainID) - iterator := sdk.KVStorePrefixIterator(store, key) + iterator := storetypes.KVStorePrefixIterator(store, key) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -97,13 +98,20 @@ func (k Keeper) ComputeNextEpochConsumerValSet( ) []types.ConsumerValidator { var nextValidators []types.ConsumerValidator for _, val := range bondedValidators { + valoper, err := k.ValidatorAddressCodec().StringToBytes(val.GetOperator()) + if err != nil { + panic(fmt.Errorf("could not decode validator operator: %w", err)) + } // get next voting power and the next consumer public key - nextPower := k.stakingKeeper.GetLastValidatorPower(ctx, val.GetOperator()) + nextPower, err := k.stakingKeeper.GetLastValidatorPower(ctx, valoper) + if err != nil { + panic(fmt.Errorf("could not get last validator power: %w", err)) + } consAddr, err := val.GetConsAddr() if err != nil { // this should never happen but is recoverable if we exclude this validator from the `nextValidators` k.Logger(ctx).Error("could not get consensus address of validator", - "validator", val.GetOperator().String(), + "validator", val.GetOperator(), "error", err) continue } @@ -112,7 +120,7 @@ func (k Keeper) ComputeNextEpochConsumerValSet( // if no consumer key assigned then use the validator's key itself k.Logger(ctx).Info("could not retrieve public key for validator on consumer chain because"+ " the validator did not assign a new consumer key", - "validator", val.GetOperator().String(), + "validator", val.GetOperator(), "chainID", chainID) nextConsumerPublicKey, err = val.TmConsPublicKey() if err != nil { diff --git a/x/ccv/provider/migrations/migrator.go b/x/ccv/provider/migrations/migrator.go index 7ffcb1a7a3..fc99bc45c7 100644 --- a/x/ccv/provider/migrations/migrator.go +++ b/x/ccv/provider/migrations/migrator.go @@ -7,6 +7,7 @@ import ( providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" v3 "github.com/cosmos/interchain-security/v5/x/ccv/provider/migrations/v3" v4 "github.com/cosmos/interchain-security/v5/x/ccv/provider/migrations/v4" + v5 "github.com/cosmos/interchain-security/v5/x/ccv/provider/migrations/v5" ) // Migrator is a struct for handling in-place store migrations. @@ -33,14 +34,15 @@ func (m Migrator) Migrate2to3(ctx sdktypes.Context) error { return v3.MigrateQueuedPackets(ctx, m.providerKeeper) } -// TODO: change to v5.MigrateParams after main merge -// func (m Migrator) Migrate3to4(ctx sdktypes.Context) error { -// return v4.MigrateParams(ctx, m.providerKeeper, m.paramSpace) -// } - // Migrate3to4 migrates x/ccvprovider state from consensus version 3 to 4. // The migration consists of provider chain params additions. func (m Migrator) Migrate3to4(ctx sdktypes.Context) error { v4.MigrateParams(ctx, m.paramSpace) return nil } + +// Migrate4to5 migrates x/ccvprovider state from consensus version 4 to 5. +// The migration consists of initializing new provider chain params using params from the legacy store. +func (m Migrator) Migrate4to5(ctx sdktypes.Context) error { + return v5.MigrateLegacyParams(ctx, m.providerKeeper, m.paramSpace) +} diff --git a/x/ccv/provider/migrations/v4/migrations.go b/x/ccv/provider/migrations/v4/migrations.go index 83078edaf7..e60c98700e 100644 --- a/x/ccv/provider/migrations/v4/migrations.go +++ b/x/ccv/provider/migrations/v4/migrations.go @@ -4,25 +4,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) -// TODO: add v5 migration post main merge - -// MigrateParams migrates the provider module's parameters from the x/params to self store. -func MigrateParams(ctx sdk.Context, keeper providerkeeper.Keeper, legacySubspace paramtypes.Subspace) error { - keeper.Logger(ctx).Info("starting provider params migration") - params := providerkeeper.GetParamsLegacy(ctx, legacySubspace) - err := params.Validate() - if err != nil { - return err - } - - keeper.SetParams(ctx, params) - keeper.Logger(ctx).Info("successfully migrated provider parameters") - return nil -} - // MigrateParams adds missing provider chain params to the param store. func MigrateParams(ctx sdk.Context, paramsSubspace paramtypes.Subspace) { if paramsSubspace.HasKeyTable() { diff --git a/x/ccv/provider/migrations/v5/migrations.go b/x/ccv/provider/migrations/v5/migrations.go new file mode 100644 index 0000000000..face264ddc --- /dev/null +++ b/x/ccv/provider/migrations/v5/migrations.go @@ -0,0 +1,22 @@ +package v4 + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" +) + +// MigrateParams migrates the provider module's parameters from the x/params to self store. +func MigrateLegacyParams(ctx sdk.Context, keeper providerkeeper.Keeper, legacySubspace paramtypes.Subspace) error { + keeper.Logger(ctx).Info("starting provider legacy params migration") + params := providerkeeper.GetParamsLegacy(ctx, legacySubspace) + err := params.Validate() + if err != nil { + return err + } + + keeper.SetParams(ctx, params) + keeper.Logger(ctx).Info("successfully migrated legacy provider parameters") + return nil +} diff --git a/x/ccv/provider/module.go b/x/ccv/provider/module.go index b91629e96a..debd77ed4b 100644 --- a/x/ccv/provider/module.go +++ b/x/ccv/provider/module.go @@ -127,8 +127,11 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { if err != nil { panic(err) } - if err := cfg.RegisterMigration(providertypes.ModuleName, 3, m.Migrate3to4); err != nil { - panic(fmt.Sprintf("failed to register migrator for %s: %s", providertypes.ModuleName, err)) + if err := cfg.RegisterMigration(providertypes.ModuleName, 3, migrator.Migrate3to4); err != nil { + panic(fmt.Sprintf("failed to register migrator for %s: %s -- from 3 -> 4", providertypes.ModuleName, err)) + } + if err := cfg.RegisterMigration(providertypes.ModuleName, 4, migrator.Migrate4to5); err != nil { + panic(fmt.Sprintf("failed to register migrator for %s: %s -- from 4 -> 4", providertypes.ModuleName, err)) } } @@ -150,7 +153,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 4 } +func (AppModule) ConsensusVersion() uint64 { return 5 } // BeginBlock implements the AppModule interface func (am AppModule) BeginBlock(ctx context.Context) error { diff --git a/x/ccv/provider/types/genesis_test.go b/x/ccv/provider/types/genesis_test.go index 523334e2f8..f040a2ee08 100644 --- a/x/ccv/provider/types/genesis_test.go +++ b/x/ccv/provider/types/genesis_test.go @@ -4,6 +4,7 @@ import ( "testing" "time" + "cosmossdk.io/math" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" @@ -81,7 +82,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 600), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), nil, nil, nil, @@ -102,7 +103,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 600), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), nil, nil, nil, @@ -123,7 +124,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 600), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), nil, nil, nil, @@ -144,7 +145,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 600), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), nil, nil, nil, @@ -171,7 +172,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 600), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), nil, nil, nil, @@ -198,7 +199,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 600), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), nil, nil, nil, @@ -225,7 +226,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: sdk.NewInt(1000000)}, 600), + sdk.Coin{Denom: "stake", Amount: math.NewInt(1000000)}, 600), nil, nil, nil, @@ -252,7 +253,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 600), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), nil, nil, nil, @@ -279,7 +280,7 @@ func TestValidateGenesisState(t *testing.T) { 0, // 0 vsc timeout here types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 600), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), nil, nil, nil, @@ -306,7 +307,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, 0, // 0 slash meter replenish period here types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 600), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), nil, nil, nil, @@ -333,7 +334,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, "1.15", - sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 600), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), nil, nil, nil, @@ -685,7 +686,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: sdk.NewInt(10000000)}, 600), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: math.NewInt(10000000)}, 600), nil, nil, nil, @@ -706,7 +707,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(-1000000)}, 600), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(-1000000)}, 600), nil, nil, nil, diff --git a/x/ccv/provider/types/params_test.go b/x/ccv/provider/types/params_test.go index c46dd7a55b..675ddd0bc5 100644 --- a/x/ccv/provider/types/params_test.go +++ b/x/ccv/provider/types/params_test.go @@ -4,6 +4,7 @@ import ( "testing" "time" + "cosmossdk.io/math" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" @@ -24,39 +25,39 @@ func TestValidateParams(t *testing.T) { {"custom valid params", types.NewParams( ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 1000), true}, + "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), true}, {"custom invalid params", types.NewParams( ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, 0, clienttypes.Height{}, nil, []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 1000), false}, + "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, {"blank client", types.NewParams(&ibctmtypes.ClientState{}, - "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 1000), false}, - {"nil client", types.NewParams(nil, "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 1000), false}, + "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, + {"nil client", types.NewParams(nil, "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, // Check if "0.00" is valid or if a zero dec TrustFraction needs to return an error {"0 trusting period fraction", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.00", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 1000), true}, + "0.00", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), true}, {"0 ccv timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", 0, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 1000), false}, + "0.33", 0, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, {"0 init timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, 0, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 1000), false}, + "0.33", time.Hour, 0, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, {"0 vsc timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 0, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 1000), false}, + "0.33", time.Hour, time.Hour, 0, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, {"0 slash meter replenish period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 24*time.Hour, 0, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 1000), false}, + "0.33", time.Hour, time.Hour, 24*time.Hour, 0, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, {"slash meter replenish fraction over 1", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "1.5", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}, 1000), false}, + "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "1.5", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, {"invalid consumer reward denom registration fee denom", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: sdk.NewInt(10000000)}, 1000), false}, + "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: math.NewInt(10000000)}, 1000), false}, {"invalid consumer reward denom registration fee amount", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: sdk.NewInt(-10000000)}, 1000), false}, + "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(-10000000)}, 1000), false}, } for _, tc := range testCases { From 594f532736da11aaea11f3aab2edc2fb6c0e90e5 Mon Sep 17 00:00:00 2001 From: MSalopek Date: Tue, 23 Apr 2024 13:25:13 +0200 Subject: [PATCH 05/35] post-merge: fix obvious test errs (imports etc.) --- tests/mbt/driver/core.go | 2 ++ tests/mbt/driver/mbt_test.go | 16 ++++++++-------- tests/mbt/driver/setup.go | 7 +++++-- testutil/integration/validators.go | 3 --- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/tests/mbt/driver/core.go b/tests/mbt/driver/core.go index c0b80669a6..62ed11671c 100644 --- a/tests/mbt/driver/core.go +++ b/tests/mbt/driver/core.go @@ -17,6 +17,7 @@ import ( "github.com/stretchr/testify/require" sdkmath "cosmossdk.io/math" + abcitypes "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" @@ -33,6 +34,7 @@ import ( consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // Define a new type for ChainIds to be more explicit diff --git a/tests/mbt/driver/mbt_test.go b/tests/mbt/driver/mbt_test.go index eaeea512f8..3e2cfe7901 100644 --- a/tests/mbt/driver/mbt_test.go +++ b/tests/mbt/driver/mbt_test.go @@ -10,6 +10,7 @@ import ( "testing" "time" + "cosmossdk.io/math" ibctesting "github.com/cosmos/ibc-go/v8/testing" "github.com/informalsystems/itf-go/itf" "github.com/kylelemons/godebug/pretty" @@ -19,11 +20,9 @@ import ( slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" tmencoding "github.com/cometbft/cometbft/crypto/encoding" - "github.com/cosmos/interchain-security/v5/testutil/integration" - cmttypes "github.com/cometbft/cometbft/types" - "github.com/cosmos/interchain-security/v5/testutil/integration" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" "github.com/cosmos/interchain-security/v5/x/ccv/types" ) @@ -163,8 +162,8 @@ func RunItfTrace(t *testing.T, path string) { trustingPeriodPerChain[ChainId(consumer)] = time.Duration(params["TrustingPeriodPerChain"].Value.(itf.MapExprType)[consumer].Value.(int64)) * time.Second ccvTimeoutPerChain[ChainId(consumer)] = time.Duration(params["CcvTimeout"].Value.(itf.MapExprType)[consumer].Value.(int64)) * time.Second } - downtimeSlashPercentage := sdk.NewDec(params["DowntimeSlashPercentage"].Value.(int64)) - doubleSignSlashPercentage := sdk.NewDec(params["DoubleSignSlashPercentage"].Value.(int64)) + downtimeSlashPercentage := math.LegacyNewDec(params["DowntimeSlashPercentage"].Value.(int64)) + doubleSignSlashPercentage := math.LegacyNewDec(params["DoubleSignSlashPercentage"].Value.(int64)) downtimeJailDuration := time.Duration(params["DowntimeJailDuration"].Value.(int64)) * time.Second modelParams := ModelParams{ @@ -222,7 +221,8 @@ func RunItfTrace(t *testing.T, path string) { driver.endAndBeginBlock("provider", 1*time.Nanosecond) } - slashingParams := driver.providerSlashingKeeper().GetParams(driver.providerCtx()) + slashingParams, err := driver.providerSlashingKeeper().GetParams(driver.providerCtx()) + require.NoError(t, err, "Error getting slashing params") slashingParams.DowntimeJailDuration = downtimeJailDuration driver.providerSlashingKeeper().SetParams(driver.providerCtx(), slashingParams) @@ -820,8 +820,8 @@ func CompareJailedValidators( modelJailEndTime := modelJailEndTimes[i] valConsAddr := sdk.ConsAddress(modelNamesToSystemConsAddr[modelJailedVal].Address) - valSigningInfo, found := driver.providerSlashingKeeper().GetValidatorSigningInfo(driver.providerCtx(), valConsAddr) - require.True(driver.t, found, "Error getting signing info for validator %v", modelJailedVal) + valSigningInfo, err := driver.providerSlashingKeeper().GetValidatorSigningInfo(driver.providerCtx(), valConsAddr) + require.NoError(driver.t, err, "Error getting signing info for validator %v", modelJailedVal) systemJailEndTime := valSigningInfo.JailedUntil actualTimeWithOffset := systemJailEndTime.Unix() - timeOffset.Unix() diff --git a/tests/mbt/driver/setup.go b/tests/mbt/driver/setup.go index fac4ba2da6..8024df7114 100644 --- a/tests/mbt/driver/setup.go +++ b/tests/mbt/driver/setup.go @@ -366,8 +366,11 @@ func (s *Driver) ConfigureNewPath(consumerChain, providerChain *ibctesting.TestC continue } - v, found := s.providerStakingKeeper().GetValidatorByConsAddr(s.providerCtx(), consAddr) - if !found { + v, err := s.providerStakingKeeper().GetValidatorByConsAddr(s.providerCtx(), consAddr) + // TODO: not sure why there was this code on ICS <= v5.x + // v, found := ... + // if !found { ... } + if err != nil { continue } stakingValidators = append(stakingValidators, v) diff --git a/testutil/integration/validators.go b/testutil/integration/validators.go index 64931af36b..83736f9058 100644 --- a/testutil/integration/validators.go +++ b/testutil/integration/validators.go @@ -1,14 +1,11 @@ package integration import ( -<<<<<<< HEAD -======= "fmt" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" "github.com/cosmos/cosmos-sdk/testutil/mock" ->>>>>>> main "github.com/cometbft/cometbft/abci/types" tmencoding "github.com/cometbft/cometbft/crypto/encoding" tmtypes "github.com/cometbft/cometbft/types" From 1b5bec285e7d6e47983347884f059f210bf000e7 Mon Sep 17 00:00:00 2001 From: MSalopek Date: Tue, 23 Apr 2024 14:38:49 +0200 Subject: [PATCH 06/35] post-merge: fix UT, IT and IT democ setup --- .../proposals_whitelisting_test.go | 26 ----------------- app/provider/app.go | 1 - app/provider/export.go | 1 - tests/integration/key_assignment.go | 3 +- tests/integration/unbonding.go | 2 +- tests/mbt/driver/setup.go | 2 +- testutil/ibc_testing/generic_setup.go | 2 +- testutil/integration/debug_test.go | 4 +++ testutil/integration/validators.go | 9 ++---- x/ccv/consumer/keeper/keeper.go | 2 +- x/ccv/provider/keeper/key_assignment_test.go | 29 +++---------------- x/ccv/provider/module.go | 1 - 12 files changed, 16 insertions(+), 66 deletions(-) delete mode 100644 app/consumer-democracy/proposals_whitelisting_test.go diff --git a/app/consumer-democracy/proposals_whitelisting_test.go b/app/consumer-democracy/proposals_whitelisting_test.go deleted file mode 100644 index d19932a8d8..0000000000 --- a/app/consumer-democracy/proposals_whitelisting_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package app_test - -import ( - "testing" - - ibctesting "github.com/cosmos/ibc-go/v8/testing" - "github.com/stretchr/testify/require" - - appConsumer "github.com/cosmos/interchain-security/v5/app/consumer-democracy" - icstestingutils "github.com/cosmos/interchain-security/v5/testutil/ibc_testing" - testutil "github.com/cosmos/interchain-security/v5/testutil/integration" -) - -func TestDemocracyGovernanceWhitelistingKeys(t *testing.T) { - _, valUpdates, _, err := testutil.CreateValidators(4, "consumer") - require.NoError(t, err) - ibctesting.DefaultTestingAppInit = icstestingutils.DemocracyConsumerAppIniter(valUpdates) - chain := ibctesting.NewTestChain(t, ibctesting.NewCoordinator(t, 0), "test") - paramKeeper := chain.App.(*appConsumer.App).ParamsKeeper - for paramKey := range appConsumer.LegacyWhitelistedParams { - ss, ok := paramKeeper.GetSubspace(paramKey.Subspace) - require.True(t, ok, "Unknown subspace %s", paramKey.Subspace) - hasKey := ss.Has(chain.GetContext(), []byte(paramKey.Key)) - require.True(t, hasKey, "Invalid key %s for subspace %s", paramKey.Key, paramKey.Subspace) - } -} diff --git a/app/provider/app.go b/app/provider/app.go index 42a3b99f90..b2042258d2 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -561,7 +561,6 @@ func New( ) // NOTE: @Msalopek -> ModuleBasic override is happening because Tx commands don't work without it - // TODO: double-check ModuleBasics = module.NewBasicManagerFromManager( app.MM, map[string]module.AppModuleBasic{ diff --git a/app/provider/export.go b/app/provider/export.go index a99ef9e83c..9fec37e3f2 100644 --- a/app/provider/export.go +++ b/app/provider/export.go @@ -96,7 +96,6 @@ func (app *App) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []str panic(err) } for _, delegation := range dels { - // NOTE: @MSalopek this may be wrong // TODO: add tests to figure this out (it's low impact since this is just a test app) delAddr, err := app.AccountKeeper.AddressCodec().StringToBytes(delegation.GetDelegatorAddr()) if err != nil { diff --git a/tests/integration/key_assignment.go b/tests/integration/key_assignment.go index 9eabdc0f49..b600c46b19 100644 --- a/tests/integration/key_assignment.go +++ b/tests/integration/key_assignment.go @@ -211,7 +211,8 @@ func (s *CCVTestSuite) TestKeyAssignment() { delegate(s, delAddr, bondAmt) // Send CCV packet to consumer - s.providerChain.NextBlock() + // s.providerChain.NextBlock() + s.nextEpoch() // Relay all VSC packets from provider to consumer relayAllCommittedPackets( diff --git a/tests/integration/unbonding.go b/tests/integration/unbonding.go index 7e366a266a..dedc3d6555 100644 --- a/tests/integration/unbonding.go +++ b/tests/integration/unbonding.go @@ -97,7 +97,7 @@ func (s *CCVTestSuite) TestUndelegationNormalOperation() { checkCCVUnbondingOp(s, s.providerCtx(), s.consumerChain.ChainID, valsetUpdateID, true, "test: "+tc.name) // call NextBlock on the provider (which increments the height) - s.providerChain.NextBlock() + s.nextEpoch() // unbond both on provider and consumer and check that // the balance remains unchanged in between diff --git a/tests/mbt/driver/setup.go b/tests/mbt/driver/setup.go index 8024df7114..b56222cb87 100644 --- a/tests/mbt/driver/setup.go +++ b/tests/mbt/driver/setup.go @@ -400,7 +400,7 @@ func (s *Driver) ConfigureNewPath(consumerChain, providerChain *ibctesting.TestC // their channel, and are ready for anything to happen. s.consumerKeeper(consumerChainId).SetProviderChannel(s.ctx(consumerChainId), consumerEndPoint.ChannelID) - // TODO: remove if not needed + // TODO: @MSalopek remove if not needed post main merge on release/v5.x branch // Commit a block on both chains, giving us two committed headers from // the same time and height. This is the starting point for all our // data driven testing. diff --git a/testutil/ibc_testing/generic_setup.go b/testutil/ibc_testing/generic_setup.go index ebdbf3da61..0df7174cbd 100644 --- a/testutil/ibc_testing/generic_setup.go +++ b/testutil/ibc_testing/generic_setup.go @@ -90,7 +90,7 @@ func AddDemocracyConsumer[T testutil.DemocConsumerApp]( s.T().Helper() // generate validators private/public key - valSet, valUpdates, signers, err := testutil.CreateValidators(4, "test") + valSet, valUpdates, signers, err := testutil.CreateValidators(4, "") require.NoError(s.T(), err) ibctesting.DefaultTestingAppInit = appIniter(valUpdates) diff --git a/testutil/integration/debug_test.go b/testutil/integration/debug_test.go index ea6f01b7ec..cac3c207c9 100644 --- a/testutil/integration/debug_test.go +++ b/testutil/integration/debug_test.go @@ -283,3 +283,7 @@ func TestHandleConsumerDoubleVotingSlashesUndelegationsAndRelegations(t *testing func TestSlashRetries(t *testing.T) { runCCVTestByName(t, "TestSlashRetries") } + +func TestKeyAssignment(t *testing.T) { + runCCVTestByName(t, "TestKeyAssignment") +} diff --git a/testutil/integration/validators.go b/testutil/integration/validators.go index 83736f9058..c317c2cf22 100644 --- a/testutil/integration/validators.go +++ b/testutil/integration/validators.go @@ -1,11 +1,6 @@ package integration import ( - "fmt" - - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - "github.com/cosmos/cosmos-sdk/testutil/mock" - "github.com/cometbft/cometbft/abci/types" tmencoding "github.com/cometbft/cometbft/crypto/encoding" tmtypes "github.com/cometbft/cometbft/types" @@ -26,8 +21,8 @@ func CreateValidators(n int, chainId string) ( signersByAddress = make(map[string]tmtypes.PrivValidator, n) ) for i := 0; i < n; i++ { - // privVal := tmtypes.NewMockPV() - privVal := mock.PV{PrivKey: ed25519.GenPrivKeyFromSecret([]byte(chainId + fmt.Sprint(i)))} + privVal := tmtypes.NewMockPV() + // privVal := mock.PV{PrivKey: ed25519.GenPrivKeyFromSecret([]byte(chainId + fmt.Sprint(i)))} pubKey, err := privVal.GetPubKey() if err != nil { return nil, nil, nil, err diff --git a/x/ccv/consumer/keeper/keeper.go b/x/ccv/consumer/keeper/keeper.go index 1f1756a82a..aa93398761 100644 --- a/x/ccv/consumer/keeper/keeper.go +++ b/x/ccv/consumer/keeper/keeper.go @@ -35,7 +35,7 @@ type Keeper struct { // should be the x/gov module account. authority string - storeKey storetypes.StoreKey // TODO: maybe needs to be removed? + storeKey storetypes.StoreKey storeService store.KVStoreService cdc codec.BinaryCodec scopedKeeper ccv.ScopedKeeper diff --git a/x/ccv/provider/keeper/key_assignment_test.go b/x/ccv/provider/keeper/key_assignment_test.go index 11248d5fab..6a0eae916f 100644 --- a/x/ccv/provider/keeper/key_assignment_test.go +++ b/x/ccv/provider/keeper/key_assignment_test.go @@ -361,12 +361,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(sdkCtx, consumerIdentities[0].SDKValConsAddress(), - // TODO: check this code after main branch is merged - // ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), - // mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower( - // sdkCtx, providerIdentities[0].SDKValOpAddress(), - // ).Return(int64(0), nil), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { @@ -389,21 +384,10 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, consumerIdentities[0].SDKValConsAddress(), - // TODO: check this code after main branch is merged - // ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), - // mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower( - // ctx, providerIdentities[0].SDKValOpAddress(), - // ).Return(int64(0), nil), - // mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, - // consumerIdentities[1].SDKValConsAddress(), - // ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), - // mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower( - // ctx, providerIdentities[0].SDKValOpAddress(), - // ).Return(int64(0), nil), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, consumerIdentities[1].SDKValConsAddress(), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), ) }, doActions: func(sdkCtx sdk.Context, k providerkeeper.Keeper) { @@ -430,12 +414,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, consumerIdentities[0].SDKValConsAddress(), - // TODO: check this code after main branch is merged - // ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), - // mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower( - // ctx, providerIdentities[0].SDKValOpAddress(), - // ).Return(int64(0), nil), - ).Return(stakingtypes.Validator{}, false), + ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, consumerIdentities[0].SDKValConsAddress(), ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), diff --git a/x/ccv/provider/module.go b/x/ccv/provider/module.go index debd77ed4b..ef35716f8c 100644 --- a/x/ccv/provider/module.go +++ b/x/ccv/provider/module.go @@ -122,7 +122,6 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { providertypes.RegisterQueryServer(cfg.QueryServer(), am.keeper) migrator := migrations.NewMigrator(*am.keeper, am.paramSpace) - // TODO: check/adapt 'fromVersion' once v0.50 branch merged with main err := cfg.RegisterMigration(am.Name(), 2, migrator.Migrate2to3) if err != nil { panic(err) From 28bab0419cf85bb920b72da4f36b01d5c7378006 Mon Sep 17 00:00:00 2001 From: MSalopek Date: Tue, 23 Apr 2024 17:48:32 +0200 Subject: [PATCH 07/35] post-merge: fix key assignment simulation test --- x/ccv/provider/keeper/key_assignment_test.go | 30 ++++++++----------- x/ccv/provider/keeper/validator_set_update.go | 2 +- .../keeper/validator_set_update_test.go | 2 +- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/x/ccv/provider/keeper/key_assignment_test.go b/x/ccv/provider/keeper/key_assignment_test.go index 6a0eae916f..dc0faf52d4 100644 --- a/x/ccv/provider/keeper/key_assignment_test.go +++ b/x/ccv/provider/keeper/key_assignment_test.go @@ -641,7 +641,6 @@ type Assignment struct { // of simulated scenarios where random key assignments and validator // set updates are generated. func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { - CHAINID := ChainID // The number of full test executions to run NUM_EXECUTIONS := 100 // Each test execution mimics the adding of a consumer chain and the @@ -727,15 +726,12 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower( gomock.Any(), gomock.Any(), - ).DoAndReturn(func(_ interface{}, valAddr sdk.ValAddress) int64 { + ).DoAndReturn(func(_ interface{}, valAddr sdk.ValAddress) (int64, error) { // When the mocked method is called, locate the appropriate validator // in the provider valset and return its power. for i, id := range providerIDS { - decodeValAddr, err := k.ValidatorAddressCodec().StringToBytes(id.SDKStakingValidator().GetOperator()) - require.NoError(t, err) - - if string(decodeValAddr) == valAddr.String() { - return providerValset.power[i] + if id.SDKStakingValidator().GetOperator() == valAddr.String() { + return providerValset.power[i], nil } } panic("must find validator") @@ -772,9 +768,9 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { }) } - nextValidators := k.ComputeNextEpochConsumerValSet(ctx, CHAINID, bondedValidators) - updates = providerkeeper.DiffValidators(k.GetConsumerValSet(ctx, CHAINID), nextValidators) - k.SetConsumerValSet(ctx, CHAINID, nextValidators) + nextValidators := k.ComputeNextEpochConsumerValSet(ctx, ChainID, bondedValidators) + updates = providerkeeper.DiffValidators(k.GetConsumerValSet(ctx, ChainID), nextValidators) + k.SetConsumerValSet(ctx, ChainID, nextValidators) consumerValset.apply(updates) // Simulate the VSCID update in EndBlock @@ -785,7 +781,7 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { applyAssignments := func(assignments []Assignment) { for _, a := range assignments { // ignore err return, it can be possible for an error to occur - _ = k.AssignConsumerKey(ctx, CHAINID, a.val, a.ck) + _ = k.AssignConsumerKey(ctx, ChainID, a.val, a.ck) } } @@ -800,7 +796,7 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { applyUpdatesAndIncrementVSCID(stakingUpdates) // Register the consumer chain - k.SetConsumerClientId(ctx, CHAINID, "") + k.SetConsumerClientId(ctx, ChainID, "") // Analogous to the last vscid received from the consumer in a maturity // Used to check the correct pruning property @@ -823,7 +819,7 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { prunedVscid := greatestPrunedVSCID + // +1 and -1 because id was incremented (-1), (+1) to make upper bound inclusive rng.Intn(int(k.GetValidatorSetUpdateId(ctx))+1-1-greatestPrunedVSCID) - k.PruneKeyAssignments(ctx, CHAINID, uint64(prunedVscid)) + k.PruneKeyAssignments(ctx, ChainID, uint64(prunedVscid)) greatestPrunedVSCID = prunedVscid /* @@ -843,7 +839,7 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { // For each active validator on the provider chain if 0 < providerValset.power[i] { // Get the assigned key - ck, found := k.GetValidatorConsumerPubKey(ctx, CHAINID, idP.ProviderConsAddress()) + ck, found := k.GetValidatorConsumerPubKey(ctx, ChainID, idP.ProviderConsAddress()) if !found { // Use default if unassigned ck = idP.TMProtoCryptoPublicKey() @@ -865,7 +861,7 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { consC := consumerValset.identities[i].ConsumerConsAddress() if 0 < consumerValset.power[i] { // Get the provider who assigned the key - consP := k.GetProviderAddrFromConsumerAddr(ctx, CHAINID, consC) + consP := k.GetProviderAddrFromConsumerAddr(ctx, ChainID, consC) // Find the corresponding provider validator (must always be found) for j, idP := range providerValset.identities { if idP.SDKValConsAddress().Equals(consP.ToSdkConsAddr()) { @@ -881,7 +877,7 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { Check that all keys have been or will eventually be pruned. */ - require.True(t, checkCorrectPruningProperty(ctx, k, CHAINID)) + require.True(t, checkCorrectPruningProperty(ctx, k, ChainID)) /* Property: Correct Consumer Initiated Slash Lookup @@ -899,7 +895,7 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { consC := consumerValset.identities[i].ConsumerConsAddress() if 0 < consumerValset.power[i] { // Get the provider who assigned the key - consP := k.GetProviderAddrFromConsumerAddr(ctx, CHAINID, consC) + consP := k.GetProviderAddrFromConsumerAddr(ctx, ChainID, consC) if _, found := historicSlashQueries[consC.String()]; !found { historicSlashQueries[consC.String()] = map[uint64]string{} diff --git a/x/ccv/provider/keeper/validator_set_update.go b/x/ccv/provider/keeper/validator_set_update.go index 8cf3fe6d28..8617d283cf 100644 --- a/x/ccv/provider/keeper/validator_set_update.go +++ b/x/ccv/provider/keeper/validator_set_update.go @@ -122,7 +122,7 @@ func (k Keeper) ComputeNextEpochConsumerValSet( " the validator did not assign a new consumer key", "validator", val.GetOperator(), "chainID", chainID) - nextConsumerPublicKey, err = val.TmConsPublicKey() + nextConsumerPublicKey, err = val.CmtConsPublicKey() if err != nil { // this should never happen and might not be recoverable because without the public key // we cannot generate a validator update diff --git a/x/ccv/provider/keeper/validator_set_update_test.go b/x/ccv/provider/keeper/validator_set_update_test.go index 103cf5aa79..7077663cc7 100644 --- a/x/ccv/provider/keeper/validator_set_update_test.go +++ b/x/ccv/provider/keeper/validator_set_update_test.go @@ -144,7 +144,7 @@ func TestComputeNextEpochConsumerValSet(t *testing.T) { valA := createStakingValidator(ctx, mocks, 1, 1) // because validator A has no consumer key set, the `ConsumerPublicKey` we expect is the key on the provider chain valAConsAddr, _ := valA.GetConsAddr() - valAPublicKey, _ := valA.TmConsPublicKey() + valAPublicKey, _ := valA.CmtConsPublicKey() expectedValidators = append(expectedValidators, types.ConsumerValidator{ ProviderConsAddr: types.NewProviderConsAddress(valAConsAddr).Address.Bytes(), Power: 1, From c533e8ded6853745849c17139fed5d61b0c17cc4 Mon Sep 17 00:00:00 2001 From: MSalopek Date: Tue, 23 Apr 2024 17:51:20 +0200 Subject: [PATCH 08/35] post-merge: fix provider UTs --- x/ccv/provider/keeper/relay_test.go | 4 ++-- x/ccv/provider/keeper/validator_set_update_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x/ccv/provider/keeper/relay_test.go b/x/ccv/provider/keeper/relay_test.go index 2f6dddf985..113a3acef2 100644 --- a/x/ccv/provider/keeper/relay_test.go +++ b/x/ccv/provider/keeper/relay_test.go @@ -682,8 +682,8 @@ func TestEndBlockVSU(t *testing.T) { for i := 0; i < 4; i++ { lastValidators = append(lastValidators, cryptotestutil.NewCryptoIdentityFromIntSeed(i).SDKStakingValidator()) } - mocks.MockStakingKeeper.EXPECT().GetLastValidators(gomock.Any()).Return(lastValidators).AnyTimes() - mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(gomock.Any(), gomock.Any()).Return(int64(2)).AnyTimes() + mocks.MockStakingKeeper.EXPECT().GetLastValidators(gomock.Any()).Return(lastValidators, nil).AnyTimes() + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(gomock.Any(), gomock.Any()).Return(int64(2), nil).AnyTimes() // set a sample client for a consumer chain so that `GetAllConsumerChains` in `QueueVSCPackets` iterates at least once providerKeeper.SetConsumerClientId(ctx, "chainID", "clientID") diff --git a/x/ccv/provider/keeper/validator_set_update_test.go b/x/ccv/provider/keeper/validator_set_update_test.go index 7077663cc7..8808cf140d 100644 --- a/x/ccv/provider/keeper/validator_set_update_test.go +++ b/x/ccv/provider/keeper/validator_set_update_test.go @@ -121,13 +121,13 @@ func TestComputeNextEpochConsumerValSet(t *testing.T) { providerConsPubKey := ed25519.GenPrivKeyFromSecret([]byte{byte(index)}).PubKey() consAddr := sdk.ConsAddress(providerConsPubKey.Address()) providerAddr := types.NewProviderConsAddress(consAddr) - pk, _ := cryptocodec.FromTmPubKeyInterface(providerConsPubKey) + pk, _ := cryptocodec.FromCmtPubKeyInterface(providerConsPubKey) pkAny, _ := codectypes.NewAnyWithValue(pk) var providerValidatorAddr sdk.ValAddress = providerAddr.Address.Bytes() mocks.MockStakingKeeper.EXPECT(). - GetLastValidatorPower(ctx, providerValidatorAddr).Return(power).AnyTimes() + GetLastValidatorPower(ctx, providerValidatorAddr).Return(power, nil).AnyTimes() return stakingtypes.Validator{ OperatorAddress: providerValidatorAddr.String(), From e4c8f975ac895c6512674e31cc22c94e670fb4a4 Mon Sep 17 00:00:00 2001 From: MSalopek Date: Tue, 23 Apr 2024 19:18:23 +0200 Subject: [PATCH 09/35] post-merge: fix slashing integration test --- tests/integration/slashing.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/integration/slashing.go b/tests/integration/slashing.go index 13ad5f3c1e..de5c7171e9 100644 --- a/tests/integration/slashing.go +++ b/tests/integration/slashing.go @@ -70,7 +70,7 @@ func (s *CCVTestSuite) TestRelayAndApplyDowntimePacket() { // convert validator to TM type pk, err := stakingVal.ConsPubKey() s.Require().NoError(err) - tmPk, err := cryptocodec.ToTmPubKeyInterface(pk) + tmPk, err := cryptocodec.ToCmtPubKeyInterface(pk) s.Require().NoError(err) s.setDefaultValSigningInfo(*tmtypes.NewValidator(tmPk, stakingVal.ConsensusPower(sdk.DefaultPowerReduction))) @@ -103,7 +103,8 @@ func (s *CCVTestSuite) TestRelayAndApplyDowntimePacket() { s.Require().NoError(err) s.Require().Equal(heightBefore+2, heightAfter) - // We've now advanced two blocks. + // this call was added starging cosmos-sdk v0.50.x + s.nextEpoch() // VSC packets should have been sent from provider during block N to each consumer expectedSentValsetUpdateId := valsetUpdateIdN @@ -187,7 +188,7 @@ func (s *CCVTestSuite) TestRelayAndApplyDoubleSignPacket() { tmVal := s.consumerChain.Vals.Validators[0] val, err := tmVal.ToProto() s.Require().NoError(err) - pubkey, err := cryptocodec.FromTmProtoPublicKey(val.GetPubKey()) + pubkey, err := cryptocodec.FromCmtProtoPublicKey(val.GetPubKey()) s.Require().Nil(err) consumerConsAddr := providertypes.NewConsumerConsAddress(sdk.GetConsAddress(pubkey)) // map consumer consensus address to provider consensus address @@ -205,7 +206,7 @@ func (s *CCVTestSuite) TestRelayAndApplyDoubleSignPacket() { // convert validator to TM type pk, err := stakingVal.ConsPubKey() s.Require().NoError(err) - tmPk, err := cryptocodec.ToTmPubKeyInterface(pk) + tmPk, err := cryptocodec.ToCmtPubKeyInterface(pk) s.Require().NoError(err) s.setDefaultValSigningInfo(*tmtypes.NewValidator(tmPk, stakingVal.ConsensusPower(sdk.DefaultPowerReduction))) From 471b46ca2ba91c7c46fa887f54bec31d721ff49e Mon Sep 17 00:00:00 2001 From: MSalopek Date: Tue, 23 Apr 2024 19:18:46 +0200 Subject: [PATCH 10/35] post-merge: fix replace deprecated tm methods --- tests/integration/valset_update.go | 8 ++++---- x/ccv/consumer/keeper/changeover_test.go | 4 ++-- x/ccv/consumer/keeper/genesis_test.go | 2 +- x/ccv/consumer/keeper/keeper_test.go | 4 ++-- x/ccv/consumer/keeper/relay_test.go | 6 +++--- x/ccv/consumer/keeper/validators.go | 2 +- x/ccv/provider/keeper/keeper_test.go | 2 +- x/ccv/provider/keeper/relay_test.go | 2 +- x/ccv/types/utils_test.go | 4 ++-- x/ccv/types/wire_test.go | 6 +++--- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/integration/valset_update.go b/tests/integration/valset_update.go index d906171753..994dfab4af 100644 --- a/tests/integration/valset_update.go +++ b/tests/integration/valset_update.go @@ -45,13 +45,13 @@ func (suite *CCVTestSuite) TestQueueAndSendVSCMaturedPackets() { suite.SetupCCVChannel(suite.path) // send 3 packets to consumer chain at different times - pk, err := cryptocodec.FromTmPubKeyInterface(suite.providerChain.Vals.Validators[0].PubKey) + pk, err := cryptocodec.FromCmtPubKeyInterface(suite.providerChain.Vals.Validators[0].PubKey) suite.Require().NoError(err) - pk1, err := cryptocodec.ToTmProtoPublicKey(pk) + pk1, err := cryptocodec.ToCmtProtoPublicKey(pk) suite.Require().NoError(err) - pk, err = cryptocodec.FromTmPubKeyInterface(suite.providerChain.Vals.Validators[1].PubKey) + pk, err = cryptocodec.FromCmtPubKeyInterface(suite.providerChain.Vals.Validators[1].PubKey) suite.Require().NoError(err) - pk2, err := cryptocodec.ToTmProtoPublicKey(pk) + pk2, err := cryptocodec.ToCmtProtoPublicKey(pk) suite.Require().NoError(err) pd := ccv.NewValidatorSetChangePacketData( diff --git a/x/ccv/consumer/keeper/changeover_test.go b/x/ccv/consumer/keeper/changeover_test.go index c2d7cda190..4f52fc926e 100644 --- a/x/ccv/consumer/keeper/changeover_test.go +++ b/x/ccv/consumer/keeper/changeover_test.go @@ -124,7 +124,7 @@ func TestChangeoverToConsumer(t *testing.T) { for _, ccVal := range ccVals { ccvValPubKey, err := ccVal.ConsPubKey() require.NoError(t, err) - tmProtoPubKey, err := sdkcryptocodec.ToTmProtoPublicKey(ccvValPubKey) + tmProtoPubKey, err := sdkcryptocodec.ToCmtProtoPublicKey(ccvValPubKey) require.NoError(t, err) if tmProtoPubKey.Equal(valUpdate.PubKey) { found = true @@ -150,7 +150,7 @@ func TestChangeoverToConsumer(t *testing.T) { for _, val := range tc.lastSovVals { ccvValPubKey, err := val.ConsPubKey() require.NoError(t, err) - tmProtoPubKey, err := sdkcryptocodec.ToTmProtoPublicKey(ccvValPubKey) + tmProtoPubKey, err := sdkcryptocodec.ToCmtProtoPublicKey(ccvValPubKey) require.NoError(t, err) if returnedValUpdate.PubKey.Equal(tmProtoPubKey) { // If val was already matched to a val update for new set, it's power won't be 0 diff --git a/x/ccv/consumer/keeper/genesis_test.go b/x/ccv/consumer/keeper/genesis_test.go index dc555554fb..780b2ba34a 100644 --- a/x/ccv/consumer/keeper/genesis_test.go +++ b/x/ccv/consumer/keeper/genesis_test.go @@ -248,7 +248,7 @@ func TestExportGenesis(t *testing.T) { // mock a validator set pubKey := ed25519.GenPrivKey().PubKey() - tmPK, err := cryptocodec.ToTmPubKeyInterface(pubKey) + tmPK, err := cryptocodec.ToCmtPubKeyInterface(pubKey) require.NoError(t, err) validator := tmtypes.NewValidator(tmPK, 1) abciValidator := abci.Validator{Address: pubKey.Address(), Power: int64(1)} diff --git a/x/ccv/consumer/keeper/keeper_test.go b/x/ccv/consumer/keeper/keeper_test.go index 51117c9683..87a8a5051f 100644 --- a/x/ccv/consumer/keeper/keeper_test.go +++ b/x/ccv/consumer/keeper/keeper_test.go @@ -51,9 +51,9 @@ func TestProviderChannel(t *testing.T) { // TestPendingChanges tests getter, setter, and delete functionality for pending VSCs on a consumer chain func TestPendingChanges(t *testing.T) { - pk1, err := cryptocodec.ToTmProtoPublicKey(ed25519.GenPrivKey().PubKey()) + pk1, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) require.NoError(t, err) - pk2, err := cryptocodec.ToTmProtoPublicKey(ed25519.GenPrivKey().PubKey()) + pk2, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) require.NoError(t, err) pd := ccv.NewValidatorSetChangePacketData( diff --git a/x/ccv/consumer/keeper/relay_test.go b/x/ccv/consumer/keeper/relay_test.go index e26a53a645..d3ab3778e1 100644 --- a/x/ccv/consumer/keeper/relay_test.go +++ b/x/ccv/consumer/keeper/relay_test.go @@ -33,11 +33,11 @@ func TestOnRecvVSCPacket(t *testing.T) { consumerCCVChannelID := "consumerCCVChannelID" providerCCVChannelID := "providerCCVChannelID" - pk1, err := cryptocodec.ToTmProtoPublicKey(ed25519.GenPrivKey().PubKey()) + pk1, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) require.NoError(t, err) - pk2, err := cryptocodec.ToTmProtoPublicKey(ed25519.GenPrivKey().PubKey()) + pk2, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) require.NoError(t, err) - pk3, err := cryptocodec.ToTmProtoPublicKey(ed25519.GenPrivKey().PubKey()) + pk3, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) require.NoError(t, err) changes1 := []abci.ValidatorUpdate{ diff --git a/x/ccv/consumer/keeper/validators.go b/x/ccv/consumer/keeper/validators.go index de53bdd1db..b1b62a3a40 100644 --- a/x/ccv/consumer/keeper/validators.go +++ b/x/ccv/consumer/keeper/validators.go @@ -323,7 +323,7 @@ func (k Keeper) MustGetCurrentValidatorsAsABCIUpdates(ctx sdk.Context) []abci.Va // to be stored correctly in ApplyCCValidatorChanges. panic(err) } - tmPK, err := cryptocodec.ToTmProtoPublicKey(pk) + tmPK, err := cryptocodec.ToCmtProtoPublicKey(pk) if err != nil { // This should never happen as the pubkey is assumed // to be stored correctly in ApplyCCValidatorChanges. diff --git a/x/ccv/provider/keeper/keeper_test.go b/x/ccv/provider/keeper/keeper_test.go index 954a0e6873..6e117551b7 100644 --- a/x/ccv/provider/keeper/keeper_test.go +++ b/x/ccv/provider/keeper/keeper_test.go @@ -159,7 +159,7 @@ func TestPendingVSCs(t *testing.T) { _, pks, _ := ibctesting.GenerateKeys(t, 4) var ppks [4]tmprotocrypto.PublicKey for i, pk := range pks { - ppks[i], _ = cryptocodec.ToTmProtoPublicKey(pk) + ppks[i], _ = cryptocodec.ToCmtProtoPublicKey(pk) } packetList := []ccv.ValidatorSetChangePacketData{ diff --git a/x/ccv/provider/keeper/relay_test.go b/x/ccv/provider/keeper/relay_test.go index 113a3acef2..5b11e44d33 100644 --- a/x/ccv/provider/keeper/relay_test.go +++ b/x/ccv/provider/keeper/relay_test.go @@ -27,7 +27,7 @@ import ( // TestQueueVSCPackets tests queueing validator set updates. func TestQueueVSCPackets(t *testing.T) { _, _, key := ibctesting.GenerateKeys(t, 1) - tmPubKey, _ := cryptocodec.ToTmProtoPublicKey(key) + tmPubKey, _ := cryptocodec.ToCmtProtoPublicKey(key) testCases := []struct { name string diff --git a/x/ccv/types/utils_test.go b/x/ccv/types/utils_test.go index c3b04f3460..081570abf2 100644 --- a/x/ccv/types/utils_test.go +++ b/x/ccv/types/utils_test.go @@ -16,8 +16,8 @@ import ( func TestAccumulateChanges(t *testing.T) { _, testKeys, _ := ibctesting.GenerateKeys(t, 2) - tmPubKey, _ := cryptocodec.ToTmProtoPublicKey(testKeys[0]) - tmPubKey2, _ := cryptocodec.ToTmProtoPublicKey(testKeys[1]) + tmPubKey, _ := cryptocodec.ToCmtProtoPublicKey(testKeys[0]) + tmPubKey2, _ := cryptocodec.ToCmtProtoPublicKey(testKeys[1]) testCases := []struct { name string diff --git a/x/ccv/types/wire_test.go b/x/ccv/types/wire_test.go index 93512a5218..300ed7071f 100644 --- a/x/ccv/types/wire_test.go +++ b/x/ccv/types/wire_test.go @@ -17,7 +17,7 @@ import ( ) func TestPacketDataValidateBasic(t *testing.T) { - pk, err := cryptocodec.ToTmProtoPublicKey(ed25519.GenPrivKey().PubKey()) + pk, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) require.NoError(t, err) cases := []struct { @@ -67,9 +67,9 @@ func TestPacketDataValidateBasic(t *testing.T) { } func TestMarshalPacketData(t *testing.T) { - pk1, err := cryptocodec.ToTmProtoPublicKey(ed25519.GenPrivKey().PubKey()) + pk1, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) require.NoError(t, err) - pk2, err := cryptocodec.ToTmProtoPublicKey(ed25519.GenPrivKey().PubKey()) + pk2, err := cryptocodec.ToCmtProtoPublicKey(ed25519.GenPrivKey().PubKey()) require.NoError(t, err) vpd := types.NewValidatorSetChangePacketData( From c866fe2e27ae07ba1487ec36cd4ffc6b888aeb67 Mon Sep 17 00:00:00 2001 From: MSalopek Date: Wed, 24 Apr 2024 21:06:38 +0200 Subject: [PATCH 11/35] feat: add consumer params upgrade message (#1814) * feat: add consumer params upgrade message * register tx services on consumer * register tx services on consumer * feat: add consumer params query * tests: add consumer param change tests --- .../proposals_whitelisting.go | 15 +- .../ccv/consumer/v1/tx.proto | 29 + tests/integration/democracy.go | 48 ++ testutil/integration/debug_test.go | 4 + x/ccv/consumer/client/cli/query.go | 28 + x/ccv/consumer/keeper/keeper.go | 5 + x/ccv/consumer/keeper/msg_server.go | 36 ++ x/ccv/consumer/module.go | 3 +- x/ccv/consumer/types/codec.go | 18 + x/ccv/consumer/types/tx.pb.go | 598 ++++++++++++++++++ 10 files changed, 776 insertions(+), 8 deletions(-) create mode 100644 proto/interchain_security/ccv/consumer/v1/tx.proto create mode 100644 x/ccv/consumer/keeper/msg_server.go create mode 100644 x/ccv/consumer/types/codec.go create mode 100644 x/ccv/consumer/types/tx.pb.go diff --git a/app/consumer-democracy/proposals_whitelisting.go b/app/consumer-democracy/proposals_whitelisting.go index 383d297505..fb333dc014 100644 --- a/app/consumer-democracy/proposals_whitelisting.go +++ b/app/consumer-democracy/proposals_whitelisting.go @@ -39,13 +39,14 @@ var LegacyWhitelistedParams = map[legacyParamChangeKey]struct{}{ // add whitelisted module param update messages [cosmos-sdk >= 0.47] var WhiteListModule = map[string]struct{}{ - "/cosmos.gov.v1.MsgUpdateParams": {}, - "/cosmos.bank.v1beta1.MsgUpdateParams": {}, - "/cosmos.staking.v1beta1.MsgUpdateParams": {}, - "/cosmos.distribution.v1beta1.MsgUpdateParams": {}, - "/cosmos.mint.v1beta1.MsgUpdateParams": {}, - "/cosmos.gov.v1beta1.TextProposal": {}, - "/ibc.applications.transfer.v1.MsgUpdateParams": {}, + "/cosmos.gov.v1.MsgUpdateParams": {}, + "/cosmos.bank.v1beta1.MsgUpdateParams": {}, + "/cosmos.staking.v1beta1.MsgUpdateParams": {}, + "/cosmos.distribution.v1beta1.MsgUpdateParams": {}, + "/cosmos.mint.v1beta1.MsgUpdateParams": {}, + "/cosmos.gov.v1beta1.TextProposal": {}, + "/ibc.applications.transfer.v1.MsgUpdateParams": {}, + "/interchain_security.ccv.consumer.v1.MsgUpdateParams": {}, } func IsModuleWhiteList(typeUrl string) bool { diff --git a/proto/interchain_security/ccv/consumer/v1/tx.proto b/proto/interchain_security/ccv/consumer/v1/tx.proto new file mode 100644 index 0000000000..e76b8dd3b9 --- /dev/null +++ b/proto/interchain_security/ccv/consumer/v1/tx.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; +package interchain_security.ccv.consumer.v1; +option go_package = "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types"; + +import "amino/amino.proto"; +import "google/api/annotations.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/msg/v1/msg.proto"; +import "interchain_security/ccv/v1/shared_consumer.proto"; + +// Msg defines the Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); +} + +// MsgUpdateParams is the Msg/UpdateParams request type +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "authority"; + + // signer is the address of the governance account. + string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + + // params defines the x/provider parameters to update. + interchain_security.ccv.v1.ConsumerParams params = 2 [(gogoproto.nullable) = false]; +} + +message MsgUpdateParamsResponse {} diff --git a/tests/integration/democracy.go b/tests/integration/democracy.go index 100018879d..5fe7e9eb6d 100644 --- a/tests/integration/democracy.go +++ b/tests/integration/democracy.go @@ -271,6 +271,54 @@ func (s *ConsumerDemocracyTestSuite) TestDemocracyGovernanceWhitelisting() { s.Assert().Equal(votersOldBalances, getAccountsBalances(s.consumerCtx(), bankKeeper, bondDenom, votingAccounts)) } +func (s *ConsumerDemocracyTestSuite) TestDemocracyMsgUpdateParams() { + govKeeper := s.consumerApp.GetTestGovKeeper() + params, err := govKeeper.Params.Get(s.consumerCtx()) + s.Require().NoError(err) + + stakingKeeper := s.consumerApp.GetTestStakingKeeper() + bankKeeper := s.consumerApp.GetTestBankKeeper() + votingAccounts := s.consumerChain.SenderAccounts + bondDenom, err := stakingKeeper.BondDenom(s.consumerCtx()) + s.Require().NoError(err) + depositAmount := params.MinDeposit + duration := (3 * time.Second) + params.VotingPeriod = &duration + err = govKeeper.Params.Set(s.consumerCtx(), params) + s.Assert().NoError(err) + proposer := s.consumerChain.SenderAccount + s.consumerChain.NextBlock() + votersOldBalances := getAccountsBalances(s.consumerCtx(), bankKeeper, bondDenom, votingAccounts) + + oldParams := s.consumerApp.GetConsumerKeeper().GetConsumerParams(s.consumerCtx()) + modifiedParams := oldParams + modifiedParams.RetryDelayPeriod = 7200 * time.Second + s.Require().NotEqual(oldParams.RetryDelayPeriod, modifiedParams.RetryDelayPeriod) + + msg := &consumertypes.MsgUpdateParams{ + Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(), + Params: modifiedParams, + } + + err = submitProposalWithDepositAndVote(govKeeper, s.consumerCtx(), []sdk.Msg{msg}, votingAccounts, proposer.GetAddress(), depositAmount) + s.Assert().NoError(err) + // set current header time to be equal or later than voting end time in order to process proposal from active queue, + // once the proposal is added to the chain + s.consumerChain.CurrentHeader.Time = s.consumerChain.CurrentHeader.Time.Add(*params.VotingPeriod) + + s.consumerChain.NextBlock() + + newParams := s.consumerApp.GetConsumerKeeper().GetConsumerParams(s.consumerCtx()) + s.Assert().NotEqual(oldParams, newParams) + s.Assert().Equal(modifiedParams, newParams) + s.Assert().NotEqual(oldParams.RetryDelayPeriod, newParams.RetryDelayPeriod) + s.Assert().Equal(modifiedParams.RetryDelayPeriod, newParams.RetryDelayPeriod) + + // deposit is refunded + s.Assert().Equal(votersOldBalances, getAccountsBalances(s.consumerCtx(), bankKeeper, bondDenom, votingAccounts)) + +} + func submitProposalWithDepositAndVote(govKeeper govkeeper.Keeper, ctx sdk.Context, msgs []sdk.Msg, accounts []ibctesting.SenderAccount, proposer sdk.AccAddress, depositAmount sdk.Coins, ) error { diff --git a/testutil/integration/debug_test.go b/testutil/integration/debug_test.go index cac3c207c9..1708cbf6c2 100644 --- a/testutil/integration/debug_test.go +++ b/testutil/integration/debug_test.go @@ -69,6 +69,10 @@ func TestDemocracyGovernanceWhitelisting(t *testing.T) { runConsumerDemocracyTestByName(t, "TestDemocracyGovernanceWhitelisting") } +func TestDemocracyMsgUpdateParams(t *testing.T) { + runConsumerDemocracyTestByName(t, "TestDemocracyMsgUpdateParams") +} + // // Distribution tests // diff --git a/x/ccv/consumer/client/cli/query.go b/x/ccv/consumer/client/cli/query.go index 3630b3ed3f..c047ae775d 100644 --- a/x/ccv/consumer/client/cli/query.go +++ b/x/ccv/consumer/client/cli/query.go @@ -23,6 +23,7 @@ func NewQueryCmd() *cobra.Command { CmdNextFeeDistribution(), CmdProviderInfo(), CmdThrottleState(), + CmdParams(), ) return cmd @@ -108,3 +109,30 @@ func CmdThrottleState() *cobra.Command { return cmd } + +func CmdParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Short: "Query consumer module parameters", + 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.QueryParamsRequest{} + res, err := queryClient.QueryParams(cmd.Context(), req) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/ccv/consumer/keeper/keeper.go b/x/ccv/consumer/keeper/keeper.go index aa93398761..242babda4d 100644 --- a/x/ccv/consumer/keeper/keeper.go +++ b/x/ccv/consumer/keeper/keeper.go @@ -101,6 +101,11 @@ func NewKeeper( return k } +// GetAuthority returns the x/ccv/provider module's authority. +func (k Keeper) GetAuthority() string { + return k.authority +} + // Returns a keeper with cdc, key and paramSpace set it does not raise any panics during registration (eg with IBCKeeper). // Used only in testing. func NewNonZeroKeeper(cdc codec.BinaryCodec, key storetypes.StoreKey, paramSpace paramtypes.Subspace) Keeper { diff --git a/x/ccv/consumer/keeper/msg_server.go b/x/ccv/consumer/keeper/msg_server.go new file mode 100644 index 0000000000..6031101b17 --- /dev/null +++ b/x/ccv/consumer/keeper/msg_server.go @@ -0,0 +1,36 @@ +package keeper + +import ( + "context" + + errorsmod "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" +) + +type msgServer struct { + *Keeper +} + +// NewMsgServerImpl returns an implementation of the bank MsgServer interface +// for the provided Keeper. +func NewMsgServerImpl(keeper *Keeper) types.MsgServer { + return &msgServer{Keeper: keeper} +} + +var _ types.MsgServer = msgServer{} + +// UpdateParams updates the params. +func (k msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + if k.GetAuthority() != msg.Authority { + return nil, errorsmod.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", k.authority, msg.Authority) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + k.Keeper.SetParams(ctx, msg.Params) + + return &types.MsgUpdateParamsResponse{}, nil +} diff --git a/x/ccv/consumer/module.go b/x/ccv/consumer/module.go index 1f384d39a3..fba9d19093 100644 --- a/x/ccv/consumer/module.go +++ b/x/ccv/consumer/module.go @@ -54,7 +54,7 @@ func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { // RegisterInterfaces registers module concrete types into protobuf Any. func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { - // ccv.RegisterInterfaces(registry) + consumertypes.RegisterInterfaces(registry) } // IsAppModule implements the appmodule.AppModule interface. @@ -120,6 +120,7 @@ func (AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { // RegisterServices registers module services. func (am AppModule) RegisterServices(cfg module.Configurator) { + consumertypes.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(&am.keeper)) consumertypes.RegisterQueryServer(cfg.QueryServer(), am.keeper) m := keeper.NewMigrator(am.keeper, am.paramSpace) diff --git a/x/ccv/consumer/types/codec.go b/x/ccv/consumer/types/codec.go new file mode 100644 index 0000000000..243fc63f46 --- /dev/null +++ b/x/ccv/consumer/types/codec.go @@ -0,0 +1,18 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +// RegisterInterfaces registers the consumer Tx message types to the interface registry +func RegisterInterfaces(registry codectypes.InterfaceRegistry) { + + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgUpdateParams{}, + ) + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} diff --git a/x/ccv/consumer/types/tx.pb.go b/x/ccv/consumer/types/tx.pb.go new file mode 100644 index 0000000000..4fde6e583d --- /dev/null +++ b/x/ccv/consumer/types/tx.pb.go @@ -0,0 +1,598 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: interchain_security/ccv/consumer/v1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + _ "github.com/cosmos/cosmos-sdk/types/msgservice" + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + types "github.com/cosmos/interchain-security/v5/x/ccv/types" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// MsgUpdateParams is the Msg/UpdateParams request type +type MsgUpdateParams struct { + // signer is the address of the governance account. + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the x/provider parameters to update. + Params types.ConsumerParams `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` +} + +func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } +func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParams) ProtoMessage() {} +func (*MsgUpdateParams) Descriptor() ([]byte, []int) { + return fileDescriptor_9d7049279494b73f, []int{0} +} +func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParams.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParams.Merge(m, src) +} +func (m *MsgUpdateParams) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParams) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParams.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParams proto.InternalMessageInfo + +func (m *MsgUpdateParams) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +func (m *MsgUpdateParams) GetParams() types.ConsumerParams { + if m != nil { + return m.Params + } + return types.ConsumerParams{} +} + +type MsgUpdateParamsResponse struct { +} + +func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse{} } +func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParamsResponse) ProtoMessage() {} +func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_9d7049279494b73f, []int{1} +} +func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParamsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParamsResponse.Merge(m, src) +} +func (m *MsgUpdateParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgUpdateParams)(nil), "interchain_security.ccv.consumer.v1.MsgUpdateParams") + proto.RegisterType((*MsgUpdateParamsResponse)(nil), "interchain_security.ccv.consumer.v1.MsgUpdateParamsResponse") +} + +func init() { + proto.RegisterFile("interchain_security/ccv/consumer/v1/tx.proto", fileDescriptor_9d7049279494b73f) +} + +var fileDescriptor_9d7049279494b73f = []byte{ + // 402 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0xc9, 0xcc, 0x2b, 0x49, + 0x2d, 0x4a, 0xce, 0x48, 0xcc, 0xcc, 0x8b, 0x2f, 0x4e, 0x4d, 0x2e, 0x2d, 0xca, 0x2c, 0xa9, 0xd4, + 0x4f, 0x4e, 0x2e, 0xd3, 0x4f, 0xce, 0xcf, 0x2b, 0x2e, 0xcd, 0x4d, 0x2d, 0xd2, 0x2f, 0x33, 0xd4, + 0x2f, 0xa9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x52, 0xc6, 0xa2, 0x5a, 0x2f, 0x39, 0xb9, + 0x4c, 0x0f, 0xa6, 0x5a, 0xaf, 0xcc, 0x50, 0x4a, 0x30, 0x31, 0x37, 0x33, 0x2f, 0x5f, 0x1f, 0x4c, + 0x42, 0xf4, 0x49, 0xc9, 0xa4, 0xe7, 0xe7, 0xa7, 0xe7, 0xa4, 0xea, 0x27, 0x16, 0x64, 0xea, 0x27, + 0xe6, 0xe5, 0xe5, 0x97, 0x24, 0x96, 0x64, 0xe6, 0xe7, 0x15, 0x43, 0x65, 0x45, 0xd2, 0xf3, 0xd3, + 0xf3, 0xc1, 0x4c, 0x7d, 0x10, 0x0b, 0x2a, 0x2a, 0x99, 0x9c, 0x5f, 0x9c, 0x9b, 0x5f, 0x1c, 0x0f, + 0x91, 0x80, 0x70, 0xa0, 0x52, 0xe2, 0x10, 0x9e, 0x7e, 0x6e, 0x71, 0x3a, 0xc8, 0x79, 0xb9, 0xc5, + 0xe9, 0x50, 0x09, 0x03, 0x5c, 0xbe, 0x29, 0x33, 0xd4, 0x2f, 0xce, 0x48, 0x2c, 0x4a, 0x4d, 0x89, + 0x87, 0xbb, 0x14, 0xac, 0x43, 0x69, 0x31, 0x23, 0x17, 0xbf, 0x6f, 0x71, 0x7a, 0x68, 0x41, 0x4a, + 0x62, 0x49, 0x6a, 0x40, 0x62, 0x51, 0x62, 0x6e, 0xb1, 0x90, 0x19, 0x17, 0x67, 0x62, 0x69, 0x49, + 0x46, 0x3e, 0x48, 0xb7, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xa7, 0x93, 0xc4, 0xa5, 0x2d, 0xba, 0x22, + 0x50, 0x37, 0x38, 0xa6, 0xa4, 0x14, 0xa5, 0x16, 0x17, 0x07, 0x97, 0x14, 0x65, 0xe6, 0xa5, 0x07, + 0x21, 0x94, 0x0a, 0x79, 0x70, 0xb1, 0x15, 0x80, 0x4d, 0x90, 0x60, 0x52, 0x60, 0xd4, 0xe0, 0x36, + 0xd2, 0xd2, 0xc3, 0x15, 0x5c, 0x65, 0x86, 0x7a, 0xce, 0x50, 0x77, 0x40, 0xec, 0x74, 0x62, 0x39, + 0x71, 0x4f, 0x9e, 0x21, 0x08, 0xaa, 0xdf, 0x8a, 0xaf, 0xe9, 0xf9, 0x06, 0x2d, 0x84, 0xc9, 0x4a, + 0x92, 0x5c, 0xe2, 0x68, 0x8e, 0x0c, 0x4a, 0x2d, 0x2e, 0xc8, 0xcf, 0x2b, 0x4e, 0x35, 0x9a, 0xc8, + 0xc8, 0xc5, 0xec, 0x5b, 0x9c, 0x2e, 0xd4, 0xc4, 0xc8, 0xc5, 0x83, 0xe2, 0x0b, 0x13, 0x3d, 0x22, + 0x22, 0x4b, 0x0f, 0xcd, 0x58, 0x29, 0x1b, 0x72, 0x74, 0xc1, 0x1c, 0x23, 0xc5, 0xda, 0xf0, 0x7c, + 0x83, 0x16, 0xa3, 0x53, 0xf8, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, + 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0xd9, + 0xa6, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0x42, 0xa3, 0x54, 0x1f, 0x61, 0x9f, + 0x2e, 0x3c, 0xca, 0xca, 0x4c, 0xf5, 0x2b, 0x50, 0x53, 0x61, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, + 0x1b, 0x38, 0xd2, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc4, 0xb3, 0xd4, 0x91, 0xb6, 0x02, + 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { + out := new(MsgUpdateParamsResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.consumer.v1.Msg/UpdateParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) UpdateParams(ctx context.Context, req *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.consumer.v1.Msg/UpdateParams", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "interchain_security.ccv.consumer.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "UpdateParams", + Handler: _Msg_UpdateParams_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "interchain_security/ccv/consumer/v1/tx.proto", +} + +func (m *MsgUpdateParams) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateParamsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgUpdateParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Params.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgUpdateParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgUpdateParams) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) From 7cd900ad2a74aae8e98106d7e7ab6c15c9daa97a Mon Sep 17 00:00:00 2001 From: MSalopek Date: Wed, 24 Apr 2024 21:34:12 +0200 Subject: [PATCH 12/35] test: move provider hooks tests to integration tests (#1816) tests: add provider gov hooks integration tests --- app/provider/app.go | 5 + tests/integration/provider_gov_hooks.go | 149 ++++++++++++++++++++++++ testutil/integration/debug_test.go | 13 +++ testutil/integration/interfaces.go | 2 +- x/ccv/provider/keeper/hooks_test.go | 138 ---------------------- 5 files changed, 168 insertions(+), 139 deletions(-) create mode 100644 tests/integration/provider_gov_hooks.go diff --git a/app/provider/app.go b/app/provider/app.go index b2042258d2..32bb17050a 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -923,6 +923,11 @@ func (app *App) GetTestAccountKeeper() testutil.TestAccountKeeper { return app.AccountKeeper } +// GetTestGovKeeper implements the ProviderApp interface. +func (app *App) GetTestGovKeeper() *govkeeper.Keeper { + return app.GovKeeper +} + // TestingApp functions // GetBaseApp implements the TestingApp interface. diff --git a/tests/integration/provider_gov_hooks.go b/tests/integration/provider_gov_hooks.go new file mode 100644 index 0000000000..d1970c1b72 --- /dev/null +++ b/tests/integration/provider_gov_hooks.go @@ -0,0 +1,149 @@ +package integration + +import ( + "time" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" +) + +// tests AfterProposalSubmission and AfterProposalVotingPeriodEnded hooks +// hooks require adding a proposal in the gov module and regitering a consumer chain with the provider module +func (s *CCVTestSuite) TestAfterPropSubmissionAndVotingPeriodEnded() { + ctx := s.providerChain.GetContext() + providerKeeper := s.providerApp.GetProviderKeeper() + govKeeper := s.providerApp.GetTestGovKeeper() + proposer := s.providerChain.SenderAccount + + content := testkeeper.GetTestConsumerAdditionProp() + content.ChainId = "newchain-0" + legacyPropContent, err := v1.NewLegacyContent( + content, + authtypes.NewModuleAddress("gov").String(), + ) + s.Require().NoError(err) + + proposal, err := v1.NewProposal([]sdk.Msg{legacyPropContent}, 1, time.Now(), time.Now().Add(1*time.Hour), "metadata", "title", "summary", proposer.GetAddress(), false) + s.Require().NoError(err) + + err = govKeeper.SetProposal(ctx, proposal) + s.Require().NoError(err) + + providerKeeper.Hooks().AfterProposalSubmission(ctx, proposal.Id) + + // verify that the proposal ID is created + proposalIdOnProvider := providerKeeper.GetProposedConsumerChain(ctx, proposal.Id) + s.Require().NotEmpty(proposalIdOnProvider) + s.Require().Equal(content.ChainId, proposalIdOnProvider) + + providerKeeper.Hooks().AfterProposalVotingPeriodEnded(ctx, proposal.Id) + // verify that the proposal ID is deleted + s.Require().Empty(providerKeeper.GetProposedConsumerChain(ctx, proposal.Id)) +} + +func (s *CCVTestSuite) TestGetConsumerAdditionLegacyPropFromProp() { + ctx := s.providerChain.GetContext() + proposer := s.providerChain.SenderAccount + + // create a dummy bank send message + dummyMsg := &banktypes.MsgSend{ + FromAddress: sdk.AccAddress(proposer.GetAddress()).String(), + ToAddress: sdk.AccAddress(proposer.GetAddress()).String(), + Amount: sdk.NewCoins(sdk.NewCoin("stake", math.OneInt())), + } + + textProp, err := v1.NewLegacyContent( + v1beta1.NewTextProposal("a title", "a legacy text prop"), + authtypes.NewModuleAddress("gov").String(), + ) + s.Require().NoError(err) + + addConsumerProp, err := v1.NewLegacyContent( + testkeeper.GetTestConsumerAdditionProp(), + authtypes.NewModuleAddress("gov").String(), + ) + s.Require().NoError(err) + + testCases := []struct { + name string + propMsg sdk.Msg + expectConsumerPropFound bool + expPanic bool + }{ + { + name: "prop not found", + propMsg: nil, + expectConsumerPropFound: false, + expPanic: false, + }, + { + name: "msgs in prop contain no legacy props", + propMsg: dummyMsg, + expectConsumerPropFound: false, + expPanic: false, + }, + { + name: "msgs contain a legacy prop but not of ConsumerAdditionProposal type", + propMsg: textProp, + expectConsumerPropFound: false, + }, + { + name: "msgs contain an invalid legacy prop", + propMsg: &v1.MsgExecLegacyContent{}, + expectConsumerPropFound: false, + expPanic: true, + }, + { + name: "msg contains a prop of ConsumerAdditionProposal type - hook should create a new proposed chain", + propMsg: addConsumerProp, + expectConsumerPropFound: true, + expPanic: false, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + providerKeeper := s.providerApp.GetProviderKeeper() + govKeeper := s.providerApp.GetTestGovKeeper() + + var proposal v1.Proposal + var err error + + if tc.propMsg == nil { + // cover edgecase where proposal has no messages + proposal, err = v1.NewProposal([]sdk.Msg{}, 1, time.Now(), time.Now().Add(1*time.Hour), "metadata", "title", "summary", proposer.GetAddress(), false) + s.Require().NoError(err) + } else { + // cover variolus cases where proposal has messages but only some are consumer addition proposals + proposal, err = v1.NewProposal([]sdk.Msg{tc.propMsg}, 1, time.Now(), time.Now().Add(1*time.Hour), "metadata", "title", "summary", proposer.GetAddress(), false) + s.Require().NoError(err) + } + + err = govKeeper.SetProposal(ctx, proposal) + s.Require().NoError(err) + + if tc.expPanic { + s.Require().Panics(func() { + // this panics with a nil pointer dereference because the proposal is invalid and cannot be unmarshalled + providerKeeper.Hooks().GetConsumerAdditionLegacyPropFromProp(ctx, proposal.Id) + }) + return + } + + savedProp, found := providerKeeper.Hooks().GetConsumerAdditionLegacyPropFromProp(ctx, proposal.Id) + if tc.expectConsumerPropFound { + s.Require().True(found) + s.Require().NotEmpty(savedProp, savedProp) + } else { + s.Require().False(found) + s.Require().Empty(savedProp) + } + }) + } +} diff --git a/testutil/integration/debug_test.go b/testutil/integration/debug_test.go index 1708cbf6c2..af37fbb5a1 100644 --- a/testutil/integration/debug_test.go +++ b/testutil/integration/debug_test.go @@ -281,6 +281,7 @@ func TestHandleConsumerDoubleVotingSlashesUndelegationsAndRelegations(t *testing runCCVTestByName(t, "TestHandleConsumerDoubleVotingSlashesUndelegationsAndRelegations") } +// // Throttle retry tests // @@ -291,3 +292,15 @@ func TestSlashRetries(t *testing.T) { func TestKeyAssignment(t *testing.T) { runCCVTestByName(t, "TestKeyAssignment") } + +// +// Provider gov hooks test +// + +func TestAfterPropSubmissionAndVotingPeriodEnded(t *testing.T) { + runCCVTestByName(t, "TestAfterPropSubmissionAndVotingPeriodEnded") +} + +func TestGetConsumerAdditionLegacyPropFromProp(t *testing.T) { + runCCVTestByName(t, "TestGetConsumerAdditionLegacyPropFromProp") +} diff --git a/testutil/integration/interfaces.go b/testutil/integration/interfaces.go index 3f8428f9d0..b36befe20f 100644 --- a/testutil/integration/interfaces.go +++ b/testutil/integration/interfaces.go @@ -47,7 +47,7 @@ type ProviderApp interface { // Returns an account keeper interface with more capabilities than the expected_keepers interface GetTestAccountKeeper() TestAccountKeeper - // GetTestGovKeeper() govkeeper.Keeper + GetTestGovKeeper() *govkeeper.Keeper } // The interface that any consumer app must implement to be compatible with integration tests diff --git a/x/ccv/provider/keeper/hooks_test.go b/x/ccv/provider/keeper/hooks_test.go index d7ea94c0dc..2a6d60db85 100644 --- a/x/ccv/provider/keeper/hooks_test.go +++ b/x/ccv/provider/keeper/hooks_test.go @@ -81,141 +81,3 @@ func TestValidatorConsensusKeyInUse(t *testing.T) { }) } } - -// TODO: move to integration tests -// func TestAfterPropSubmissionAndVotingPeriodEnded(t *testing.T) { -// acct := cryptotestutil.NewCryptoIdentityFromIntSeed(0) - -// propMsg, err := v1.NewLegacyContent( -// testkeeper.GetTestConsumerAdditionProp(), -// authtypes.NewModuleAddress("gov").String(), -// ) -// require.NoError(t, err) - -// prop, err := v1.NewProposal( -// []sdk.Msg{propMsg}, -// 0, -// time.Now(), -// time.Now(), -// "", -// "", -// "", -// sdk.AccAddress(acct.SDKValOpAddress()), -// false, // proposal not expedited -// ) -// require.NoError(t, err) - -// k, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) -// defer ctrl.Finish() - -// // TODO: not sure how to ho about fetching props on the mock -// // pass the prop to the mocked gov keeper, -// // which is called by both the AfterProposalVotingPeriodEnded and -// // AfterProposalSubmission gov hooks -// // gomock.InOrder( -// // mocks.MockGovKeeper.EXPECT().GetProposal(ctx, prop.Id).Return(prop, true).Times(2), -// // ) - -// k.Hooks().AfterProposalSubmission(ctx, prop.Id) -// // verify that the proposal ID is created -// require.NotEmpty(t, k.GetProposedConsumerChain(ctx, prop.Id)) - -// k.Hooks().AfterProposalVotingPeriodEnded(ctx, prop.Id) -// // verify that the proposal ID is deleted -// require.Empty(t, k.GetProposedConsumerChain(ctx, prop.Id)) -// } - -// func TestGetConsumerAdditionLegacyPropFromProp(t *testing.T) { -// acct := cryptotestutil.NewCryptoIdentityFromIntSeed(0) -// anotherAcct := cryptotestutil.NewCryptoIdentityFromIntSeed(1) - -// // create a dummy bank send message -// dummyMsg := &banktypes.MsgSend{ -// FromAddress: sdk.AccAddress(acct.SDKValOpAddress()).String(), -// ToAddress: sdk.AccAddress(anotherAcct.SDKValOpAddress()).String(), -// Amount: sdk.NewCoins(sdk.NewCoin("stake", math.OneInt())), -// } - -// textProp, err := v1.NewLegacyContent( -// v1beta1.NewTextProposal("a title", "a legacy text prop"), -// authtypes.NewModuleAddress("gov").String(), -// ) -// require.NoError(t, err) - -// consuProp, err := v1.NewLegacyContent( -// testkeeper.GetTestConsumerAdditionProp(), -// authtypes.NewModuleAddress("gov").String(), -// ) -// require.NoError(t, err) - -// testCases := map[string]struct { -// propMsg sdk.Msg -// // setup func(sdk.Context, k providerkeeper, proposalID uint64) -// expPanic bool -// expConsuAddProp bool -// }{ -// "prop not found": { -// propMsg: nil, -// expPanic: true, -// }, -// "msgs in prop contain no legacy props": { -// propMsg: dummyMsg, -// }, -// "msgs contain a legacy prop but not of ConsumerAdditionProposal type": { -// propMsg: textProp, -// }, -// "msgs contain an invalid legacy prop": { -// propMsg: &v1.MsgExecLegacyContent{}, -// expPanic: true, -// }, -// "msg contains a prop of ConsumerAdditionProposal type - hook should create a new proposed chain": { -// propMsg: consuProp, -// expConsuAddProp: true, -// }, -// } - -// for name, tc := range testCases { -// t.Run(name, func(t *testing.T) { -// k, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) -// defer ctrl.Finish() - -// var ( -// prop v1.Proposal -// // propFound bool -// ) - -// if tc.propMsg != nil { -// // propFound = true -// prop, err = v1.NewProposal( -// []sdk.Msg{tc.propMsg}, -// 0, -// time.Now(), -// time.Now(), -// "", -// "", -// "", -// sdk.AccAddress(acct.SDKValOpAddress()), -// false, // proposal not expedited -// ) -// require.NoError(t, err) -// } - -// // gomock.InOrder( -// // mocks.MockGovKeeper.EXPECT().GetProposal(ctx, prop.Id).Return(prop, propFound), -// // ) - -// if tc.expPanic { -// defer func() { -// // fail test if not panic was recovered -// if r := recover(); r == nil { -// require.Fail(t, r.(string)) -// } -// }() -// } - -// // retrieve consumer addition proposal -// _, ok := k.Hooks().GetConsumerAdditionLegacyPropFromProp(ctx, prop.Id) -// require.Equal(t, tc.expConsuAddProp, ok) -// }) -// } -// } From 728a1e53b17f833504e778547bdadb09911ab258 Mon Sep 17 00:00:00 2001 From: MSalopek Date: Thu, 25 Apr 2024 15:28:28 +0200 Subject: [PATCH 13/35] chore: add consumer and provider migrations for ICS v5 (#1817) * chore: add consumer migration 2 -> 3 * chore: add provider migration; update params * fix: resolve review nits --- x/ccv/consumer/keeper/migrations.go | 7 +- .../v3}/legacy_params.go | 34 ++++--- x/ccv/consumer/migrations/v3/migration.go | 19 ++-- .../consumer/migrations/v3/migration_test.go | 95 +++++++++++++++++++ x/ccv/consumer/module.go | 5 +- x/ccv/provider/migrations/migrator.go | 4 + .../v5}/legacy_params.go | 23 +++-- x/ccv/provider/migrations/v5/migrations.go | 10 +- .../provider/migrations/v5/migrations_test.go | 57 +++++++++++ x/ccv/provider/module.go | 7 +- x/ccv/types/params.go | 8 ++ 11 files changed, 220 insertions(+), 49 deletions(-) rename x/ccv/consumer/{keeper => migrations/v3}/legacy_params.go (69%) create mode 100644 x/ccv/consumer/migrations/v3/migration_test.go rename x/ccv/provider/{keeper => migrations/v5}/legacy_params.go (74%) create mode 100644 x/ccv/provider/migrations/v5/migrations_test.go diff --git a/x/ccv/consumer/keeper/migrations.go b/x/ccv/consumer/keeper/migrations.go index ba4746b3d4..145d595087 100644 --- a/x/ccv/consumer/keeper/migrations.go +++ b/x/ccv/consumer/keeper/migrations.go @@ -5,6 +5,7 @@ import ( paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" v2 "github.com/cosmos/interchain-security/v5/x/ccv/consumer/migrations/v2" + v3 "github.com/cosmos/interchain-security/v5/x/ccv/consumer/migrations/v3" ) // Migrator is a struct for handling in-place store migrations. @@ -24,8 +25,10 @@ func (m Migrator) Migrate1to2(ctx sdk.Context) error { return v2.MigrateConsumerPacketData(ctx, store) } -// Migrate2to3 migrates x/ccvconsumer state from consensus version 2 to 3. +// Migrate2to3 migrates x/ccvconsumer from consensus version 2 to 3. +// This migration is necessary to move the consumer module legacy params. func (m Migrator) Migrate2to3(ctx sdk.Context) error { store := ctx.KVStore(m.keeper.storeKey) - return v2.MigrateConsumerPacketData(ctx, store) + cdc := m.keeper.cdc + return v3.MigrateLegacyParams(ctx, cdc, store, m.paramSpace) } diff --git a/x/ccv/consumer/keeper/legacy_params.go b/x/ccv/consumer/migrations/v3/legacy_params.go similarity index 69% rename from x/ccv/consumer/keeper/legacy_params.go rename to x/ccv/consumer/migrations/v3/legacy_params.go index 9bf1618dcc..0906455e21 100644 --- a/x/ccv/consumer/keeper/legacy_params.go +++ b/x/ccv/consumer/migrations/v3/legacy_params.go @@ -1,18 +1,16 @@ -package keeper +package v3 import ( "time" sdk "github.com/cosmos/cosmos-sdk/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // Legacy: used for migration only! -// GetConsumerParamsLegacy returns the params for the consumer ccv module from x/param subspace -// which will be deprecated soon -func GetConsumerParamsLegacy(ctx sdk.Context, keeper Keeper, paramSpace paramtypes.Subspace) ccvtypes.ConsumerParams { +// GetConsumerParamsLegacy returns the params for the consumer ccv module from legacy subspace +func GetConsumerParamsLegacy(ctx sdk.Context, paramSpace ccvtypes.LegacyParamSubspace) ccvtypes.ConsumerParams { return ccvtypes.NewParams( getEnabled(ctx, paramSpace), getBlocksPerDistributionTransmission(ctx, paramSpace), @@ -31,39 +29,39 @@ func GetConsumerParamsLegacy(ctx sdk.Context, keeper Keeper, paramSpace paramtyp } // getEnabled returns the enabled flag for the consumer module -func getEnabled(ctx sdk.Context, paramStore paramtypes.Subspace) bool { +func getEnabled(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) bool { var enabled bool paramStore.Get(ctx, ccvtypes.KeyEnabled, &enabled) return enabled } -func getBlocksPerDistributionTransmission(ctx sdk.Context, paramStore paramtypes.Subspace) int64 { +func getBlocksPerDistributionTransmission(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) int64 { var bpdt int64 paramStore.Get(ctx, ccvtypes.KeyBlocksPerDistributionTransmission, &bpdt) return bpdt } -func getDistributionTransmissionChannel(ctx sdk.Context, paramStore paramtypes.Subspace) string { +func getDistributionTransmissionChannel(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) string { var s string paramStore.Get(ctx, ccvtypes.KeyDistributionTransmissionChannel, &s) return s } -func getProviderFeePoolAddrStr(ctx sdk.Context, paramStore paramtypes.Subspace) string { +func getProviderFeePoolAddrStr(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) string { var s string paramStore.Get(ctx, ccvtypes.KeyProviderFeePoolAddrStr, &s) return s } // getCCVTimeoutPeriod returns the timeout period for sent ccv related ibc packets -func getCCVTimeoutPeriod(ctx sdk.Context, paramStore paramtypes.Subspace) time.Duration { +func getCCVTimeoutPeriod(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) time.Duration { var p time.Duration paramStore.Get(ctx, ccvtypes.KeyCCVTimeoutPeriod, &p) return p } // getTransferTimeoutPeriod returns the timeout period for sent transfer related ibc packets -func getTransferTimeoutPeriod(ctx sdk.Context, paramStore paramtypes.Subspace) time.Duration { +func getTransferTimeoutPeriod(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) time.Duration { var p time.Duration paramStore.Get(ctx, ccvtypes.KeyTransferTimeoutPeriod, &p) return p @@ -72,20 +70,20 @@ func getTransferTimeoutPeriod(ctx sdk.Context, paramStore paramtypes.Subspace) t // getConsumerRedistributionFrac returns the fraction of tokens allocated to the consumer redistribution // address during distribution events. The fraction is a string representing a // decimal number. For example "0.75" would represent 75%. -func getConsumerRedistributionFrac(ctx sdk.Context, paramStore paramtypes.Subspace) string { +func getConsumerRedistributionFrac(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) string { var str string paramStore.Get(ctx, ccvtypes.KeyConsumerRedistributionFrac, &str) return str } // getHistoricalEntries returns the number of historical info entries to persist in store -func getHistoricalEntries(ctx sdk.Context, paramStore paramtypes.Subspace) int64 { +func getHistoricalEntries(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) int64 { var n int64 paramStore.Get(ctx, ccvtypes.KeyHistoricalEntries, &n) return n } -func getUnbondingPeriod(ctx sdk.Context, paramStore paramtypes.Subspace) time.Duration { +func getUnbondingPeriod(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) time.Duration { var period time.Duration paramStore.Get(ctx, ccvtypes.KeyConsumerUnbondingPeriod, &period) return period @@ -93,25 +91,25 @@ func getUnbondingPeriod(ctx sdk.Context, paramStore paramtypes.Subspace) time.Du // getSoftOptOutThreshold returns the percentage of validators at the bottom of the set // that can opt out of running the consumer chain -func getSoftOptOutThreshold(ctx sdk.Context, paramStore paramtypes.Subspace) string { +func getSoftOptOutThreshold(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) string { var str string paramStore.Get(ctx, ccvtypes.KeySoftOptOutThreshold, &str) return str } -func getRewardDenoms(ctx sdk.Context, paramStore paramtypes.Subspace) []string { +func getRewardDenoms(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) []string { var denoms []string paramStore.Get(ctx, ccvtypes.KeyRewardDenoms, &denoms) return denoms } -func getProviderRewardDenoms(ctx sdk.Context, paramStore paramtypes.Subspace) []string { +func getProviderRewardDenoms(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) []string { var denoms []string paramStore.Get(ctx, ccvtypes.KeyProviderRewardDenoms, &denoms) return denoms } -func getRetryDelayPeriod(ctx sdk.Context, paramStore paramtypes.Subspace) time.Duration { +func getRetryDelayPeriod(ctx sdk.Context, paramStore ccvtypes.LegacyParamSubspace) time.Duration { var period time.Duration paramStore.Get(ctx, ccvtypes.KeyRetryDelayPeriod, &period) return period diff --git a/x/ccv/consumer/migrations/v3/migration.go b/x/ccv/consumer/migrations/v3/migration.go index aa2bd21b3a..aadc94bc43 100644 --- a/x/ccv/consumer/migrations/v3/migration.go +++ b/x/ccv/consumer/migrations/v3/migration.go @@ -1,22 +1,27 @@ package v3 import ( + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + storetypes "cosmossdk.io/store/types" - consumerKeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) -// MigrateParams migrates the consumers module's parameters from the x/params subspace to the +// MigrateLegacyParams migrates the consumers module's parameters from the x/params subspace to the // consumer modules store. -func MigrateParams(ctx sdk.Context, keeper consumerKeeper.Keeper, legacyParamspace paramtypes.Subspace) error { - params := consumerKeeper.GetConsumerParamsLegacy(ctx, keeper, legacyParamspace) +func MigrateLegacyParams(ctx sdk.Context, cdc codec.BinaryCodec, store storetypes.KVStore, legacyParamspace ccvtypes.LegacyParamSubspace) error { + ctx.Logger().Info("starting consumer legacy params migration") + params := GetConsumerParamsLegacy(ctx, legacyParamspace) err := params.Validate() if err != nil { return err } - keeper.SetParams(ctx, params) - keeper.Logger(ctx).Info("successfully migrated provider parameters") + + bz := cdc.MustMarshal(¶ms) + store.Set(consumertypes.ParametersKey(), bz) + ctx.Logger().Info("successfully migrated consumer parameters") return nil } diff --git a/x/ccv/consumer/migrations/v3/migration_test.go b/x/ccv/consumer/migrations/v3/migration_test.go new file mode 100644 index 0000000000..bdc3f59f70 --- /dev/null +++ b/x/ccv/consumer/migrations/v3/migration_test.go @@ -0,0 +1,95 @@ +package v3 + +import ( + "fmt" + "testing" + "time" + + storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/interchain-security/v5/app/encoding" + consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" + + "github.com/stretchr/testify/require" +) + +type testLegacyParamSubspace struct { + *ccvtypes.ConsumerParams +} + +func newTestLegacyParamsSubspace(p ccvtypes.ConsumerParams) testLegacyParamSubspace { + return testLegacyParamSubspace{ + &p, + } +} + +func (ps testLegacyParamSubspace) Get(ctx sdk.Context, key []byte, ptr interface{}) { + switch string(key) { + case string(ccvtypes.KeyEnabled): + *ptr.(*bool) = ps.Enabled + case string(ccvtypes.KeyBlocksPerDistributionTransmission): + *ptr.(*int64) = ps.BlocksPerDistributionTransmission + case string(ccvtypes.KeyDistributionTransmissionChannel): + *ptr.(*string) = ps.DistributionTransmissionChannel + case string(ccvtypes.KeyProviderFeePoolAddrStr): + *ptr.(*string) = ps.ProviderFeePoolAddrStr + case string(ccvtypes.KeyCCVTimeoutPeriod): + *ptr.(*time.Duration) = ps.CcvTimeoutPeriod + case string(ccvtypes.KeyTransferTimeoutPeriod): + *ptr.(*time.Duration) = ps.TransferTimeoutPeriod + case string(ccvtypes.KeyConsumerRedistributionFrac): + *ptr.(*string) = ps.ConsumerRedistributionFraction + case string(ccvtypes.KeyHistoricalEntries): + *ptr.(*int64) = ps.HistoricalEntries + case string(ccvtypes.KeyConsumerUnbondingPeriod): + *ptr.(*time.Duration) = ps.UnbondingPeriod + case string(ccvtypes.KeySoftOptOutThreshold): + *ptr.(*string) = ps.SoftOptOutThreshold + case string(ccvtypes.KeyRewardDenoms): + *ptr.(*[]string) = ps.RewardDenoms + case string(ccvtypes.KeyProviderRewardDenoms): + *ptr.(*[]string) = ps.ProviderRewardDenoms + case string(ccvtypes.KeyRetryDelayPeriod): + *ptr.(*time.Duration) = ps.RetryDelayPeriod + default: + panic(fmt.Sprintf("invalid paramspace key: %s", string(key))) + + } +} + +func TestMigrateParams(t *testing.T) { + cdc := encoding.MakeTestEncodingConfig().Codec + storeKey := storetypes.NewKVStoreKey("ccvconsumer") + ctx := testutil.DefaultContext(storeKey, storetypes.NewTransientStoreKey("transient_test")) + store := ctx.KVStore(storeKey) + + defaultParams := ccvtypes.DefaultParams() + legacyParamSubspace := newTestLegacyParamsSubspace(defaultParams) + // confirms that testLegacyParamSubspace works as expected + require.NotPanics(t, func() { + GetConsumerParamsLegacy(ctx, legacyParamSubspace) + }) + + emptyParams := ccvtypes.ConsumerParams{} + bz := store.Get(consumertypes.ParametersKey()) + require.NoError(t, cdc.Unmarshal(bz, &emptyParams)) + require.NotNil(t, emptyParams) + require.Empty(t, emptyParams) + require.NotEqual(t, defaultParams, emptyParams) + + err := MigrateLegacyParams(ctx, cdc, store, legacyParamSubspace) + require.NoError(t, err) + + // check that new params are available after migration and equal to defaults + // legacyParamSubspace was set to match defaultParams + migratedParams := ccvtypes.ConsumerParams{} + paramsBz := store.Get(consumertypes.ParametersKey()) + require.NotEqual(t, bz, paramsBz) + require.NoError(t, cdc.Unmarshal(paramsBz, &migratedParams)) + + require.Equal(t, defaultParams, migratedParams) + require.NotEqual(t, emptyParams, migratedParams) +} diff --git a/x/ccv/consumer/module.go b/x/ccv/consumer/module.go index fba9d19093..49e19542be 100644 --- a/x/ccv/consumer/module.go +++ b/x/ccv/consumer/module.go @@ -127,6 +127,9 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { if err := cfg.RegisterMigration(consumertypes.ModuleName, 1, m.Migrate1to2); err != nil { panic(fmt.Sprintf("failed to register migrator for %s: %s", consumertypes.ModuleName, err)) } + if err := cfg.RegisterMigration(consumertypes.ModuleName, 2, m.Migrate2to3); err != nil { + panic(fmt.Sprintf("failed to register migrator for %s: %s -- from 2 -> 3", consumertypes.ModuleName, err)) + } } // InitGenesis performs genesis initialization for the consumer module. It returns @@ -146,7 +149,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw // ConsensusVersion implements AppModule/ConsensusVersion. func (AppModule) ConsensusVersion() uint64 { - return 2 + return 3 } // BeginBlock implements the AppModule interface diff --git a/x/ccv/provider/migrations/migrator.go b/x/ccv/provider/migrations/migrator.go index fc99bc45c7..83812b6eb5 100644 --- a/x/ccv/provider/migrations/migrator.go +++ b/x/ccv/provider/migrations/migrator.go @@ -1,6 +1,8 @@ package migrations import ( + storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/codec" sdktypes "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" @@ -14,6 +16,8 @@ import ( type Migrator struct { providerKeeper providerkeeper.Keeper paramSpace paramtypes.Subspace + cdc codec.BinaryCodec + storeKey storetypes.StoreKey } // NewMigrator returns a new Migrator. diff --git a/x/ccv/provider/keeper/legacy_params.go b/x/ccv/provider/migrations/v5/legacy_params.go similarity index 74% rename from x/ccv/provider/keeper/legacy_params.go rename to x/ccv/provider/migrations/v5/legacy_params.go index def88809ac..146339a131 100644 --- a/x/ccv/provider/keeper/legacy_params.go +++ b/x/ccv/provider/migrations/v5/legacy_params.go @@ -1,10 +1,9 @@ -package keeper +package v5 import ( "time" sdk "github.com/cosmos/cosmos-sdk/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" @@ -12,7 +11,7 @@ import ( ) // getTemplateClient returns the template client for provider proposals -func getTemplateClient(ctx sdk.Context, paramSpace paramtypes.Subspace) *ibctmtypes.ClientState { +func getTemplateClient(ctx sdk.Context, paramSpace ccvtypes.LegacyParamSubspace) *ibctmtypes.ClientState { var cs ibctmtypes.ClientState paramSpace.Get(ctx, types.KeyTemplateClient, &cs) return &cs @@ -20,28 +19,28 @@ func getTemplateClient(ctx sdk.Context, paramSpace paramtypes.Subspace) *ibctmty // getTrustingPeriodFraction returns a TrustingPeriodFraction // used to compute the provider IBC client's TrustingPeriod as UnbondingPeriod / TrustingPeriodFraction -func getTrustingPeriodFraction(ctx sdk.Context, paramSpace paramtypes.Subspace) string { +func getTrustingPeriodFraction(ctx sdk.Context, paramSpace ccvtypes.LegacyParamSubspace) string { var f string paramSpace.Get(ctx, types.KeyTrustingPeriodFraction, &f) return f } // getCCVTimeoutPeriod returns the timeout period for sent ibc packets -func getCCVTimeoutPeriod(ctx sdk.Context, paramSpace paramtypes.Subspace) time.Duration { +func getCCVTimeoutPeriod(ctx sdk.Context, paramSpace ccvtypes.LegacyParamSubspace) time.Duration { var p time.Duration paramSpace.Get(ctx, ccvtypes.KeyCCVTimeoutPeriod, &p) return p } // getInitTimeoutPeriod returns the init timeout period -func getInitTimeoutPeriod(ctx sdk.Context, paramSpace paramtypes.Subspace) time.Duration { +func getInitTimeoutPeriod(ctx sdk.Context, paramSpace ccvtypes.LegacyParamSubspace) time.Duration { var p time.Duration paramSpace.Get(ctx, types.KeyInitTimeoutPeriod, &p) return p } // getVscTimeoutPeriod returns the vsc timeout period -func getVscTimeoutPeriod(ctx sdk.Context, paramSpace paramtypes.Subspace) time.Duration { +func getVscTimeoutPeriod(ctx sdk.Context, paramSpace ccvtypes.LegacyParamSubspace) time.Duration { var p time.Duration paramSpace.Get(ctx, types.KeyVscTimeoutPeriod, &p) return p @@ -49,7 +48,7 @@ func getVscTimeoutPeriod(ctx sdk.Context, paramSpace paramtypes.Subspace) time.D // getSlashMeterReplenishPeriod returns the period in which: // Once the slash meter becomes not-full, the slash meter is replenished after this period. -func getSlashMeterReplenishPeriod(ctx sdk.Context, paramSpace paramtypes.Subspace) time.Duration { +func getSlashMeterReplenishPeriod(ctx sdk.Context, paramSpace ccvtypes.LegacyParamSubspace) time.Duration { var p time.Duration paramSpace.Get(ctx, types.KeySlashMeterReplenishPeriod, &p) return p @@ -58,19 +57,19 @@ func getSlashMeterReplenishPeriod(ctx sdk.Context, paramSpace paramtypes.Subspac // getSlashMeterReplenishFraction returns the string fraction of total voting power that is replenished // to the slash meter every replenish period. This param also serves as a maximum fraction of total // voting power that the slash meter can hold. -func getSlashMeterReplenishFraction(ctx sdk.Context, paramSpace paramtypes.Subspace) string { +func getSlashMeterReplenishFraction(ctx sdk.Context, paramSpace ccvtypes.LegacyParamSubspace) string { var f string paramSpace.Get(ctx, types.KeySlashMeterReplenishFraction, &f) return f } -func getConsumerRewardDenomRegistrationFee(ctx sdk.Context, paramSpace paramtypes.Subspace) sdk.Coin { +func getConsumerRewardDenomRegistrationFee(ctx sdk.Context, paramSpace ccvtypes.LegacyParamSubspace) sdk.Coin { var c sdk.Coin paramSpace.Get(ctx, types.KeyConsumerRewardDenomRegistrationFee, &c) return c } -func getBlocksPerEpoch(ctx sdk.Context, paramSpace paramtypes.Subspace) int64 { +func getBlocksPerEpoch(ctx sdk.Context, paramSpace ccvtypes.LegacyParamSubspace) int64 { var b int64 paramSpace.Get(ctx, types.KeyBlocksPerEpoch, &b) return b @@ -78,7 +77,7 @@ func getBlocksPerEpoch(ctx sdk.Context, paramSpace paramtypes.Subspace) int64 { // Legacy: Only for migration purposes. GetParamsLegacy returns the paramset for the provider // module from a given param subspace -func GetParamsLegacy(ctx sdk.Context, paramspace paramtypes.Subspace) types.Params { +func GetParamsLegacy(ctx sdk.Context, paramspace ccvtypes.LegacyParamSubspace) types.Params { return types.NewParams( getTemplateClient(ctx, paramspace), getTrustingPeriodFraction(ctx, paramspace), diff --git a/x/ccv/provider/migrations/v5/migrations.go b/x/ccv/provider/migrations/v5/migrations.go index face264ddc..f61428e48a 100644 --- a/x/ccv/provider/migrations/v5/migrations.go +++ b/x/ccv/provider/migrations/v5/migrations.go @@ -1,16 +1,16 @@ -package v4 +package v5 import ( sdk "github.com/cosmos/cosmos-sdk/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // MigrateParams migrates the provider module's parameters from the x/params to self store. -func MigrateLegacyParams(ctx sdk.Context, keeper providerkeeper.Keeper, legacySubspace paramtypes.Subspace) error { - keeper.Logger(ctx).Info("starting provider legacy params migration") - params := providerkeeper.GetParamsLegacy(ctx, legacySubspace) +func MigrateLegacyParams(ctx sdk.Context, keeper providerkeeper.Keeper, legacyParamspace ccvtypes.LegacyParamSubspace) error { + ctx.Logger().Info("starting provider legacy params migration") + params := GetParamsLegacy(ctx, legacyParamspace) err := params.Validate() if err != nil { return err diff --git a/x/ccv/provider/migrations/v5/migrations_test.go b/x/ccv/provider/migrations/v5/migrations_test.go new file mode 100644 index 0000000000..a7705da8b0 --- /dev/null +++ b/x/ccv/provider/migrations/v5/migrations_test.go @@ -0,0 +1,57 @@ +package v5 + +import ( + "testing" + + "github.com/stretchr/testify/require" + + testutil "github.com/cosmos/interchain-security/v5/testutil/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" +) + +func TestMigrateParams(t *testing.T) { + t.Helper() + inMemParams := testutil.NewInMemKeeperParams(t) + k, ctx, ctrl, _ := testutil.GetProviderKeeperAndCtx(t, inMemParams) + defer ctrl.Finish() + + if !inMemParams.ParamsSubspace.HasKeyTable() { + inMemParams.ParamsSubspace.WithKeyTable(providertypes.ParamKeyTable()) + } + + defaultParams := providertypes.DefaultParams() + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyTemplateClient, defaultParams.TemplateClient) + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyTrustingPeriodFraction, defaultParams.TrustingPeriodFraction) + inMemParams.ParamsSubspace.Set(ctx, ccvtypes.KeyCCVTimeoutPeriod, defaultParams.CcvTimeoutPeriod) + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyInitTimeoutPeriod, defaultParams.InitTimeoutPeriod) + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyVscTimeoutPeriod, defaultParams.VscTimeoutPeriod) + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeySlashMeterReplenishPeriod, defaultParams.SlashMeterReplenishPeriod) + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeySlashMeterReplenishFraction, defaultParams.SlashMeterReplenishFraction) + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyConsumerRewardDenomRegistrationFee, defaultParams.ConsumerRewardDenomRegistrationFee) + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyBlocksPerEpoch, defaultParams.BlocksPerEpoch) + + // confirms that inMemParams.ParamsSubspace works as expected + require.NotPanics(t, func() { + GetParamsLegacy(ctx, inMemParams.ParamsSubspace) + }) + + // no "new" params should be available before migration + // "new" params are stored under providertypes.ParametersKey() + emptyParams := k.GetParams(ctx) + require.Empty(t, emptyParams) + + // make sure that the legacy params are equal to the default params (they were set using inMemParams.ParamsSubspace.Set()) + legacyParams := GetParamsLegacy(ctx, inMemParams.ParamsSubspace) + require.NotNil(t, legacyParams) + require.Equal(t, defaultParams, legacyParams) + + err := MigrateLegacyParams(ctx, k, inMemParams.ParamsSubspace) + require.NoError(t, err) + + // check that "new" params are available after migration and equal to defaults + migratedParams := k.GetParams(ctx) + require.NotEmpty(t, migratedParams) + require.Equal(t, defaultParams, migratedParams) + require.NotEqual(t, emptyParams, migratedParams) +} diff --git a/x/ccv/provider/module.go b/x/ccv/provider/module.go index ef35716f8c..63e26431fc 100644 --- a/x/ccv/provider/module.go +++ b/x/ccv/provider/module.go @@ -122,15 +122,14 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { providertypes.RegisterQueryServer(cfg.QueryServer(), am.keeper) migrator := migrations.NewMigrator(*am.keeper, am.paramSpace) - err := cfg.RegisterMigration(am.Name(), 2, migrator.Migrate2to3) - if err != nil { - panic(err) + if err := cfg.RegisterMigration(providertypes.ModuleName, 2, migrator.Migrate2to3); err != nil { + panic(fmt.Sprintf("failed to register migrator for %s: %s -- from 2 -> 3", providertypes.ModuleName, err)) } if err := cfg.RegisterMigration(providertypes.ModuleName, 3, migrator.Migrate3to4); err != nil { panic(fmt.Sprintf("failed to register migrator for %s: %s -- from 3 -> 4", providertypes.ModuleName, err)) } if err := cfg.RegisterMigration(providertypes.ModuleName, 4, migrator.Migrate4to5); err != nil { - panic(fmt.Sprintf("failed to register migrator for %s: %s -- from 4 -> 4", providertypes.ModuleName, err)) + panic(fmt.Sprintf("failed to register migrator for %s: %s -- from 4 -> 5", providertypes.ModuleName, err)) } } diff --git a/x/ccv/types/params.go b/x/ccv/types/params.go index 2bcbc41717..72a95ae7dd 100644 --- a/x/ccv/types/params.go +++ b/x/ccv/types/params.go @@ -61,6 +61,14 @@ var ( KeyRetryDelayPeriod = []byte("RetryDelayPeriod") ) +// helper interface +// sdk::paramtypes.ParamSpace implicitly implements this interface because it +// implements the Get(ctx sdk.Context, key []byte, ptr interface{}) +// since only Get(...) is needed to migrate params we can ignore the other methods on paramtypes.ParamSpace. +type LegacyParamSubspace interface { + Get(ctx sdktypes.Context, key []byte, ptr interface{}) +} + // ParamKeyTable type declaration for parameters func ParamKeyTable() paramtypes.KeyTable { return paramtypes.NewKeyTable().RegisterParamSet(&ConsumerParams{}) From 2de60f504c75d868c026e0c9654a54623fbcdf33 Mon Sep 17 00:00:00 2001 From: MSalopek Date: Thu, 25 Apr 2024 15:55:03 +0200 Subject: [PATCH 14/35] fix!: revert PutUnbondingOnHold to desired behaviour (#1819) * fix!: revert PutUnbondingOnHold to desired behaviour * fix: correctly change AfterUnbondingInitiated --- x/ccv/provider/keeper/hooks.go | 40 ++++++++++------------------------ 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/x/ccv/provider/keeper/hooks.go b/x/ccv/provider/keeper/hooks.go index d99ab43c93..dee2b7869e 100644 --- a/x/ccv/provider/keeper/hooks.go +++ b/x/ccv/provider/keeper/hooks.go @@ -47,19 +47,6 @@ func (h Hooks) AfterUnbondingInitiated(goCtx context.Context, id uint64) error { // Do not put the unbonding op on hold if there are no consumer chains return nil } - // Call back into staking to tell it to stop this op from unbonding when the unbonding period is complete - if err := h.k.stakingKeeper.PutUnbondingOnHold(ctx, id); err != nil { - // Note: that in the case of a validator unbonding, AfterUnbondingInitiated is called - // from staking.EndBlock. - - // In this case PutUnbondingOnHold fails if either the unbonding operation was - // not found or the UnbondingOnHoldRefCount is negative. - - // This change should be updated for SDK v0.48 because it will include changes in handling - // check: https://github.com/cosmos/cosmos-sdk/pull/16043 - h.k.Logger(ctx).Error("unbonding could not be put on hold: %w", err) - return nil - } valsetUpdateID := h.k.GetValidatorSetUpdateId(ctx) unbondingOp := providertypes.UnbondingOp{ @@ -76,22 +63,19 @@ func (h Hooks) AfterUnbondingInitiated(goCtx context.Context, id uint64) error { h.k.SetUnbondingOp(ctx, unbondingOp) - // NOTE: This is a temporary fix for v0.47 -> we should not panic in this edge case - // since the AfterUnbondInitiatedHook can be called with a non-existing UnbondingEntry.id - // check: https://github.com/cosmos/cosmos-sdk/pull/16043 - // // Call back into staking to tell it to stop this op from unbonding when the unbonding period is complete - // if err := h.k.stakingKeeper.PutUnbondingOnHold(ctx, id); err != nil { - // // If there was an error putting the unbonding on hold, panic to end execution for - // // the current tx and prevent committal of this invalid state. - // // - // // Note: that in the case of a validator unbonding, AfterUnbondingInitiated is called - // // from staking.EndBlock, thus the following panic would halt the chain. - // // In this case PutUnbondingOnHold fails if either the unbonding operation was - // // not found or the UnbondingOnHoldRefCount is negative. In either cases, - // // the state of the x/staking module of cosmos-sdk is invalid. - // panic(fmt.Errorf("unbonding could not be put on hold: %w", err)) - // } + if err := h.k.stakingKeeper.PutUnbondingOnHold(ctx, id); err != nil { + // If there was an error putting the unbonding on hold, panic to end execution for + // the current tx and prevent committal of this invalid state. + // + // Note: that in the case of a validator unbonding, AfterUnbondingInitiated is called + // from staking.EndBlock, thus the following panic would halt the chain. + + // In this case PutUnbondingOnHold fails if either the unbonding operation was + // not found or the UnbondingOnHoldRefCount is negative. In either cases, + // the state of the x/staking module of cosmos-sdk is invalid. + panic(fmt.Errorf("unbonding could not be put on hold: %w", err)) + } return nil } From 637713b37bd34b88e1196b111822ed3ebbe49dca Mon Sep 17 00:00:00 2001 From: MSalopek Date: Thu, 25 Apr 2024 20:02:38 +0200 Subject: [PATCH 15/35] docs: add v5 migration instructions (#1820) * docs: add v5 migration instructions * docs: fix typos * docs: add internal v50 update notes --- docs/docs/upgrading/_category_.json | 4 + docs/docs/upgrading/migrate_v4_v5.md | 381 ++++++++++++++++++ .../migrations/cosmos-sdk-v0.50-migration.md | 353 ++++++++++++++++ x/ccv/provider/keeper/legacy_proposal.go | 2 - 4 files changed, 738 insertions(+), 2 deletions(-) create mode 100644 docs/docs/upgrading/_category_.json create mode 100644 docs/docs/upgrading/migrate_v4_v5.md create mode 100644 docs/internal/migrations/cosmos-sdk-v0.50-migration.md diff --git a/docs/docs/upgrading/_category_.json b/docs/docs/upgrading/_category_.json new file mode 100644 index 0000000000..372e6c1900 --- /dev/null +++ b/docs/docs/upgrading/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Upgrading", + "position": 2 +} diff --git a/docs/docs/upgrading/migrate_v4_v5.md b/docs/docs/upgrading/migrate_v4_v5.md new file mode 100644 index 0000000000..d655984b54 --- /dev/null +++ b/docs/docs/upgrading/migrate_v4_v5.md @@ -0,0 +1,381 @@ +--- +sidebar_position: 1 +--- + +# Upgrading to ICS v5.0.0 + +This ICS version uses cosmos-sdk v0.50.x and ibc-go v8.x. + +To migrate you application to cosmos-sdk v0.50.x please use this [guide](https://docs.cosmos.network/v0.50/build/migrations/upgrading). + +To migrate your application to ibc-go v8.x.y please use the following guides: + * [migrate ibc-go to v8.0.0](https://ibc.cosmos.network/main/migrations/v7-to-v8) + * [migrate ibc-go to v8.1.0](https://ibc.cosmos.network/main/migrations/v8-to-v8_1) + + +ICS specific changes are outlined below. + +Pre-requisite version for this upgrade: `v4.x`. + +## Provider + +### Keeper initialization + +```diff +// app.go + +app.ProviderKeeper = ibcproviderkeeper.NewKeeper( + appCodec, + keys[providertypes.StoreKey], + app.GetSubspace(providertypes.ModuleName), + scopedIBCProviderKeeper, + app.IBCKeeper.ChannelKeeper, +- app.IBCKeeper.PortKeeper ++ app.IBCKeeper.PortKeeper, + app.IBCKeeper.ConnectionKeeper, + app.IBCKeeper.ClientKeeper, + app.StakingKeeper, + app.SlashingKeeper, + app.AccountKeeper, + app.DistrKeeper, + app.BankKeeper, + *app.GovKeeper, ++ authtypes.NewModuleAddress(govtypes.ModuleName).String(), ++ authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), ++ authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), + authtypes.FeeCollectorName, +) +``` + +* `authority` was added - requirement for executing `MsgUpdateParams` + * uses `x/gov` module address by default + +* `validatorAddressCodec` & `consensusAddressCodec` were added - they must match the bech32 address codec used by `x/auth`, `x/bank`, `x/staking` + + +### Protocol changes + +#### Revert `AfterUnbondingInitiated` + +`AfterUnbondingInitiated` behavior was reverted to [ICS@v1.2.0-multiden](https://github.com/cosmos/interchain-security/blob/v1.2.0-multiden/x/ccv/provider/keeper/hooks.go#L53) + +The revert re-introduces an additional state check. + +See this [issue](https://github.com/cosmos/interchain-security/issues/1045) for more context and the actions taken. + + +### Migration (v4 -> v5) + +ConensusVersion was bumped to `5`. + +The migration allows storing the provider module params in the `x/ccv/provider` module store instead of relying on legacy `x/param` store. + +There are no special requirements for executing this migration. + + +### Additions + +### MsgUpdateParams transaction + +`x/gov` module account is selected as the default `authority`. + +It is available when using `gov` CLI commands: + +Drafting a proposal: + +```shell +interchain-security-pd tx gov draft-proposal +# select "other" +# find and select "/interchain_security.ccv.provider.v1.MsgUpdateParams" +``` + +Submitting a proposal: + +```shell +interchain-security-pd tx gov submit-proposal +``` + +Example `proposal-message.json`: + +```json +{ + "messages": [ + { + "@type": "/interchain_security.ccv.provider.v1.MsgUpdateParams", + "authority": "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn", + "params": { + "trusting_period_fraction": "0.66", + "ccv_timeout_period": "2419200s", + "init_timeout_period": "604800s", + "vsc_timeout_period": "3024000s", + "slash_meter_replenish_period": "3s", + "slash_meter_replenish_fraction": "1.0", + "consumer_reward_denom_registration_fee": { + "denom": "stake", + "amount": "10000000" + }, + "blocks_per_epoch": "600" + } + } + ], + "metadata": "ipfs://CID", + "deposit": "10000stake", + "title": "Update Provider params", + "summary": "Update Provider params", + "expedited": false +} +``` + +### + +When updating parameters **all** parameters fields must be specified. Make sure you are only changing parameters that you are interested in. + +To avoid accidentally changing parameters you can first check the current on-chain provider params using: + +```shell +interchain-security-pd q provider params -o json + +{ + "template_client": {...}, + "trusting_period_fraction": "0.66", + "ccv_timeout_period": "2419200s", + "init_timeout_period": "604800s", + "vsc_timeout_period": "3024000s", + "slash_meter_replenish_period": "3s", + "slash_meter_replenish_fraction": "1.0", + "consumer_reward_denom_registration_fee": { + "denom": "stake", + "amount": "10000000" + }, + "blocks_per_epoch": "600" +} +``` + +### Governance proposals + +Submitting the following legacy proposals is still supported: + +# Consumer addition proposal + +```shell +interchain-security-pd tx gov submit-legacy-proposal consumer-addition +``` + +# Consumer removal proposal + +```shell +interchain-security-pd tx gov submit-legacy-proposal consumer-removal +``` + +# Consumer addition proposal +```shell +interchain-security-pd tx gov submit-legacy-proposal change-reward-denoms +``` + +You may also submit proposal messages above using `submit-proposal`. + + +## Consumer + +### Keeper initialization + +```diff +// pre-initialize ConsumerKeeper to satsfy ibckeeper.NewKeeper +app.ConsumerKeeper = ibcconsumerkeeper.NewNonZeroKeeper( + appCodec, + keys[ibcconsumertypes.StoreKey], + app.GetSubspace(ibcconsumertypes.ModuleName), +) + +app.IBCKeeper = ibckeeper.NewKeeper( + appCodec, + keys[ibchost.StoreKey], + app.GetSubspace(ibchost.ModuleName), + app.ConsumerKeeper, + app.UpgradeKeeper, + scopedIBCKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), +) + +// initialize the actual consumer keeper +app.ConsumerKeeper = ibcconsumerkeeper.NewKeeper( + appCodec, + keys[ibcconsumertypes.StoreKey], + app.GetSubspace(ibcconsumertypes.ModuleName), + scopedIBCConsumerKeeper, + app.IBCKeeper.ChannelKeeper, +- &app.IBCKeeper.PortKeeper, ++ app.IBCKeeper.PortKeeper, + app.IBCKeeper.ConnectionKeeper, + app.IBCKeeper.ClientKeeper, + app.SlashingKeeper, + app.BankKeeper, + app.AccountKeeper, + &app.TransferKeeper, + app.IBCKeeper, + authtypes.FeeCollectorName, + + // make sure the authority address makes sense for your chain + // the exact module account may differ depending on your setup (x/gov, x/admin or custom module) + // for x/ccv/democracy using the x/gov module address is correct + // if you don't have a way of updating consumer params you may still use the line below as it will have no affect ++ authtypes.NewModuleAddress(govtypes.ModuleName).String(), + + // add address codecs ++ authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), ++ authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), +) +``` + + +* `authority` was added - requirement for executing `MsgUpdateParams` + * make sure the authority address makes sense for your chain + * the exact module account may differ depending on your setup (`x/gov`, `x/admin` or custom module) + * for `x/ccv/democracy` using the `x/gov` module address is correct + * if you don't have a way of updating consumer params you may use `authtypes.NewModuleAddress(govtypes.ModuleName).String()` (has no effect on functionality) + +* `validatorAddressCodec` & `consensusAddressCodec` were added - they must match the bech32 address codec used by `x/auth`, `x/bank`, `x/staking` + + +### Additions + +#### `MsgUpdateParams` transaction + +**This functionality is not supported on `x/ccv/consumer` without additional configuration.** +* if you are using `x/ccv/democracy` the feature is supported out of the box +* if you are using custom logic for changing consumer params, please update your code by providing the appropriate `authority` module account during `ConsumerKeeper` initialization in `app.go`. + +**You must add `"/interchain_security.ccv.consumer.v1.MsgUpdateParams"` to your parameters whitelist to be able to change `ccvconsumer` parameters via governance.** + +It is available when using `gov` CLI commands: + +Drafting a proposal: + +```shell +interchain-security-cd tx gov draft-proposal +# select "other" +# find and select "/interchain_security.ccv.consumer.v1.MsgUpdateParams" +``` + +Submitting a proposal: +* **this proposal cannot be executed on chains without access to `x/gov` or other modules for managing governance** + +```shell + +interchain-security-cdd tx gov submit-proposal + +``` + +Example `proposal-message.json`. +```json +{ + "messages": [ + { + "@type": "/interchain_security.ccv.consumer.v1.MsgUpdateParams", + "authority": "consumer10d07y265gmmuvt4z0w9aw880jnsr700jlh7295", + "params": { + "enabled": true, + "blocks_per_distribution_transmission": "20", + "distribution_transmission_channel": "channel-1", + "provider_fee_pool_addr_str": "", + "ccv_timeout_period": "2419200s", + "transfer_timeout_period": "3000s", + "consumer_redistribution_fraction": "0.75", + "historical_entries": "10000", + "unbonding_period": "1209600s", + "soft_opt_out_threshold": "0.05", + "reward_denoms": [], + "provider_reward_denoms": [], + "retry_delay_period": "3000s" + } + } + ], + "metadata": "ipfs://CID", + "deposit": "1000uatom", + "title": "Update Consumer Params -- change transfer_timeout_period to 3000s", + "summary": "Test Update Consumer Params", + "expedited": false +} +``` + +When updating parameters **all** parameters fields must be specified. Make sure you are only changing parameters that you are interested in. + +To avoid accidentally changing parameters you can first check the current on-chain consumer params using: + +```shell +interchain-security-pd q ccvconsumer params -o json +``` + + +#### Params Query + +Consumer params query was added: +```shell +interchain-security-cd q ccvconsumer params -o json + +{ + "params": { + "enabled": true, + "blocks_per_distribution_transmission": "1000", + "distribution_transmission_channel": "", + "provider_fee_pool_addr_str": "", + "ccv_timeout_period": "2419200s", + "transfer_timeout_period": "3600s", + "consumer_redistribution_fraction": "0.75", + "historical_entries": "10000", + "unbonding_period": "1209600s", + "soft_opt_out_threshold": "0.05", + "reward_denoms": [], + "provider_reward_denoms": [], + "retry_delay_period": "3600s" + } +} +``` + + +### Migration (v2 -> v3) +ConensusVersion was bumped to `3`. + +The migration allows storing the consumer module params in the `x/ccv/consumer` module store instead of relying on legacy `x/param` store. + +There are no special requirements for executing this migration. + + +### Interface method changes +Consumer methods were changed to match the cosmos-sdk `StakingKeeper` interface. +You will not need to change your code, unless you are using the `ConsumerKeeper` inside custom tests or you have developed custom app functionality that relies on `ConsumerKeeper`. + +Please check the list below if you are using any of the consumer methods: +```go +type StakingKeeper interface { + UnbondingTime(ctx context.Context) (time.Duration, error) + GetValidatorByConsAddr(ctx context.Context, consAddr sdk.ConsAddress) (stakingtypes.Validator, error) + GetLastValidatorPower(ctx context.Context, operator sdk.ValAddress) (int64, error) + Jail(context.Context, sdk.ConsAddress) error // jail a validator + Slash(ctx context.Context, consAddr sdk.ConsAddress, infractionHeight, power int64, slashFactor math.LegacyDec) (math.Int, error) + SlashWithInfractionReason(ctx context.Context, consAddr sdk.ConsAddress, infractionHeight, power int64, slashFactor math.LegacyDec, infraction stakingtypes.Infraction) (math.Int, error) + Unjail(ctx context.Context, addr sdk.ConsAddress) error + GetValidator(ctx context.Context, addr sdk.ValAddress) (stakingtypes.Validator, error) + IterateLastValidatorPowers(ctx context.Context, cb func(addr sdk.ValAddress, power int64) (stop bool)) error + IterateValidators(ctx context.Context, f func(index int64, validator stakingtypes.ValidatorI) (stop bool)) error + Validator(ctx context.Context, addr sdk.ValAddress) (stakingtypes.ValidatorI, error) + IsValidatorJailed(ctx context.Context, addr sdk.ConsAddress) (bool, error) + ValidatorByConsAddr(ctx context.Context, consAddr sdk.ConsAddress) (stakingtypes.ValidatorI, error) + Delegation(ctx context.Context, addr sdk.AccAddress, valAddr sdk.ValAddress) (stakingtypes.DelegationI, error) + MaxValidators(ctx context.Context) (uint32, error) +} +``` + +The consumer implements the `StakingKeeper` interface shown above. + +## Democracy + +Changes in `Consumer` also apply to `Democracy`. + +Democracy `x/staking`, `x/distribution` and `x/gov` were updated to reflect changes in `cosmos-sdk v0.50.x`. + +There were no notable changes arising to the module functionality aside from conforming to `cosmos-sdk v0.50.x`. + + +## Note: +You must add `"/interchain_security.ccv.consumer.v1.MsgUpdateParams"` to your parameters whitelist to be able to change `consumer` parameters via governance. diff --git a/docs/internal/migrations/cosmos-sdk-v0.50-migration.md b/docs/internal/migrations/cosmos-sdk-v0.50-migration.md new file mode 100644 index 0000000000..9844de696e --- /dev/null +++ b/docs/internal/migrations/cosmos-sdk-v0.50-migration.md @@ -0,0 +1,353 @@ +# cosmos-sdk v0.50.x internal upgrade doc + +This file lists various changes that were needed when upgrading from cosmos-sdk v0.47.x -> v0.50.x. + +Upgrade instructions used: +* https://docs.cosmos.network/v0.50/migrations/upgrading +* https://ibc.cosmos.network/main/migrations/v7-to-v8.html +* https://ibc.cosmos.network/main/migrations/v8-to-v8_1 + +## Proto files +Some proto files needed to be updated to reflect changes required for cosmos-sdk v50. + +## Provider proto changes + +### proto/interchain_security/ccv/provider/v1/tx.proto + +Added rpc methods and message types to support v50 governance (`submit-proposal`) +* `rpc ConsumerAddition` +* `rpc ConsumerRemoval` +* `message MsgUpdateParams` +* `message MsgConsumerAddition` +* `message MsgConsumerRemoval` +* `message MsgChangeRewardDenoms` +* `message MsgUpdateParams` + + +Update existing messages with `option (cosmos.msg.v1.signer) = "signer"` so they are considered as Tx messages by v50. +* `message MsgAssignConsumerKey` + +`message MsgUpdateParams` was added to support updating params via governance. + + +## Generating protos with updated dependencies: + +``` +# update Makefile containerProtoVersion to latest (v0.14.0) +cd proto +# update buf.yml +buf mod update +cd .. +make proto-gen +``` + +### Steps for upgrading cosmos-sdk and ibc-go +Key dependencies: +* `cosmos-sdk@v0.50.4` +* `ibc-go/v8@v8.1.0` +* `ibc-go/modules/capability@v1.0.0` + +```shell +go get github.com/cosmos/cosmos-sdk@v0.50.4 +go get github.com/cosmos/ibc-go/v8@v8.1.0 +go get github.com/cosmos/ibc-go/modules/capability@v1.0.0-rc5 +``` + +`ibc-go/v8` is using the `x/capability` module that lives in `github.com/cosmos/ibc-go/modules/capability`. +* this module was added after all the file imports were changed for ibc-go (from v7 -> v8) to avoid weird import behaviour + +### Search & replace +* github.com/cosmos/ibc-go/v7 -> github.com/cosmos/ibc-go/v8 +* github.com/cosmos/cosmos-sdk/store -> cosmossdk.io/store +* github.com/cosmos/cosmos-sdk/x/feegrant -> cosmossdk.io/x/feegrant +* github.com/cosmos/cosmos-sdk/x/evidence -> cosmossdk.io/x/evidence +* github.com/cosmos/cosmos-sdk/x/upgrade -> cosmossdk.io/x/upgrade + +* github.com/cometbft/cometbft/libs/log -> cosmossdk.io/log +* github.com/cosmos/cosmos-sdk/x/capability/keeper -> github.com/cosmos/ibc-go/modules/capability +* github.com/cosmos/cosmos-sdk/client/grpc/tmservice -> github.com/cosmos/cosmos-sdk/client/grpc/cmtservice + +### Remove +* cosmossdk.io/x/upgrade/client -> no longer exists and not needed +* github.com/cosmos/ibc-go/v7/modules/core/02-client/client -> these gov handlers no longer exist (deprecated) + +### Math search & replace +* use `math.LegacyDec` instead of `sdk.Dec` and other types + * eg. `sdk.NewDecFromStr`, `sdktypes.NewDecFromStr`, `sdk.NewDec` + * `sdk.ZeroDec` -> `math.LegacyZeroDec` + * `sdk.NewDecFromInt` -> `math.LegacyNewDecFromInt` + * `sdk.MustNewDecFromStr` -> `math.LegacyMustNewDecFromStr` + * `sdk.NewDecFromInt` -> `math.LegacyNewDecFromInt` + * `sdk.OneDec` -> `math.LegacyOneDec` + * `sdk.NewDecWithPrec` -> `math.LegacyNewDecWithPrec` + * also update all function defintions that are using them + +* use `math.NewInt` instead of `sdk.NewInt` + * `sdktypes.NewInt`, + * `sdktypes.ZeroInt` -> `math.ZeroInt` + * also update all dunction definitions that are using them + +## Genesis +`expedited_voting_period` was introduced. All functions using gov proposals needed to be updated to support `expedited_voting_period (bool)` + + +## Governance proposals (provider) +Legacy proposal handlers were modified to reflect cosmos-sdk v0.50.x changes. Legacy proposals are still supported. + +## Query & Tx +AutoCLI usage was added. + +To use AutoCLI all Txs must be annotated with `option (cosmos.msg.v1.service) = true`; + + +## ICS code changes + +## migrate x/staking & x/slashing interfaces + +New interfaces match x/staking and x/slashing on cosmos-sdk v0.50.x. + +```go +type StakingKeeper interface { + GetValidatorUpdates(ctx context.Context) ([]abci.ValidatorUpdate, error) + UnbondingCanComplete(ctx context.Context, id uint64) error + UnbondingTime(ctx context.Context) (time.Duration, error) + GetValidatorByConsAddr(ctx context.Context, consAddr sdk.ConsAddress) (stakingtypes.Validator, error) + GetLastValidatorPower(ctx context.Context, operator sdk.ValAddress) (int64, error) + Jail(context.Context, sdk.ConsAddress) error // jail a validator + Slash(ctx context.Context, consAddr sdk.ConsAddress, infractionHeight, power int64, slashFactor math.LegacyDec) (math.Int, error) + SlashWithInfractionReason(ctx context.Context, consAddr sdk.ConsAddress, infractionHeight, power int64, slashFactor math.LegacyDec, infraction stakingtypes.Infraction) (math.Int, error) + SlashUnbondingDelegation(ctx context.Context, unbondingDelegation stakingtypes.UnbondingDelegation, infractionHeight int64, slashFactor math.LegacyDec) (math.Int, error) + SlashRedelegation(ctx context.Context, srcValidator stakingtypes.Validator, redelegation stakingtypes.Redelegation, infractionHeight int64, slashFactor math.LegacyDec) (math.Int, error) + Unjail(ctx context.Context, addr sdk.ConsAddress) error + GetValidator(ctx context.Context, addr sdk.ValAddress) (stakingtypes.Validator, error) + IterateLastValidatorPowers(ctx context.Context, cb func(addr sdk.ValAddress, power int64) (stop bool)) error + PowerReduction(ctx context.Context) math.Int + PutUnbondingOnHold(ctx context.Context, id uint64) error + IterateValidators(ctx context.Context, f func(index int64, validator stakingtypes.ValidatorI) (stop bool)) error + Validator(ctx context.Context, addr sdk.ValAddress) (stakingtypes.ValidatorI, error) + IsValidatorJailed(ctx context.Context, addr sdk.ConsAddress) (bool, error) + ValidatorByConsAddr(ctx context.Context, consAddr sdk.ConsAddress) (stakingtypes.ValidatorI, error) + Delegation(ctx context.Context, addr sdk.AccAddress, valAddr sdk.ValAddress) (stakingtypes.DelegationI, error) + MaxValidators(ctx context.Context) (uint32, error) + GetLastTotalPower(ctx context.Context) (math.Int, error) + GetLastValidators(ctx context.Context) ([]stakingtypes.Validator, error) + BondDenom(ctx context.Context) (string, error) + GetUnbondingDelegationsFromValidator(ctx context.Context, valAddr sdk.ValAddress) ([]stakingtypes.UnbondingDelegation, error) + GetRedelegationsFromSrcValidator(ctx context.Context, valAddr sdk.ValAddress) ([]stakingtypes.Redelegation, error) + GetUnbondingType(ctx context.Context, id uint64) (stakingtypes.UnbondingType, error) +} + +type SlashingKeeper interface { + JailUntil(context.Context, sdk.ConsAddress, time.Time) error // called from provider keeper only + GetValidatorSigningInfo(context.Context, sdk.ConsAddress) (slashingtypes.ValidatorSigningInfo, error) + SetValidatorSigningInfo(context.Context, sdk.ConsAddress, slashingtypes.ValidatorSigningInfo) error + DowntimeJailDuration(context.Context) (time.Duration, error) + SlashFractionDowntime(context.Context) (math.LegacyDec, error) + SlashFractionDoubleSign(context.Context) (math.LegacyDec, error) + Tombstone(context.Context, sdk.ConsAddress) error + IsTombstoned(context.Context, sdk.ConsAddress) bool +} +``` + +Changes to these interfaces required changing unit and integration test assertions. Almost all methods are now returning an `error`. Previously, almost none of the methods were returning errors. + +## Refactoring ICS keepers + +### Context +Instead of using `sdk.Context` we need to use `context.Context`. + +Example: +```go +func (k Keeper) Logger(ctx context.Context) log.Logger { + sdkCtx := sdk.UnwrapSDKContext(ctx) // we accept context.Context and unwrap it + return sdkCtx.Logger().With("module", "x/"+ibchost.ModuleName+"-"+types.ModuleName) +} +``` + +Remaining work for future upgrades: +* allow store access via `k.storeService.OpenKVStore(ctx)` instead of `ctx.KVStore(k.storeKey)`. + + +### validator.GetConsAddr() +Cannot do `sdk.ConsAddress(validatorConsumerAddrs.ConsumerAddr).Equals(consensusAddr)` because `.Equals()` now takes a `sdk.Address` interface type. +Change to `sdk.ConsAddress(validatorConsumerAddrs.ConsumerAddr).Equals(sdk.ConsAddress(consensusAddr))` + + + +### ICS keepers initialization +```go +type Keeper struct { + // the address capable of executing a MsgUpdateParams message. Typically, this + // should be the x/gov module account. + authority string + + // address codecs were added + validatorAddressCodec addresscodec.Codec + consensusAddressCodec addresscodec.Codec +} + +// GetAuthority returns the module's authority. +func (k Keeper) GetAuthority() string { + return k.authority +} + +``` + + +### Hooks +In v0.50.x hooks are setup in the `keeper.go` + +```go +// Hooks gets the hooks for staking *Keeper +func (k *Keeper) Hooks() types.StakingHooks { + if k.hooks == nil { + // return a no-op implementation if no hooks are set + return types.MultiStakingHooks{} + } + + return k.hooks +} + +// SetHooks sets the validator hooks. In contrast to other receivers, this method must take a pointer due to nature +// of the hooks interface and SDK start up sequence. +func (k *Keeper) SetHooks(sh types.StakingHooks) { + if k.hooks != nil { + panic("cannot set validator hooks twice") + } + + k.hooks = sh +} +``` + +## Proposals + +`sdk.Handler` no longer exists and needs to be replaced with `baseapp.MsgServiceHandler +```diff +// x/ccv/provider/handler.go +-func NewHandler(k *keeper.Keeper) sdk.Handler { +- msgServer := keeper.NewMsgServerImpl(k) ++func NewHandler(k *keeper.Keeper) sdk.Handler { ++ msgServer := keeper.NewMsgServerImpl(k) + // ... +} +``` + + +## validator.GetOperator() has different return type +Previously `validator.GetOperator()` was returning `sdk.ValAddress`. In v0.50.x it returns a `string`. + +Additional processing is required when fetching validator operator address: +```diff +-slashedVal.GetOperator() ++providerKeeper.ValidatorAddressCodec().StringToBytes(slashedVal.GetOperator()) +``` + +Example: +```diff +// from integration tests +-lastValPower := providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), slashedVal.GetOperator()) ++slashedValOperator, err := providerKeeper.ValidatorAddressCodec().StringToBytes(slashedVal.GetOperator()) // must get the addr bytes first ++s.Require().NoError(err) ++lastValPower, err := providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), slashedValOperator) +``` + + +## evidencekeeper equivocation handling was made private + +```diff +type EvidenceKeeper interface { +- HandleEquivocationEvidence(ctx sdk.Context, evidence *evidencetypes.Equivocation) ++ handleEquivocationEvidence(ctx sdk.Context, evidence *evidencetypes.Equivocation) +} +``` + +This method is only used in integration testing. To preserve testing, the method was copied and modified to fit the testing use case. +```go +// copy of the function from slashing/keeper.go +// in cosmos-sdk v0.50.x the function HandleEquivocationEvidence is not exposed (it was exposed for versions <= v0.47.x) +// https://github.com/cosmos/cosmos-sdk/blob/v0.50.4/x/evidence/keeper/infraction.go#L27 +func handleEquivocationEvidence(ctx context.Context, k integration.ConsumerApp, evidence *types.Equivocation) error { + sdkCtx := sdk.UnwrapSDKContext(ctx) + slashingKeeper := k.GetTestSlashingKeeper().(slashingkeeper.Keeper) + evidenceKeeper := k.GetTestEvidenceKeeper() + consAddr := evidence.GetConsensusAddress(k.GetConsumerKeeper().ConsensusAddressCodec()) + + validator, err := k.GetConsumerKeeper().ValidatorByConsAddr(ctx, consAddr) + if err != nil { + return err + } + if validator == nil || validator.IsUnbonded() { + return nil + } + + if len(validator.GetOperator()) != 0 { + if _, err := slashingKeeper.GetPubkey(ctx, consAddr.Bytes()); err != nil { + return nil + } + } + + // calculate the age of the evidence + infractionHeight := evidence.GetHeight() + infractionTime := evidence.GetTime() + ageDuration := sdkCtx.BlockHeader().Time.Sub(infractionTime) + ageBlocks := sdkCtx.BlockHeader().Height - infractionHeight + + // Reject evidence if the double-sign is too old. Evidence is considered stale + // if the difference in time and number of blocks is greater than the allowed + // parameters defined. + cp := sdkCtx.ConsensusParams() + if cp.Evidence != nil { + if ageDuration > cp.Evidence.MaxAgeDuration && ageBlocks > cp.Evidence.MaxAgeNumBlocks { + return nil + } + } + + if ok := slashingKeeper.HasValidatorSigningInfo(ctx, consAddr); !ok { + panic(fmt.Sprintf("expected signing info for validator %s but not found", consAddr)) + } + + // ignore if the validator is already tombstoned + if slashingKeeper.IsTombstoned(ctx, consAddr) { + return nil + } + + distributionHeight := infractionHeight - sdk.ValidatorUpdateDelay + slashFractionDoubleSign, err := slashingKeeper.SlashFractionDoubleSign(ctx) + if err != nil { + return err + } + + err = slashingKeeper.SlashWithInfractionReason( + ctx, + consAddr, + slashFractionDoubleSign, + evidence.GetValidatorPower(), distributionHeight, + stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN, + ) + if err != nil { + return err + } + + // Jail the validator if not already jailed. This will begin unbonding the + // validator if not already unbonding (tombstoned). + if !validator.IsJailed() { + err = slashingKeeper.Jail(ctx, consAddr) + if err != nil { + return err + } + } + + err = slashingKeeper.JailUntil(ctx, consAddr, types.DoubleSignJailEndTime) + if err != nil { + return err + } + + err = slashingKeeper.Tombstone(ctx, consAddr) + if err != nil { + return err + } + return evidenceKeeper.Evidences.Set(ctx, evidence.Hash(), evidence) +} + +``` + diff --git a/x/ccv/provider/keeper/legacy_proposal.go b/x/ccv/provider/keeper/legacy_proposal.go index 2ea1353173..a5391ceff3 100644 --- a/x/ccv/provider/keeper/legacy_proposal.go +++ b/x/ccv/provider/keeper/legacy_proposal.go @@ -34,7 +34,6 @@ func (k Keeper) HandleLegacyConsumerRewardDenomProposal(ctx sdk.Context, p *type return nil } -// [DEPRECATED] // HandleConsumerAdditionProposal will receive the consumer chain's client state from the proposal. // If the client can be successfully created in a cached context, it stores the proposal as a pending proposal. // @@ -59,7 +58,6 @@ func (k Keeper) HandleLegacyConsumerAdditionProposal(ctx sdk.Context, p *types.C return nil } -// [DEPRECATED] // HandleConsumerRemovalProposal stops a consumer chain and released the outstanding unbonding operations. // If the consumer can be successfully stopped in a cached context, it stores the proposal as a pending proposal. // From 81c8a9220e040e65f6efaa92acb6e24efc4aab4b Mon Sep 17 00:00:00 2001 From: bernd-m <43466467+bermuell@users.noreply.github.com> Date: Tue, 30 Apr 2024 11:30:53 +0200 Subject: [PATCH 16/35] test: adapt e2e compatibility tests v5.x (#1828) * refactor e2e * e2e tests infra for compatibility testing * fix compatibility tests * adapt nightly runs * cleanup * addressed comments --- .github/workflows/nightly-e2e.yml | 4 +- tests/e2e/actions.go | 608 +++++++++---------- tests/e2e/actions_consumer_misbehaviour.go | 24 +- tests/e2e/actions_sovereign_chain.go | 37 +- tests/e2e/config.go | 144 ++--- tests/e2e/json_marshal_test.go | 3 +- tests/e2e/json_utils.go | 103 ---- tests/e2e/state.go | 626 +++++++++----------- tests/e2e/steps_compatibility.go | 4 +- tests/e2e/test_driver.go | 141 +++-- tests/e2e/test_target.go | 8 +- tests/e2e/testlib/types.go | 339 +++++++++++ tests/e2e/testlib/utils.go | 43 ++ tests/e2e/v4/state.go | 654 +++++++++++++++++++++ 14 files changed, 1782 insertions(+), 956 deletions(-) create mode 100644 tests/e2e/testlib/types.go create mode 100644 tests/e2e/testlib/utils.go create mode 100644 tests/e2e/v4/state.go diff --git a/.github/workflows/nightly-e2e.yml b/.github/workflows/nightly-e2e.yml index 3e8cc7d614..ca560550ca 100644 --- a/.github/workflows/nightly-e2e.yml +++ b/.github/workflows/nightly-e2e.yml @@ -18,7 +18,7 @@ on: jobs: compatibility-test: runs-on: ubuntu-latest - timeout-minutes: 180 + timeout-minutes: 200 steps: - uses: actions/setup-go@v5 with: @@ -36,7 +36,7 @@ jobs: # Run compatibility tests for different consumer (-cv) and provider (-pv) versions. # Combination of all provider versions with consumer versions are tested. # For new versions to be tested add/modify -pc/-cv parameters. - run: go run ./tests/e2e/... --tc compatibility -pv latest -pv v4.0.0 -pv v3.3.3-lsm -cv latest -cv v4.0.0 -cv v3.3.0 -cv v3.2.0 + run: go run ./tests/e2e/... --tc compatibility -pv latest -pv v5.0.0-rc0 -pv v4.1.1-lsm -pv v3.3.3-lsm -cv latest -cv v5.0.0-rc0 -cv v4.1.1 -cv v3.3.0 -cv v3.2.0 happy-path-test: runs-on: ubuntu-latest timeout-minutes: 20 diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index ca185aadea..8821aa40e5 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -19,6 +19,7 @@ import ( "github.com/tidwall/gjson" "golang.org/x/mod/semver" + e2e "github.com/cosmos/interchain-security/v5/tests/e2e/testlib" "github.com/cosmos/interchain-security/v5/x/ccv/provider/client" "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" @@ -40,13 +41,12 @@ type SendTokensAction struct { Amount uint } -func (tr TestConfig) sendTokens( +func (tr Chain) sendTokens( action SendTokensAction, - target ExecutionTarget, verbose bool, ) { - fromValCfg := tr.validatorConfigs[action.From] - toValCfg := tr.validatorConfigs[action.To] + fromValCfg := tr.testConfig.validatorConfigs[action.From] + toValCfg := tr.testConfig.validatorConfigs[action.To] fromAddress := fromValCfg.DelAddress toAddress := toValCfg.DelAddress if action.Chain != ChainID("provi") { @@ -65,15 +65,15 @@ func (tr TestConfig) sendTokens( } } - binaryName := tr.chainConfigs[action.Chain].BinaryName - cmd := target.ExecCommand(binaryName, + binaryName := tr.testConfig.chainConfigs[action.Chain].BinaryName + cmd := tr.target.ExecCommand(binaryName, "tx", "bank", "send", fromAddress, toAddress, fmt.Sprint(action.Amount)+`stake`, - `--chain-id`, string(tr.chainConfigs[action.Chain].ChainId), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, action.From), `--node`, tr.getValidatorNode(action.Chain, action.From), `--keyring-backend`, `test`, @@ -105,12 +105,11 @@ type StartChainValidator struct { Stake uint } -func (tr *TestConfig) startChain( +func (tr *Chain) startChain( action StartChainAction, - target ExecutionTarget, verbose bool, ) { - chainConfig := tr.chainConfigs[action.Chain] + chainConfig := tr.testConfig.chainConfigs[action.Chain] type jsonValAttrs struct { Mnemonic string `json:"mnemonic"` Allocation string `json:"allocation"` @@ -128,18 +127,18 @@ func (tr *TestConfig) startChain( var validators []jsonValAttrs for _, val := range action.Validators { validators = append(validators, jsonValAttrs{ - Mnemonic: tr.validatorConfigs[val.Id].Mnemonic, - NodeKey: tr.validatorConfigs[val.Id].NodeKey, + Mnemonic: tr.testConfig.validatorConfigs[val.Id].Mnemonic, + NodeKey: tr.testConfig.validatorConfigs[val.Id].NodeKey, ValId: fmt.Sprint(val.Id), - PrivValidatorKey: tr.validatorConfigs[val.Id].PrivValidatorKey, + PrivValidatorKey: tr.testConfig.validatorConfigs[val.Id].PrivValidatorKey, Allocation: fmt.Sprint(val.Allocation) + "stake", Stake: fmt.Sprint(val.Stake) + "stake", - IpSuffix: tr.validatorConfigs[val.Id].IpSuffix, + IpSuffix: tr.testConfig.validatorConfigs[val.Id].IpSuffix, - ConsumerMnemonic: tr.validatorConfigs[val.Id].ConsumerMnemonic, - ConsumerPrivValidatorKey: tr.validatorConfigs[val.Id].ConsumerPrivValidatorKey, + ConsumerMnemonic: tr.testConfig.validatorConfigs[val.Id].ConsumerMnemonic, + ConsumerPrivValidatorKey: tr.testConfig.validatorConfigs[val.Id].ConsumerPrivValidatorKey, // if true node will be started with consumer key for each consumer chain - StartWithConsumerKey: tr.validatorConfigs[val.Id].UseConsumerKey, + StartWithConsumerKey: tr.testConfig.validatorConfigs[val.Id].UseConsumerKey, }) } @@ -157,14 +156,14 @@ func (tr *TestConfig) startChain( } var cometmockArg string - if tr.useCometmock { + if tr.testConfig.useCometmock { cometmockArg = "true" } else { cometmockArg = "false" } - startChainScript := target.GetTestScriptPath(action.IsConsumer, "start-chain.sh") - cmd := target.ExecCommand("/bin/bash", + startChainScript := tr.target.GetTestScriptPath(action.IsConsumer, "start-chain.sh") + cmd := tr.target.ExecCommand("/bin/bash", startChainScript, chainConfig.BinaryName, string(vals), string(chainConfig.ChainId), chainConfig.IpPrefix, genesisChanges, fmt.Sprint(action.IsConsumer), @@ -172,7 +171,7 @@ func (tr *TestConfig) startChain( // usually timeout_commit and peer_gossip_sleep_duration are changed to vary the test run duration // lower timeout_commit means the blocks are produced faster making the test run shorter // with short timeout_commit (eg. timeout_commit = 1s) some nodes may miss blocks causing the test run to fail - tr.tendermintConfigOverride, + tr.testConfig.tendermintConfigOverride, cometmockArg, ) @@ -205,14 +204,14 @@ func (tr *TestConfig) startChain( Chain: action.Chain, Validator: action.Validators[0].Id, IsConsumer: action.IsConsumer, - }, target, verbose) + }, verbose) // store the fact that we started the chain - tr.runningChains[action.Chain] = true + tr.testConfig.runningChains[action.Chain] = true fmt.Println("Started chain", action.Chain) - if tr.timeOffset != 0 { + if tr.testConfig.timeOffset != 0 { // advance time for this chain so that it is in sync with the rest of the network - tr.AdvanceTimeForChain(action.Chain, tr.timeOffset) + tr.AdvanceTimeForChain(action.Chain, tr.testConfig.timeOffset) } } @@ -224,20 +223,19 @@ type SubmitTextProposalAction struct { Description string } -func (tr TestConfig) submitTextProposal( +func (tr Chain) submitTextProposal( action SubmitTextProposalAction, - target ExecutionTarget, verbose bool, ) { // TEXT PROPOSAL - bz, err := target.ExecCommand( - tr.chainConfigs[action.Chain].BinaryName, + bz, err := tr.target.ExecCommand( + tr.testConfig.chainConfigs[action.Chain].BinaryName, "tx", "gov", "submit-legacy-proposal", `--title`, action.Title, `--description`, action.Description, `--deposit`, fmt.Sprint(action.Deposit)+`stake`, `--from`, `validator`+fmt.Sprint(action.From), - `--chain-id`, string(tr.chainConfigs[action.Chain].ChainId), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, action.From), `--node`, tr.getValidatorNode(action.Chain, action.From), `--keyring-backend`, `test`, @@ -262,17 +260,16 @@ type SubmitConsumerAdditionProposalAction struct { DistributionChannel string } -func (tr TestConfig) submitConsumerAdditionProposal( +func (tr Chain) submitConsumerAdditionProposal( action SubmitConsumerAdditionProposalAction, - target ExecutionTarget, verbose bool, ) { - spawnTime := tr.containerConfig.Now.Add(time.Duration(action.SpawnTime) * time.Millisecond) + spawnTime := tr.testConfig.containerConfig.Now.Add(time.Duration(action.SpawnTime) * time.Millisecond) params := ccvtypes.DefaultParams() prop := client.ConsumerAdditionProposalJSON{ Title: "Propose the addition of a new chain", Summary: "Gonna be a great chain", - ChainId: string(tr.chainConfigs[action.ConsumerChain].ChainId), + ChainId: string(tr.testConfig.chainConfigs[action.ConsumerChain].ChainId), InitialHeight: action.InitialHeight, GenesisHash: []byte("gen_hash"), BinaryHash: []byte("bin_hash"), @@ -298,7 +295,7 @@ func (tr TestConfig) submitConsumerAdditionProposal( } //#nosec G204 -- bypass unsafe quoting warning (no production code) - bz, err = target.ExecCommand( + bz, err = tr.target.ExecCommand( "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/temp-proposal.json"), ).CombinedOutput() if err != nil { @@ -306,11 +303,11 @@ func (tr TestConfig) submitConsumerAdditionProposal( } // CONSUMER ADDITION PROPOSAL - cmd := target.ExecCommand( - tr.chainConfigs[action.Chain].BinaryName, + cmd := tr.target.ExecCommand( + tr.testConfig.chainConfigs[action.Chain].BinaryName, "tx", "gov", "submit-legacy-proposal", "consumer-addition", "/temp-proposal.json", `--from`, `validator`+fmt.Sprint(action.From), - `--chain-id`, string(tr.chainConfigs[action.Chain].ChainId), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, action.From), `--gas`, `900000`, `--node`, tr.getValidatorNode(action.Chain, action.From), @@ -344,16 +341,15 @@ type SubmitConsumerRemovalProposalAction struct { StopTimeOffset time.Duration // offset from time.Now() } -func (tr TestConfig) submitConsumerRemovalProposal( +func (tr Chain) submitConsumerRemovalProposal( action SubmitConsumerRemovalProposalAction, - target ExecutionTarget, verbose bool, ) { - stopTime := tr.containerConfig.Now.Add(action.StopTimeOffset) + stopTime := tr.testConfig.containerConfig.Now.Add(action.StopTimeOffset) prop := client.ConsumerRemovalProposalJSON{ Title: fmt.Sprintf("Stop the %v chain", action.ConsumerChain), Summary: "It was a great chain", - ChainId: string(tr.chainConfigs[action.ConsumerChain].ChainId), + ChainId: string(tr.testConfig.chainConfigs[action.ConsumerChain].ChainId), StopTime: stopTime, Deposit: fmt.Sprint(action.Deposit) + `stake`, } @@ -368,18 +364,18 @@ func (tr TestConfig) submitConsumerRemovalProposal( log.Fatal("prop json contains single quote") } - bz, err = target.ExecCommand( + bz, err = tr.target.ExecCommand( "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/temp-proposal.json")).CombinedOutput() if err != nil { log.Fatal(err, "\n", string(bz)) } - bz, err = target.ExecCommand( - tr.chainConfigs[action.Chain].BinaryName, + bz, err = tr.target.ExecCommand( + tr.testConfig.chainConfigs[action.Chain].BinaryName, "tx", "gov", "submit-legacy-proposal", "consumer-removal", "/temp-proposal.json", `--from`, `validator`+fmt.Sprint(action.From), - `--chain-id`, string(tr.chainConfigs[action.Chain].ChainId), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, action.From), `--node`, tr.getValidatorNode(action.Chain, action.From), `--gas`, "900000", @@ -401,9 +397,8 @@ type SubmitEnableTransfersProposalAction struct { Deposit uint } -func (tr TestConfig) submitEnableTransfersProposalAction( +func (tr Chain) submitEnableTransfersProposalAction( action SubmitEnableTransfersProposalAction, - target ExecutionTarget, verbose bool, ) { // gov signed addres got by checking the gov module acc address in the test container @@ -430,18 +425,18 @@ func (tr TestConfig) submitEnableTransfersProposalAction( jsonStr := fmt.Sprintf(template, action.Deposit, action.Title) //#nosec G204 -- bypass unsafe quoting warning (no production code) - bz, err := target.ExecCommand( + bz, err := tr.target.ExecCommand( "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/params-proposal.json"), ).CombinedOutput() if err != nil { log.Fatal(err, "\n", string(bz)) } - cmd := target.ExecCommand( - tr.chainConfigs[action.Chain].BinaryName, + cmd := tr.target.ExecCommand( + tr.testConfig.chainConfigs[action.Chain].BinaryName, "tx", "gov", "submit-proposal", "/params-proposal.json", `--from`, `validator`+fmt.Sprint(action.From), - `--chain-id`, string(tr.chainConfigs[action.Chain].ChainId), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, action.From), `--node`, tr.getValidatorNode(action.Chain, action.From), `--gas`, "900000", @@ -465,9 +460,8 @@ type VoteGovProposalAction struct { PropNumber uint } -func (tr *TestConfig) voteGovProposal( +func (tr *Chain) voteGovProposal( action VoteGovProposalAction, - target ExecutionTarget, verbose bool, ) { var wg sync.WaitGroup @@ -476,14 +470,14 @@ func (tr *TestConfig) voteGovProposal( vote := action.Vote[i] go func(val ValidatorID, vote string) { defer wg.Done() - bz, err := target.ExecCommand( - tr.chainConfigs[action.Chain].BinaryName, + bz, err := tr.target.ExecCommand( + tr.testConfig.chainConfigs[action.Chain].BinaryName, "tx", "gov", "vote", fmt.Sprint(action.PropNumber), vote, `--from`, `validator`+fmt.Sprint(val), - `--chain-id`, string(tr.chainConfigs[action.Chain].ChainId), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, val), `--node`, tr.getValidatorNode(action.Chain, val), `--keyring-backend`, `test`, @@ -499,7 +493,7 @@ func (tr *TestConfig) voteGovProposal( wg.Wait() // wait for inclusion in a block -> '--broadcast-mode block' is deprecated tr.waitBlocks(action.Chain, 1, 10*time.Second) - tr.WaitTime(time.Duration(tr.chainConfigs[action.Chain].VotingWaitTime) * time.Second) + tr.WaitTime(time.Duration(tr.testConfig.chainConfigs[action.Chain].VotingWaitTime) * time.Second) } type StartConsumerChainAction struct { @@ -509,14 +503,13 @@ type StartConsumerChainAction struct { GenesisChanges string } -func (tr *TestConfig) startConsumerChain( +func (tr *Chain) startConsumerChain( action StartConsumerChainAction, - target ExecutionTarget, verbose bool, ) { fmt.Println("Starting consumer chain ", action.ConsumerChain) - consumerGenesis := ".app_state.ccvconsumer = " + tr.getConsumerGenesis(action.ProviderChain, action.ConsumerChain, target) - consumerGenesisChanges := tr.chainConfigs[action.ConsumerChain].GenesisChanges + consumerGenesis := ".app_state.ccvconsumer = " + tr.getConsumerGenesis(action.ProviderChain, action.ConsumerChain) + consumerGenesisChanges := tr.testConfig.chainConfigs[action.ConsumerChain].GenesisChanges if consumerGenesisChanges != "" { consumerGenesis = consumerGenesis + " | " + consumerGenesisChanges + " | " + action.GenesisChanges } @@ -526,21 +519,21 @@ func (tr *TestConfig) startConsumerChain( Validators: action.Validators, GenesisChanges: consumerGenesis, IsConsumer: true, - }, target, verbose) + }, verbose) } // Get consumer genesis from provider -func (tr *TestConfig) getConsumerGenesis(providerChain, consumerChain ChainID, target ExecutionTarget) string { +func (tr *Chain) getConsumerGenesis(providerChain, consumerChain ChainID) string { fmt.Println("Exporting consumer genesis from provider") - providerBinaryName := tr.chainConfigs[providerChain].BinaryName + providerBinaryName := tr.testConfig.chainConfigs[providerChain].BinaryName - cmd := target.ExecCommand( + cmd := tr.target.ExecCommand( providerBinaryName, "query", "provider", "consumer-genesis", - string(tr.chainConfigs[consumerChain].ChainId), + string(tr.testConfig.chainConfigs[consumerChain].ChainId), - `--node`, tr.getQueryNode(providerChain), + `--node`, tr.target.GetQueryNode(providerChain), `-o`, `json`, ) @@ -549,8 +542,8 @@ func (tr *TestConfig) getConsumerGenesis(providerChain, consumerChain ChainID, t log.Fatal(err, "\n", string(bz)) } - if tr.transformGenesis || needsGenesisTransform(target.GetTargetConfig()) { - return string(tr.transformConsumerGenesis(consumerChain, bz, target)) + if tr.testConfig.transformGenesis || needsGenesisTransform(tr.testConfig) { + return string(tr.transformConsumerGenesis(consumerChain, bz)) } else { fmt.Println("No genesis transformation performed") } @@ -558,7 +551,7 @@ func (tr *TestConfig) getConsumerGenesis(providerChain, consumerChain ChainID, t } // needsGenesisTransform tries to identify if a genesis transformation should be performed -func needsGenesisTransform(cfg TargetConfig) bool { +func needsGenesisTransform(cfg TestConfig) bool { // no genesis transformation needed for same versions if cfg.consumerVersion == cfg.providerVersion { return false @@ -663,7 +656,7 @@ func getTransformParameter(consumerVersion string) (string, error) { } // Transform consumer genesis content from older version -func (tr *TestConfig) transformConsumerGenesis(consumerChain ChainID, genesis []byte, target ExecutionTarget) []byte { +func (tr *Chain) transformConsumerGenesis(consumerChain ChainID, genesis []byte) []byte { fmt.Println("Transforming consumer genesis") fileName := "consumer_genesis.json" @@ -677,7 +670,7 @@ func (tr *TestConfig) transformConsumerGenesis(consumerChain ChainID, genesis [] log.Panicf("Failed writing consumer genesis to file: %v", err) } - containerInstance := tr.containerConfig.InstanceName + containerInstance := tr.testConfig.containerConfig.InstanceName targetFile := fmt.Sprintf("/tmp/%s", fileName) sourceFile := file.Name() //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. @@ -689,20 +682,19 @@ func (tr *TestConfig) transformConsumerGenesis(consumerChain ChainID, genesis [] } // check if genesis transform supports --to target - bz, err := target.ExecCommand( + bz, err := tr.target.ExecCommand( "interchain-security-transformer", "genesis", "transform", "--to").CombinedOutput() if err != nil && !strings.Contains(string(bz), "unknown flag: --to") { - cfg := target.GetTargetConfig() - targetVersion, err := getTransformParameter(cfg.consumerVersion) + targetVersion, err := getTransformParameter(tr.testConfig.consumerVersion) if err != nil { log.Panic("Failed getting genesis transformation parameter: ", err) } - cmd = target.ExecCommand( + cmd = tr.target.ExecCommand( "interchain-security-transformer", "genesis", "transform", targetVersion, targetFile) } else { - cmd = target.ExecCommand( + cmd = tr.target.ExecCommand( "interchain-security-transformer", "genesis", "transform", targetFile) } @@ -721,20 +713,19 @@ type ChangeoverChainAction struct { GenesisChanges string } -func (tr TestConfig) changeoverChain( +func (tr Chain) changeoverChain( action ChangeoverChainAction, - target ExecutionTarget, verbose bool, ) { // sleep until the consumer chain genesis is ready on consumer time.Sleep(5 * time.Second) - cmd := target.ExecCommand( - tr.chainConfigs[action.ProviderChain].BinaryName, + cmd := tr.target.ExecCommand( + tr.testConfig.chainConfigs[action.ProviderChain].BinaryName, "query", "provider", "consumer-genesis", - string(tr.chainConfigs[action.SovereignChain].ChainId), + string(tr.testConfig.chainConfigs[action.SovereignChain].ChainId), - `--node`, tr.getQueryNode(action.ProviderChain), + `--node`, tr.target.GetQueryNode(action.ProviderChain), `-o`, `json`, ) @@ -748,7 +739,7 @@ func (tr TestConfig) changeoverChain( } consumerGenesis := ".app_state.ccvconsumer = " + string(bz) - consumerGenesisChanges := tr.chainConfigs[action.SovereignChain].GenesisChanges + consumerGenesisChanges := tr.testConfig.chainConfigs[action.SovereignChain].GenesisChanges if consumerGenesisChanges != "" { consumerGenesis = consumerGenesis + " | " + consumerGenesisChanges + " | " + action.GenesisChanges } @@ -756,15 +747,14 @@ func (tr TestConfig) changeoverChain( tr.startChangeover(ChangeoverChainAction{ Validators: action.Validators, GenesisChanges: consumerGenesis, - }, target, verbose) + }, verbose) } -func (tr TestConfig) startChangeover( +func (tr Chain) startChangeover( action ChangeoverChainAction, - target ExecutionTarget, verbose bool, ) { - chainConfig := tr.chainConfigs[ChainID("sover")] + chainConfig := tr.testConfig.chainConfigs[ChainID("sover")] type jsonValAttrs struct { Mnemonic string `json:"mnemonic"` Allocation string `json:"allocation"` @@ -782,18 +772,18 @@ func (tr TestConfig) startChangeover( var validators []jsonValAttrs for _, val := range action.Validators { validators = append(validators, jsonValAttrs{ - Mnemonic: tr.validatorConfigs[val.Id].Mnemonic, - NodeKey: tr.validatorConfigs[val.Id].NodeKey, + Mnemonic: tr.testConfig.validatorConfigs[val.Id].Mnemonic, + NodeKey: tr.testConfig.validatorConfigs[val.Id].NodeKey, ValId: fmt.Sprint(val.Id), - PrivValidatorKey: tr.validatorConfigs[val.Id].PrivValidatorKey, + PrivValidatorKey: tr.testConfig.validatorConfigs[val.Id].PrivValidatorKey, Allocation: fmt.Sprint(val.Allocation) + "stake", Stake: fmt.Sprint(val.Stake) + "stake", - IpSuffix: tr.validatorConfigs[val.Id].IpSuffix, + IpSuffix: tr.testConfig.validatorConfigs[val.Id].IpSuffix, - ConsumerMnemonic: tr.validatorConfigs[val.Id].ConsumerMnemonic, - ConsumerPrivValidatorKey: tr.validatorConfigs[val.Id].ConsumerPrivValidatorKey, + ConsumerMnemonic: tr.testConfig.validatorConfigs[val.Id].ConsumerMnemonic, + ConsumerPrivValidatorKey: tr.testConfig.validatorConfigs[val.Id].ConsumerPrivValidatorKey, // if true node will be started with consumer key for each consumer chain - StartWithConsumerKey: tr.validatorConfigs[val.Id].UseConsumerKey, + StartWithConsumerKey: tr.testConfig.validatorConfigs[val.Id].UseConsumerKey, }) } @@ -811,12 +801,12 @@ func (tr TestConfig) startChangeover( } isConsumer := true - changeoverScript := target.GetTestScriptPath(isConsumer, "start-changeover.sh") - cmd := target.ExecCommand( + changeoverScript := tr.target.GetTestScriptPath(isConsumer, "start-changeover.sh") + cmd := tr.target.ExecCommand( "/bin/bash", changeoverScript, chainConfig.UpgradeBinary, string(vals), "sover", chainConfig.IpPrefix, genesisChanges, - tr.tendermintConfigOverride, + tr.testConfig.tendermintConfigOverride, ) cmdReader, err := cmd.StdoutPipe() @@ -873,34 +863,32 @@ const gorelayerChainConfigTemplate = ` } }` -func (tr TestConfig) addChainToRelayer( +func (tr Chain) addChainToRelayer( action AddChainToRelayerAction, - target ExecutionTarget, verbose bool, ) { - if !tr.useGorelayer { - tr.addChainToHermes(action, target, verbose) + if !tr.testConfig.useGorelayer { + tr.addChainToHermes(action, verbose) } else { - tr.addChainToGorelayer(action, target, verbose) + tr.addChainToGorelayer(action, verbose) } } -func (tr TestConfig) addChainToGorelayer( +func (tr Chain) addChainToGorelayer( action AddChainToRelayerAction, - target ExecutionTarget, verbose bool, ) { - queryNodeIP := tr.getQueryNodeIP(action.Chain) - ChainId := tr.chainConfigs[action.Chain].ChainId + queryNodeIP := tr.target.GetQueryNodeIP(action.Chain) + ChainId := tr.testConfig.chainConfigs[action.Chain].ChainId rpcAddr := "http://" + queryNodeIP + ":26658" chainConfig := fmt.Sprintf(gorelayerChainConfigTemplate, ChainId, rpcAddr, - tr.chainConfigs[action.Chain].AccountPrefix, + tr.testConfig.chainConfigs[action.Chain].AccountPrefix, ) - bz, err := target.ExecCommand( + bz, err := tr.target.ExecCommand( "rly", "config", "init").CombinedOutput() if err != nil && !strings.Contains(string(bz), "config already exists") { log.Fatal(err, "\n", string(bz)) @@ -909,25 +897,25 @@ func (tr TestConfig) addChainToGorelayer( chainConfigFileName := fmt.Sprintf("/root/%s_config.json", ChainId) bashCommand := fmt.Sprintf(`echo '%s' >> %s`, chainConfig, chainConfigFileName) - bz, err = target.ExecCommand("bash", "-c", + bz, err = tr.target.ExecCommand("bash", "-c", bashCommand).CombinedOutput() if err != nil { log.Fatal(err, "\n", string(bz)) } - addChainCommand := target.ExecCommand("rly", "chains", "add", "--file", chainConfigFileName, string(ChainId)) - executeCommand(addChainCommand, "add chain") + addChainCommand := tr.target.ExecCommand("rly", "chains", "add", "--file", chainConfigFileName, string(ChainId)) + e2e.ExecuteCommand(addChainCommand, "add chain") - keyRestoreCommand := target.ExecCommand("rly", "keys", "restore", string(ChainId), "default", tr.validatorConfigs[action.Validator].Mnemonic) - executeCommand(keyRestoreCommand, "restore keys") + keyRestoreCommand := tr.target.ExecCommand("rly", "keys", "restore", string(ChainId), "default", tr.testConfig.validatorConfigs[action.Validator].Mnemonic) + e2e.ExecuteCommand(keyRestoreCommand, "restore keys") } -func (tr TestConfig) addChainToHermes( +func (tr Chain) addChainToHermes( action AddChainToRelayerAction, - target ExecutionTarget, verbose bool, ) { - bz, err := target.ExecCommand("bash", "-c", "hermes", "version").CombinedOutput() + + bz, err := tr.target.ExecCommand("bash", "-c", "hermes", "version").CombinedOutput() if err != nil { log.Fatal(err, "\n error getting hermes version", string(bz)) } @@ -938,34 +926,34 @@ func (tr TestConfig) addChainToHermes( } hermesVersion := match[1] - queryNodeIP := tr.getQueryNodeIP(action.Chain) - hermesConfig := GetHermesConfig(hermesVersion, queryNodeIP, tr.chainConfigs[action.Chain], action.IsConsumer) + queryNodeIP := tr.target.GetQueryNodeIP(action.Chain) + hermesConfig := GetHermesConfig(hermesVersion, queryNodeIP, tr.testConfig.chainConfigs[action.Chain], action.IsConsumer) bashCommand := fmt.Sprintf(`echo '%s' >> %s`, hermesConfig, "/root/.hermes/config.toml") - bz, err = target.ExecCommand("bash", "-c", bashCommand).CombinedOutput() + bz, err = tr.target.ExecCommand("bash", "-c", bashCommand).CombinedOutput() if err != nil { log.Fatal(err, "\n", string(bz)) } // Save mnemonic to file within container var mnemonic string - if tr.validatorConfigs[action.Validator].UseConsumerKey && action.IsConsumer { - mnemonic = tr.validatorConfigs[action.Validator].ConsumerMnemonic + if tr.testConfig.validatorConfigs[action.Validator].UseConsumerKey && action.IsConsumer { + mnemonic = tr.testConfig.validatorConfigs[action.Validator].ConsumerMnemonic } else { - mnemonic = tr.validatorConfigs[action.Validator].Mnemonic + mnemonic = tr.testConfig.validatorConfigs[action.Validator].Mnemonic } saveMnemonicCommand := fmt.Sprintf(`echo '%s' > %s`, mnemonic, "/root/.hermes/mnemonic.txt") fmt.Println("Add to hermes", action.Validator) - bz, err = target.ExecCommand("bash", "-c", saveMnemonicCommand).CombinedOutput() + bz, err = tr.target.ExecCommand("bash", "-c", saveMnemonicCommand).CombinedOutput() if err != nil { log.Fatal(err, "\n", string(bz)) } - bz, err = target.ExecCommand("hermes", + bz, err = tr.target.ExecCommand("hermes", "keys", "add", - "--chain", string(tr.chainConfigs[action.Chain].ChainId), + "--chain", string(tr.testConfig.chainConfigs[action.Chain].ChainId), "--mnemonic-file", "/root/.hermes/mnemonic.txt", ).CombinedOutput() if err != nil { @@ -1000,21 +988,19 @@ type AddIbcConnectionAction struct { ClientB uint } -func (tr TestConfig) addIbcConnection( +func (tr Chain) addIbcConnection( action AddIbcConnectionAction, - target ExecutionTarget, verbose bool, ) { - if !tr.useGorelayer { - tr.addIbcConnectionHermes(action, target, verbose) + if !tr.testConfig.useGorelayer { + tr.addIbcConnectionHermes(action, verbose) } else { - tr.addIbcConnectionGorelayer(action, target, verbose) + tr.addIbcConnectionGorelayer(action, verbose) } } -func (tr TestConfig) addIbcConnectionGorelayer( +func (tr Chain) addIbcConnectionGorelayer( action AddIbcConnectionAction, - target ExecutionTarget, verbose bool, ) { pathName := tr.GetPathNameForGorelayer(action.ChainA, action.ChainB) @@ -1026,32 +1012,32 @@ func (tr TestConfig) addIbcConnectionGorelayer( bashCommand := fmt.Sprintf(`echo '%s' >> %s`, pathConfig, pathConfigFileName) //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - pathConfigCommand := target.ExecCommand("bash", "-c", bashCommand) - executeCommand(pathConfigCommand, "add path config") + pathConfigCommand := tr.target.ExecCommand("bash", "-c", bashCommand) + e2e.ExecuteCommand(pathConfigCommand, "add path config") //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - newPathCommand := target.ExecCommand("rly", + newPathCommand := tr.target.ExecCommand("rly", "paths", "add", - string(tr.chainConfigs[action.ChainA].ChainId), - string(tr.chainConfigs[action.ChainB].ChainId), + string(tr.testConfig.chainConfigs[action.ChainA].ChainId), + string(tr.testConfig.chainConfigs[action.ChainB].ChainId), pathName, "--file", pathConfigFileName, ) - executeCommand(newPathCommand, "new path") + e2e.ExecuteCommand(newPathCommand, "new path") //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - newClientsCommand := target.ExecCommand("rly", "transact", "clients", pathName) + newClientsCommand := tr.target.ExecCommand("rly", "transact", "clients", pathName) - executeCommand(newClientsCommand, "new clients") + e2e.ExecuteCommand(newClientsCommand, "new clients") tr.waitBlocks(action.ChainA, 1, 10*time.Second) tr.waitBlocks(action.ChainB, 1, 10*time.Second) //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - newConnectionCommand := target.ExecCommand("rly", "transact", "connection", pathName) + newConnectionCommand := tr.target.ExecCommand("rly", "transact", "connection", pathName) - executeCommand(newConnectionCommand, "new connection") + e2e.ExecuteCommand(newConnectionCommand, "new connection") tr.waitBlocks(action.ChainA, 1, 10*time.Second) tr.waitBlocks(action.ChainB, 1, 10*time.Second) @@ -1065,15 +1051,14 @@ type CreateIbcClientsAction struct { // if clients are not provided hermes will first // create new clients and then a new connection // otherwise, it would use client provided as CLI argument (-a-client) -func (tr TestConfig) createIbcClientsHermes( +func (tr Chain) createIbcClientsHermes( action CreateIbcClientsAction, - target ExecutionTarget, verbose bool, ) { - cmd := target.ExecCommand("hermes", + cmd := tr.target.ExecCommand("hermes", "create", "connection", - "--a-chain", string(tr.chainConfigs[action.ChainA].ChainId), - "--b-chain", string(tr.chainConfigs[action.ChainB].ChainId), + "--a-chain", string(tr.testConfig.chainConfigs[action.ChainA].ChainId), + "--b-chain", string(tr.testConfig.chainConfigs[action.ChainB].ChainId), ) cmdReader, err := cmd.StdoutPipe() @@ -1102,14 +1087,13 @@ func (tr TestConfig) createIbcClientsHermes( } } -func (tr TestConfig) addIbcConnectionHermes( +func (tr Chain) addIbcConnectionHermes( action AddIbcConnectionAction, - target ExecutionTarget, verbose bool, ) { - cmd := target.ExecCommand("hermes", + cmd := tr.target.ExecCommand("hermes", "create", "connection", - "--a-chain", string(tr.chainConfigs[action.ChainA].ChainId), + "--a-chain", string(tr.testConfig.chainConfigs[action.ChainA].ChainId), "--a-client", "07-tendermint-"+fmt.Sprint(action.ClientA), "--b-client", "07-tendermint-"+fmt.Sprint(action.ClientB), ) @@ -1152,25 +1136,23 @@ type AddIbcChannelAction struct { type StartRelayerAction struct{} -func (tr TestConfig) startRelayer( +func (tr Chain) startRelayer( action StartRelayerAction, - target ExecutionTarget, verbose bool, ) { - if tr.useGorelayer { - tr.startGorelayer(action, target, verbose) + if tr.testConfig.useGorelayer { + tr.startGorelayer(action, verbose) } else { - tr.startHermes(action, target, verbose) + tr.startHermes(action, verbose) } } -func (tr TestConfig) startGorelayer( +func (tr Chain) startGorelayer( action StartRelayerAction, - target ExecutionTarget, verbose bool, ) { // gorelayer start is running in detached mode - cmd := target.ExecDetachedCommand("rly", "start") + cmd := tr.target.ExecDetachedCommand("rly", "start") if err := cmd.Start(); err != nil { log.Fatal(err) @@ -1181,13 +1163,12 @@ func (tr TestConfig) startGorelayer( } } -func (tr TestConfig) startHermes( +func (tr Chain) startHermes( action StartRelayerAction, - target ExecutionTarget, verbose bool, ) { // hermes start is running in detached mode - cmd := target.ExecDetachedCommand("hermes", "start") + cmd := tr.target.ExecDetachedCommand("hermes", "start") if err := cmd.Start(); err != nil { log.Fatal(err) @@ -1198,51 +1179,48 @@ func (tr TestConfig) startHermes( } } -func (tr TestConfig) addIbcChannel( +func (tr Chain) addIbcChannel( action AddIbcChannelAction, - target ExecutionTarget, verbose bool, ) { - if tr.useGorelayer { - tr.addIbcChannelGorelayer(action, target, verbose) + if tr.testConfig.useGorelayer { + tr.addIbcChannelGorelayer(action, verbose) } else { - tr.addIbcChannelHermes(action, target, verbose) + tr.addIbcChannelHermes(action, verbose) } } -func (tr TestConfig) addIbcChannelGorelayer( +func (tr Chain) addIbcChannelGorelayer( action AddIbcChannelAction, - target ExecutionTarget, verbose bool, ) { pathName := tr.GetPathNameForGorelayer(action.ChainA, action.ChainB) - cmd := target.ExecCommand("rly", + cmd := tr.target.ExecCommand("rly", "transact", "channel", pathName, "--src-port", action.PortA, "--dst-port", action.PortB, - "--version", tr.containerConfig.CcvVersion, + "--version", tr.testConfig.containerConfig.CcvVersion, "--order", action.Order, "--debug", ) - executeCommand(cmd, "addChannel") + e2e.ExecuteCommand(cmd, "addChannel") } -func (tr TestConfig) addIbcChannelHermes( +func (tr Chain) addIbcChannelHermes( action AddIbcChannelAction, - target ExecutionTarget, verbose bool, ) { // if version is not specified, use the default version when creating ccv connections // otherwise, use the provided version schema (usually it is ICS20-1 for IBC transfer) chanVersion := action.Version if chanVersion == "" { - chanVersion = tr.containerConfig.CcvVersion + chanVersion = tr.testConfig.containerConfig.CcvVersion } - cmd := target.ExecCommand("hermes", + cmd := tr.target.ExecCommand("hermes", "create", "channel", - "--a-chain", string(tr.chainConfigs[action.ChainA].ChainId), + "--a-chain", string(tr.testConfig.chainConfigs[action.ChainA].ChainId), "--a-connection", "connection-"+fmt.Sprint(action.ConnectionA), "--a-port", action.PortA, "--b-port", action.PortB, @@ -1291,30 +1269,29 @@ type TransferChannelCompleteAction struct { ChannelB uint } -func (tr TestConfig) transferChannelComplete( +func (tr Chain) transferChannelComplete( action TransferChannelCompleteAction, - target ExecutionTarget, verbose bool, ) { - if tr.useGorelayer { + if tr.testConfig.useGorelayer { log.Fatal("transferChannelComplete is not implemented for rly") } - chanOpenTryCmd := target.ExecCommand("hermes", + chanOpenTryCmd := tr.target.ExecCommand("hermes", "tx", "chan-open-try", - "--dst-chain", string(tr.chainConfigs[action.ChainB].ChainId), - "--src-chain", string(tr.chainConfigs[action.ChainA].ChainId), + "--dst-chain", string(tr.testConfig.chainConfigs[action.ChainB].ChainId), + "--src-chain", string(tr.testConfig.chainConfigs[action.ChainA].ChainId), "--dst-connection", "connection-"+fmt.Sprint(action.ConnectionA), "--dst-port", action.PortB, "--src-port", action.PortA, "--src-channel", "channel-"+fmt.Sprint(action.ChannelA), ) - executeCommand(chanOpenTryCmd, "transferChanOpenTry") + e2e.ExecuteCommand(chanOpenTryCmd, "transferChanOpenTry") - chanOpenAckCmd := target.ExecCommand("hermes", + chanOpenAckCmd := tr.target.ExecCommand("hermes", "tx", "chan-open-ack", - "--dst-chain", string(tr.chainConfigs[action.ChainA].ChainId), - "--src-chain", string(tr.chainConfigs[action.ChainB].ChainId), + "--dst-chain", string(tr.testConfig.chainConfigs[action.ChainA].ChainId), + "--src-chain", string(tr.testConfig.chainConfigs[action.ChainB].ChainId), "--dst-connection", "connection-"+fmt.Sprint(action.ConnectionA), "--dst-port", action.PortA, "--src-port", action.PortB, @@ -1322,52 +1299,19 @@ func (tr TestConfig) transferChannelComplete( "--src-channel", "channel-"+fmt.Sprint(action.ChannelB), ) - executeCommand(chanOpenAckCmd, "transferChanOpenAck") + e2e.ExecuteCommand(chanOpenAckCmd, "transferChanOpenAck") - chanOpenConfirmCmd := target.ExecCommand("hermes", + chanOpenConfirmCmd := tr.target.ExecCommand("hermes", "tx", "chan-open-confirm", - "--dst-chain", string(tr.chainConfigs[action.ChainB].ChainId), - "--src-chain", string(tr.chainConfigs[action.ChainA].ChainId), + "--dst-chain", string(tr.testConfig.chainConfigs[action.ChainB].ChainId), + "--src-chain", string(tr.testConfig.chainConfigs[action.ChainA].ChainId), "--dst-connection", "connection-"+fmt.Sprint(action.ConnectionA), "--dst-port", action.PortB, "--src-port", action.PortA, "--dst-channel", "channel-"+fmt.Sprint(action.ChannelB), "--src-channel", "channel-"+fmt.Sprint(action.ChannelA), ) - executeCommand(chanOpenConfirmCmd, "transferChanOpenConfirm") -} - -func executeCommandWithVerbosity(cmd *exec.Cmd, cmdName string, verbose bool) { - if verbose { - fmt.Println(cmdName+" cmd:", cmd.String()) - } - - cmdReader, err := cmd.StdoutPipe() - if err != nil { - log.Fatal(err) - } - cmd.Stderr = cmd.Stdout - - if err := cmd.Start(); err != nil { - log.Fatal(err) - } - - scanner := bufio.NewScanner(cmdReader) - - for scanner.Scan() { - out := scanner.Text() - if verbose { - fmt.Println(cmdName + ": " + out) - } - } - if err := scanner.Err(); err != nil { - log.Fatal(err) - } -} - -// Executes a command with verbosity specified by CLI flag -func executeCommand(cmd *exec.Cmd, cmdName string) { - executeCommandWithVerbosity(cmd, cmdName, *verbose) + e2e.ExecuteCommand(chanOpenConfirmCmd, "transferChanOpenConfirm") } type RelayPacketsAction struct { @@ -1377,21 +1321,19 @@ type RelayPacketsAction struct { Channel uint } -func (tr TestConfig) relayPackets( +func (tr Chain) relayPackets( action RelayPacketsAction, - target ExecutionTarget, verbose bool, ) { - if tr.useGorelayer { - tr.relayPacketsGorelayer(action, target, verbose) + if tr.testConfig.useGorelayer { + tr.relayPacketsGorelayer(action, verbose) } else { - tr.relayPacketsHermes(action, target, verbose) + tr.relayPacketsHermes(action, verbose) } } -func (tr TestConfig) relayPacketsGorelayer( +func (tr Chain) relayPacketsGorelayer( action RelayPacketsAction, - target ExecutionTarget, verbose bool, ) { // Because `.app_state.provider.params.blocks_per_epoch` is set to 3 in the E2E tests, we wait 3 blocks @@ -1403,7 +1345,7 @@ func (tr TestConfig) relayPacketsGorelayer( pathName := tr.GetPathNameForGorelayer(action.ChainA, action.ChainB) // rly transact relay-packets [path-name] --channel [channel-id] - cmd := target.ExecCommand("rly", "transact", "flush", + cmd := tr.target.ExecCommand("rly", "transact", "flush", pathName, "channel-"+fmt.Sprint(action.Channel), ) @@ -1419,9 +1361,8 @@ func (tr TestConfig) relayPacketsGorelayer( tr.waitBlocks(action.ChainB, 1, 30*time.Second) } -func (tr TestConfig) relayPacketsHermes( +func (tr Chain) relayPacketsHermes( action RelayPacketsAction, - target ExecutionTarget, verbose bool, ) { // Because `.app_state.provider.params.blocks_per_epoch` is set to 3 in the E2E tests, we wait 3 blocks @@ -1431,8 +1372,8 @@ func (tr TestConfig) relayPacketsHermes( tr.waitBlocks(action.ChainB, 3, 90*time.Second) // hermes clear packets ibc0 transfer channel-13 - cmd := target.ExecCommand("hermes", "clear", "packets", - "--chain", string(tr.chainConfigs[action.ChainA].ChainId), + cmd := tr.target.ExecCommand("hermes", "clear", "packets", + "--chain", string(tr.testConfig.chainConfigs[action.ChainA].ChainId), "--port", action.Port, "--channel", "channel-"+fmt.Sprint(action.Channel), ) @@ -1456,18 +1397,17 @@ type RelayRewardPacketsToProviderAction struct { Channel uint } -func (tr TestConfig) relayRewardPacketsToProvider( +func (tr Chain) relayRewardPacketsToProvider( action RelayRewardPacketsToProviderAction, - target ExecutionTarget, verbose bool, ) { - blockPerDistribution, _ := strconv.ParseUint(strings.Trim(tr.getParam(action.ConsumerChain, Param{Subspace: "ccvconsumer", Key: "BlocksPerDistributionTransmission"}), "\""), 10, 64) - currentBlock := uint64(tr.getBlockHeight(action.ConsumerChain)) + blockPerDistribution, _ := strconv.ParseUint(strings.Trim(tr.target.GetParam(action.ConsumerChain, Param{Subspace: "ccvconsumer", Key: "BlocksPerDistributionTransmission"}), "\""), 10, 64) + currentBlock := uint64(tr.target.GetBlockHeight(action.ConsumerChain)) if currentBlock <= blockPerDistribution { tr.waitBlocks(action.ConsumerChain, uint(blockPerDistribution-currentBlock+1), 60*time.Second) } - tr.relayPackets(RelayPacketsAction{ChainA: action.ConsumerChain, ChainB: action.ProviderChain, Port: action.Port, Channel: action.Channel}, target, verbose) + tr.relayPackets(RelayPacketsAction{ChainA: action.ConsumerChain, ChainB: action.ProviderChain, Port: action.Port, Channel: action.Channel}, verbose) tr.waitBlocks(action.ProviderChain, 1, 10*time.Second) } @@ -1478,12 +1418,11 @@ type DelegateTokensAction struct { Amount uint } -func (tr TestConfig) delegateTokens( +func (tr Chain) delegateTokens( action DelegateTokensAction, - target ExecutionTarget, verbose bool, ) { - toValCfg := tr.validatorConfigs[action.To] + toValCfg := tr.testConfig.validatorConfigs[action.To] validatorAddress := toValCfg.ValoperAddress if action.Chain != ChainID("provi") { // use binary with Bech32Prefix set to ConsumerAccountPrefix @@ -1495,14 +1434,14 @@ func (tr TestConfig) delegateTokens( } } - cmd := target.ExecCommand(tr.chainConfigs[action.Chain].BinaryName, + cmd := tr.target.ExecCommand(tr.testConfig.chainConfigs[action.Chain].BinaryName, "tx", "staking", "delegate", validatorAddress, fmt.Sprint(action.Amount)+`stake`, `--from`, `validator`+fmt.Sprint(action.From), - `--chain-id`, string(tr.chainConfigs[action.Chain].ChainId), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, action.From), `--node`, tr.getValidatorNode(action.Chain, action.From), `--keyring-backend`, `test`, @@ -1529,12 +1468,11 @@ type UnbondTokensAction struct { Amount uint } -func (tr TestConfig) unbondTokens( +func (tr Chain) unbondTokens( action UnbondTokensAction, - target ExecutionTarget, verbose bool, ) { - unbondFromValCfg := tr.validatorConfigs[action.UnbondFrom] + unbondFromValCfg := tr.testConfig.validatorConfigs[action.UnbondFrom] validatorAddress := unbondFromValCfg.ValoperAddress if action.Chain != ChainID("provi") { // use binary with Bech32Prefix set to ConsumerAccountPrefix @@ -1546,14 +1484,14 @@ func (tr TestConfig) unbondTokens( } } - cmd := target.ExecCommand(tr.chainConfigs[action.Chain].BinaryName, + cmd := tr.target.ExecCommand(tr.testConfig.chainConfigs[action.Chain].BinaryName, "tx", "staking", "unbond", validatorAddress, fmt.Sprint(action.Amount)+`stake`, `--from`, `validator`+fmt.Sprint(action.Sender), - `--chain-id`, string(tr.chainConfigs[action.Chain].ChainId), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, action.Sender), `--node`, tr.getValidatorNode(action.Chain, action.Sender), `--gas`, "900000", @@ -1581,13 +1519,12 @@ type CancelUnbondTokensAction struct { Amount uint } -func (tr TestConfig) cancelUnbondTokens( +func (tr Chain) cancelUnbondTokens( action CancelUnbondTokensAction, - target ExecutionTarget, verbose bool, ) { - valCfg := tr.validatorConfigs[action.Validator] - delCfg := tr.validatorConfigs[action.Delegator] + valCfg := tr.testConfig.validatorConfigs[action.Validator] + delCfg := tr.testConfig.validatorConfigs[action.Delegator] validatorAddress := valCfg.ValoperAddress delegatorAddress := delCfg.DelAddress if action.Chain != ChainID("provi") { @@ -1607,7 +1544,7 @@ func (tr TestConfig) cancelUnbondTokens( } // get creation-height from state - cmd := target.ExecCommand(tr.chainConfigs[action.Chain].BinaryName, + cmd := tr.target.ExecCommand(tr.testConfig.chainConfigs[action.Chain].BinaryName, "q", "staking", "unbonding-delegation", delegatorAddress, validatorAddress, @@ -1628,13 +1565,13 @@ func (tr TestConfig) cancelUnbondTokens( log.Fatal("invalid creation height") } - cmd = target.ExecCommand(tr.chainConfigs[action.Chain].BinaryName, + cmd = tr.target.ExecCommand(tr.testConfig.chainConfigs[action.Chain].BinaryName, "tx", "staking", "cancel-unbond", validatorAddress, fmt.Sprint(action.Amount)+`stake`, fmt.Sprint(creationHeight), `--from`, `validator`+fmt.Sprint(action.Delegator), - `--chain-id`, string(tr.chainConfigs[action.Chain].ChainId), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, action.Delegator), `--node`, tr.getValidatorNode(action.Chain, action.Delegator), `--gas`, "900000", @@ -1664,9 +1601,9 @@ type RedelegateTokensAction struct { Amount uint } -func (tr TestConfig) redelegateTokens(action RedelegateTokensAction, target ExecutionTarget, verbose bool) { - srcCfg := tr.validatorConfigs[action.Src] - dstCfg := tr.validatorConfigs[action.Dst] +func (tr Chain) redelegateTokens(action RedelegateTokensAction, verbose bool) { + srcCfg := tr.testConfig.validatorConfigs[action.Src] + dstCfg := tr.testConfig.validatorConfigs[action.Dst] redelegateSrc := srcCfg.ValoperAddress redelegateDst := dstCfg.ValoperAddress if action.Chain != ChainID("provi") { @@ -1685,15 +1622,15 @@ func (tr TestConfig) redelegateTokens(action RedelegateTokensAction, target Exec } } - cmd := target.ExecCommand( - tr.chainConfigs[action.Chain].BinaryName, + cmd := tr.target.ExecCommand( + tr.testConfig.chainConfigs[action.Chain].BinaryName, "tx", "staking", "redelegate", redelegateSrc, redelegateDst, fmt.Sprint(action.Amount)+`stake`, `--from`, `validator`+fmt.Sprint(action.TxSender), - `--chain-id`, string(tr.chainConfigs[action.Chain].ChainId), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, action.TxSender), `--node`, tr.getValidatorNode(action.Chain, action.TxSender), // Need to manually set gas limit past default (200000), since redelegate has a lot of operations @@ -1723,7 +1660,7 @@ type DowntimeSlashAction struct { // takes a string representation of the private key like // `{"address":"DF090A4880B54CD57B2A79E64D9E969BD7514B09","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ujY14AgopV907IYgPAk/5x8c9267S4fQf89nyeCPTes="},"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"TRJgf7lkTjs/sj43pyweEOanyV7H7fhnVivOi0A4yjW6NjXgCCilX3TshiA8CT/nHxz3brtLh9B/z2fJ4I9N6w=="}}` // and returns the value of the "address" field -func (tr TestConfig) getValidatorKeyAddressFromString(keystring string) string { +func (tr Chain) getValidatorKeyAddressFromString(keystring string) string { var key struct { Address string `json:"address"` } @@ -1734,17 +1671,17 @@ func (tr TestConfig) getValidatorKeyAddressFromString(keystring string) string { return key.Address } -func (tr TestConfig) invokeDowntimeSlash(action DowntimeSlashAction, target ExecutionTarget, verbose bool) { +func (tr Chain) invokeDowntimeSlash(action DowntimeSlashAction, verbose bool) { // Bring validator down - tr.setValidatorDowntime(action.Chain, action.Validator, true, target, verbose) + tr.setValidatorDowntime(action.Chain, action.Validator, true, verbose) // Wait appropriate amount of blocks for validator to be slashed tr.waitBlocks(action.Chain, 11, 3*time.Minute) // Bring validator back up - tr.setValidatorDowntime(action.Chain, action.Validator, false, target, verbose) + tr.setValidatorDowntime(action.Chain, action.Validator, false, verbose) } // Sets validator downtime by setting the virtual ethernet interface of a node to "up" or "down" -func (tr TestConfig) setValidatorDowntime(chain ChainID, validator ValidatorID, down bool, target ExecutionTarget, verbose bool) { +func (tr Chain) setValidatorDowntime(chain ChainID, validator ValidatorID, down bool, verbose bool) { var lastArg string if down { lastArg = "down" @@ -1752,20 +1689,20 @@ func (tr TestConfig) setValidatorDowntime(chain ChainID, validator ValidatorID, lastArg = "up" } - if tr.useCometmock { + if tr.testConfig.useCometmock { // send set_signing_status either to down or up for validator validatorPrivateKeyAddress := tr.GetValidatorPrivateKeyAddress(chain, validator) method := "set_signing_status" params := fmt.Sprintf(`{"private_key_address":"%s","status":"%s"}`, validatorPrivateKeyAddress, lastArg) - address := tr.getQueryNodeRPCAddress(chain) + address := tr.target.GetQueryNodeRPCAddress(chain) tr.curlJsonRPCRequest(method, params, address) tr.waitBlocks(chain, 1, 10*time.Second) return } - cmd := target.ExecCommand( + cmd := tr.target.ExecCommand( "ip", "link", "set", @@ -1783,16 +1720,16 @@ func (tr TestConfig) setValidatorDowntime(chain ChainID, validator ValidatorID, } } -func (tr TestConfig) GetValidatorPrivateKeyAddress(chain ChainID, validator ValidatorID) string { +func (tr Chain) GetValidatorPrivateKeyAddress(chain ChainID, validator ValidatorID) string { var validatorPrivateKeyAddress string if chain == ChainID("provi") { - validatorPrivateKeyAddress = tr.getValidatorKeyAddressFromString(tr.validatorConfigs[validator].PrivValidatorKey) + validatorPrivateKeyAddress = tr.getValidatorKeyAddressFromString(tr.testConfig.validatorConfigs[validator].PrivValidatorKey) } else { var valAddressString string - if tr.validatorConfigs[validator].UseConsumerKey { - valAddressString = tr.validatorConfigs[validator].ConsumerPrivValidatorKey + if tr.testConfig.validatorConfigs[validator].UseConsumerKey { + valAddressString = tr.testConfig.validatorConfigs[validator].ConsumerPrivValidatorKey } else { - valAddressString = tr.validatorConfigs[validator].PrivValidatorKey + valAddressString = tr.testConfig.validatorConfigs[validator].PrivValidatorKey } validatorPrivateKeyAddress = tr.getValidatorKeyAddressFromString(valAddressString) } @@ -1805,16 +1742,16 @@ type UnjailValidatorAction struct { } // Sends an unjail transaction to the provider chain -func (tr TestConfig) unjailValidator(action UnjailValidatorAction, target ExecutionTarget, verbose bool) { +func (tr Chain) unjailValidator(action UnjailValidatorAction, verbose bool) { // wait until downtime_jail_duration has elapsed, to make sure the validator can be unjailed tr.WaitTime(61 * time.Second) - cmd := target.ExecCommand( - tr.chainConfigs[action.Provider].BinaryName, + cmd := tr.target.ExecCommand( + tr.testConfig.chainConfigs[action.Provider].BinaryName, "tx", "slashing", "unjail", // Validator is sender here `--from`, `validator`+fmt.Sprint(action.Validator), - `--chain-id`, string(tr.chainConfigs[action.Provider].ChainId), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Provider].ChainId), `--home`, tr.getValidatorHome(action.Provider, action.Validator), `--node`, tr.getValidatorNode(action.Provider, action.Validator), `--gas`, "900000", @@ -1843,9 +1780,8 @@ type RegisterRepresentativeAction struct { Stakes []uint } -func (tr TestConfig) registerRepresentative( +func (tr Chain) registerRepresentative( action RegisterRepresentativeAction, - target ExecutionTarget, verbose bool, ) { fileTempl := `{ @@ -1868,7 +1804,7 @@ func (tr TestConfig) registerRepresentative( go func(val ValidatorID, stake uint) { defer wg.Done() - pubKeycmd := target.ExecCommand(tr.chainConfigs[action.Chain].BinaryName, + pubKeycmd := tr.target.ExecCommand(tr.testConfig.chainConfigs[action.Chain].BinaryName, "tendermint", "show-validator", `--home`, tr.getValidatorHome(action.Chain, val), ) @@ -1890,7 +1826,7 @@ func (tr TestConfig) registerRepresentative( log.Fatalf("Failed writing consumer genesis to file: %v", err) } - containerInstance := tr.containerConfig.InstanceName + containerInstance := tr.testConfig.containerConfig.InstanceName targetFile := fmt.Sprintf("/tmp/%s", fileName) sourceFile := file.Name() //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. @@ -1901,11 +1837,11 @@ func (tr TestConfig) registerRepresentative( log.Fatal(err, "\n", string(writeResult)) } - cmd := target.ExecCommand(tr.chainConfigs[action.Chain].BinaryName, + cmd := tr.target.ExecCommand(tr.testConfig.chainConfigs[action.Chain].BinaryName, "tx", "staking", "create-validator", targetFile, `--from`, `validator`+fmt.Sprint(val), - `--chain-id`, string(tr.chainConfigs[action.Chain].ChainId), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, val), `--node`, tr.getValidatorNode(action.Chain, val), `--keyring-backend`, `test`, @@ -1936,8 +1872,8 @@ type SubmitChangeRewardDenomsProposalAction struct { From ValidatorID } -func (tr TestConfig) submitChangeRewardDenomsProposal(action SubmitChangeRewardDenomsProposalAction, target ExecutionTarget, verbose bool) { - providerChain := tr.chainConfigs[ChainID("provi")] +func (tr Chain) submitChangeRewardDenomsProposal(action SubmitChangeRewardDenomsProposalAction, verbose bool) { + providerChain := tr.testConfig.chainConfigs[ChainID("provi")] prop := client.ChangeRewardDenomsProposalJSON{ Summary: "Change reward denoms", @@ -1960,14 +1896,14 @@ func (tr TestConfig) submitChangeRewardDenomsProposal(action SubmitChangeRewardD log.Fatal("prop json contains single quote") } - bz, err = target.ExecCommand( + bz, err = tr.target.ExecCommand( "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/change-reward-denoms-proposal.json")).CombinedOutput() if err != nil { log.Fatal(err, "\n", string(bz)) } // CHANGE REWARDS DENOM PROPOSAL - bz, err = target.ExecCommand(providerChain.BinaryName, + bz, err = tr.target.ExecCommand(providerChain.BinaryName, "tx", "gov", "submit-legacy-proposal", "change-reward-denoms", "/change-reward-denoms-proposal.json", `--from`, `validator`+fmt.Sprint(action.From), `--chain-id`, string(providerChain.ChainId), @@ -2001,15 +1937,14 @@ type DoublesignSlashAction struct { Chain ChainID } -func (tr TestConfig) invokeDoublesignSlash( +func (tr Chain) invokeDoublesignSlash( action DoublesignSlashAction, - target ExecutionTarget, verbose bool, ) { - if !tr.useCometmock { - chainConfig := tr.chainConfigs[action.Chain] - doubleSignScript := target.GetTestScriptPath(false, "cause-doublesign.sh") - bz, err := target.ExecCommand("/bin/bash", + if !tr.testConfig.useCometmock { + chainConfig := tr.testConfig.chainConfigs[action.Chain] + doubleSignScript := tr.target.GetTestScriptPath(false, "cause-doublesign.sh") + bz, err := tr.target.ExecCommand("/bin/bash", doubleSignScript, chainConfig.BinaryName, string(action.Validator), string(chainConfig.ChainId), chainConfig.IpPrefix).CombinedOutput() if err != nil { @@ -2022,7 +1957,7 @@ func (tr TestConfig) invokeDoublesignSlash( method := "cause_double_sign" params := fmt.Sprintf(`{"private_key_address":"%s"}`, validatorPrivateKeyAddress) - address := tr.getQueryNodeRPCAddress(action.Chain) + address := tr.target.GetQueryNodeRPCAddress(action.Chain) tr.curlJsonRPCRequest(method, params, address) tr.waitBlocks(action.Chain, 1, 10*time.Second) @@ -2039,7 +1974,7 @@ type LightClientEquivocationAttackAction struct { Chain ChainID } -func (tr TestConfig) lightClientEquivocationAttack( +func (tr Chain) lightClientEquivocationAttack( action LightClientEquivocationAttackAction, verbose bool, ) { @@ -2055,7 +1990,7 @@ type LightClientAmnesiaAttackAction struct { Chain ChainID } -func (tr TestConfig) lightClientAmnesiaAttack( +func (tr Chain) lightClientAmnesiaAttack( action LightClientAmnesiaAttackAction, verbose bool, ) { @@ -2071,7 +2006,7 @@ type LightClientLunaticAttackAction struct { Chain ChainID } -func (tr TestConfig) lightClientLunaticAttack( +func (tr Chain) lightClientLunaticAttack( action LightClientLunaticAttackAction, verbose bool, ) { @@ -2086,12 +2021,12 @@ const ( LightClientLunaticAttack LightClientAttackType = "Lunatic" ) -func (tr TestConfig) lightClientAttack( +func (tr Chain) lightClientAttack( validator ValidatorID, chain ChainID, attackType LightClientAttackType, ) { - if !tr.useCometmock { + if !tr.testConfig.useCometmock { log.Fatal("light client attack is only supported with CometMock") } validatorPrivateKeyAddress := tr.GetValidatorPrivateKeyAddress(chain, validator) @@ -2099,7 +2034,7 @@ func (tr TestConfig) lightClientAttack( method := "cause_light_client_attack" params := fmt.Sprintf(`{"private_key_address":"%s", "misbehaviour_type": "%s"}`, validatorPrivateKeyAddress, attackType) - address := tr.getQueryNodeRPCAddress(chain) + address := tr.target.GetQueryNodeRPCAddress(chain) tr.curlJsonRPCRequest(method, params, address) tr.waitBlocks(chain, 1, 10*time.Second) @@ -2116,28 +2051,28 @@ type AssignConsumerPubKeyAction struct { ExpectedError string } -func (tr TestConfig) assignConsumerPubKey(action AssignConsumerPubKeyAction, target ExecutionTarget, verbose bool) { - valCfg := tr.validatorConfigs[action.Validator] +func (tr Chain) assignConsumerPubKey(action AssignConsumerPubKeyAction, verbose bool) { + valCfg := tr.testConfig.validatorConfigs[action.Validator] // Note: to get error response reported back from this command '--gas auto' needs to be set. gas := "auto" // Unfortunately, --gas auto does not work with CometMock. so when using CometMock, just use --gas 9000000 then - if tr.useCometmock { + if tr.testConfig.useCometmock { gas = "9000000" } assignKey := fmt.Sprintf( `%s tx provider assign-consensus-key %s '%s' --from validator%s --chain-id %s --home %s --node %s --gas %s --keyring-backend test -y -o json`, - tr.chainConfigs[ChainID("provi")].BinaryName, - string(tr.chainConfigs[action.Chain].ChainId), + tr.testConfig.chainConfigs[ChainID("provi")].BinaryName, + string(tr.testConfig.chainConfigs[action.Chain].ChainId), action.ConsumerPubkey, action.Validator, - tr.chainConfigs[ChainID("provi")].ChainId, + tr.testConfig.chainConfigs[ChainID("provi")].ChainId, tr.getValidatorHome(ChainID("provi"), action.Validator), tr.getValidatorNode(ChainID("provi"), action.Validator), gas, ) - cmd := target.ExecCommand( + cmd := tr.target.ExecCommand( "/bin/bash", "-c", assignKey, ) @@ -2151,7 +2086,7 @@ func (tr TestConfig) assignConsumerPubKey(action AssignConsumerPubKeyAction, tar log.Fatalf("unexpected error during key assignment - output: %s, err: %s", string(bz), err) } - if action.ExpectError && !tr.useCometmock { // error report only works with --gas auto, which does not work with CometMock, so ignore + if action.ExpectError && !tr.testConfig.useCometmock { // error report only works with --gas auto, which does not work with CometMock, so ignore if err == nil || !strings.Contains(string(bz), action.ExpectedError) { log.Fatalf("expected error not raised: expected: '%s', got '%s'", action.ExpectedError, (bz)) } @@ -2164,12 +2099,12 @@ func (tr TestConfig) assignConsumerPubKey(action AssignConsumerPubKeyAction, tar // node was started with provider key // we swap the nodes's keys for consumer keys and restart it if action.ReconfigureNode { - isConsumer := tr.chainConfigs[action.Chain].BinaryName != "interchain-security-pd" - reconfigureScript := target.GetTestScriptPath(isConsumer, "reconfigure-node.sh") - configureNodeCmd := target.ExecCommand("/bin/bash", - reconfigureScript, tr.chainConfigs[action.Chain].BinaryName, + isConsumer := tr.testConfig.chainConfigs[action.Chain].BinaryName != "interchain-security-pd" + reconfigureScript := tr.target.GetTestScriptPath(isConsumer, "reconfigure-node.sh") + configureNodeCmd := tr.target.ExecCommand("/bin/bash", + reconfigureScript, tr.testConfig.chainConfigs[action.Chain].BinaryName, string(action.Validator), string(action.Chain), - tr.chainConfigs[action.Chain].IpPrefix, valCfg.IpSuffix, + tr.testConfig.chainConfigs[action.Chain].IpPrefix, valCfg.IpSuffix, valCfg.ConsumerMnemonic, valCfg.ConsumerPrivValidatorKey, valCfg.ConsumerNodeKey, ) @@ -2208,7 +2143,7 @@ func (tr TestConfig) assignConsumerPubKey(action AssignConsumerPubKeyAction, tar // @POfftermatt I am currently using this for downtime slashing with cometmock // (I need to find the currently used validator key address)Í valCfg.UseConsumerKey = true - tr.validatorConfigs[action.Validator] = valCfg + tr.testConfig.validatorConfigs[action.Validator] = valCfg } // wait for inclusion in a block -> '--broadcast-mode block' is deprecated @@ -2222,19 +2157,19 @@ type SlashMeterReplenishmentAction struct { Timeout time.Duration } -func (tr TestConfig) waitForSlashMeterReplenishment( +func (tr Chain) waitForSlashMeterReplenishment( action SlashMeterReplenishmentAction, verbose bool, ) { timeout := time.Now().Add(action.Timeout) - initialSlashMeter := tr.getSlashMeter() + initialSlashMeter := tr.target.GetSlashMeter() if initialSlashMeter >= 0 { panic(fmt.Sprintf("No need to wait for slash meter replenishment, current value: %d", initialSlashMeter)) } for { - slashMeter := tr.getSlashMeter() + slashMeter := tr.target.GetSlashMeter() if verbose { fmt.Printf("waiting for slash meter to be replenished, current value: %d\n", slashMeter) } @@ -2256,7 +2191,7 @@ type WaitTimeAction struct { WaitTime time.Duration } -func (tr TestConfig) waitForTime( +func (tr Chain) waitForTime( action WaitTimeAction, verbose bool, ) { @@ -2266,7 +2201,7 @@ func (tr TestConfig) waitForTime( // GetPathNameForGorelayer returns the name of the path between two given chains used by Gorelayer. // Since paths are bidirectional, we need either chain to be able to be provided as first or second argument // and still return the same name, so we sort the chain names alphabetically. -func (tr TestConfig) GetPathNameForGorelayer(chainA, chainB ChainID) string { +func (tr Chain) GetPathNameForGorelayer(chainA, chainB ChainID) string { var pathName string if string(chainA) < string(chainB) { pathName = string(chainA) + "-" + string(chainB) @@ -2285,19 +2220,18 @@ type StartConsumerEvidenceDetectorAction struct { Chain ChainID } -func (tc TestConfig) startConsumerEvidenceDetector( +func (tr Chain) startConsumerEvidenceDetector( action StartConsumerEvidenceDetectorAction, - target ExecutionTarget, verbose bool, ) { - chainConfig := tc.chainConfigs[action.Chain] + chainConfig := tr.testConfig.chainConfigs[action.Chain] // run in detached mode so it will keep running in the background - bz, err := target.ExecDetachedCommand( + bz, err := tr.target.ExecDetachedCommand( "hermes", "evidence", "--chain", string(chainConfig.ChainId)).CombinedOutput() if err != nil { log.Fatal(err, "\n", string(bz)) } - tc.waitBlocks("provi", 10, 2*time.Minute) + tr.waitBlocks("provi", 10, 2*time.Minute) } // WaitTime waits for the given duration. @@ -2306,12 +2240,12 @@ func (tc TestConfig) startConsumerEvidenceDetector( // The CometMock version of this takes a pointer to the TestConfig as it needs to manipulate // information in the testrun that stores how much each chain has waited, to keep times in sync. // Be careful that all functions calling WaitTime should therefore also take a pointer to the TestConfig. -func (tr *TestConfig) WaitTime(duration time.Duration) { - if !tr.useCometmock { +func (tr *Chain) WaitTime(duration time.Duration) { + if !tr.testConfig.useCometmock { time.Sleep(duration) } else { - tr.timeOffset += duration - for chain, running := range tr.runningChains { + tr.testConfig.timeOffset += duration + for chain, running := range tr.testConfig.runningChains { if !running { continue } @@ -2321,12 +2255,12 @@ func (tr *TestConfig) WaitTime(duration time.Duration) { } } -func (tr TestConfig) AdvanceTimeForChain(chain ChainID, duration time.Duration) { +func (tr Chain) AdvanceTimeForChain(chain ChainID, duration time.Duration) { // cometmock avoids sleeping, and instead advances time for all chains method := "advance_time" params := fmt.Sprintf(`{"duration_in_seconds": "%d"}`, int(math.Ceil(duration.Seconds()))) - address := tr.getQueryNodeRPCAddress(chain) + address := tr.target.GetQueryNodeRPCAddress(chain) tr.curlJsonRPCRequest(method, params, address) diff --git a/tests/e2e/actions_consumer_misbehaviour.go b/tests/e2e/actions_consumer_misbehaviour.go index 10cd4ea5c6..6c2fc74304 100644 --- a/tests/e2e/actions_consumer_misbehaviour.go +++ b/tests/e2e/actions_consumer_misbehaviour.go @@ -3,7 +3,6 @@ package main import ( "bufio" "log" - "os/exec" "strconv" "time" ) @@ -17,15 +16,13 @@ type ForkConsumerChainAction struct { RelayerConfig string } -func (tc TestConfig) forkConsumerChain(action ForkConsumerChainAction, verbose bool) { - valCfg := tc.validatorConfigs[action.Validator] - - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - configureNodeCmd := exec.Command("docker", "exec", tc.containerConfig.InstanceName, "/bin/bash", - "/testnet-scripts/fork-consumer.sh", tc.chainConfigs[action.ConsumerChain].BinaryName, +func (tc Chain) forkConsumerChain(action ForkConsumerChainAction, verbose bool) { + valCfg := tc.testConfig.validatorConfigs[action.Validator] + configureNodeCmd := tc.target.ExecCommand("/bin/bash", + "/testnet-scripts/fork-consumer.sh", tc.testConfig.chainConfigs[action.ConsumerChain].BinaryName, string(action.Validator), string(action.ConsumerChain), - tc.chainConfigs[action.ConsumerChain].IpPrefix, - tc.chainConfigs[action.ProviderChain].IpPrefix, + tc.testConfig.chainConfigs[action.ConsumerChain].IpPrefix, + tc.testConfig.chainConfigs[action.ProviderChain].IpPrefix, valCfg.Mnemonic, action.RelayerConfig, ) @@ -69,21 +66,20 @@ type UpdateLightClientAction struct { ClientID string } -func (tc TestConfig) updateLightClient( +func (tc Chain) updateLightClient( action UpdateLightClientAction, verbose bool, ) { // retrieve a trusted height of the consumer light client - trustedHeight := tc.getTrustedHeight(action.HostChain, action.ClientID, 2) + revHeight, _ := tc.target.GetTrustedHeight(action.HostChain, action.ClientID, 2) - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - cmd := exec.Command("docker", "exec", tc.containerConfig.InstanceName, "hermes", + cmd := tc.target.ExecCommand("hermes", "--config", action.RelayerConfig, "update", "client", "--client", action.ClientID, "--host-chain", string(action.HostChain), - "--trusted-height", strconv.Itoa(int(trustedHeight.RevisionHeight)), + "--trusted-height", strconv.Itoa(int(revHeight)), ) if verbose { log.Println("UpdateLightClientAction cmd:", cmd.String()) diff --git a/tests/e2e/actions_sovereign_chain.go b/tests/e2e/actions_sovereign_chain.go index 3e5035aa5c..96d308ba57 100644 --- a/tests/e2e/actions_sovereign_chain.go +++ b/tests/e2e/actions_sovereign_chain.go @@ -17,12 +17,11 @@ type StartSovereignChainAction struct { // calls a simplified startup script (start-sovereign.sh) and runs a validator node // upgrades are simpler with a single validator node since only one node needs to be upgraded -func (tr TestConfig) startSovereignChain( +func (tr Chain) startSovereignChain( action StartSovereignChainAction, - target ExecutionTarget, verbose bool, ) { - chainConfig := tr.chainConfigs["sover"] + chainConfig := tr.testConfig.chainConfigs["sover"] type jsonValAttrs struct { Mnemonic string `json:"mnemonic"` Allocation string `json:"allocation"` @@ -40,18 +39,18 @@ func (tr TestConfig) startSovereignChain( var validators []jsonValAttrs for _, val := range action.Validators { validators = append(validators, jsonValAttrs{ - Mnemonic: tr.validatorConfigs[val.Id].Mnemonic, - NodeKey: tr.validatorConfigs[val.Id].NodeKey, + Mnemonic: tr.testConfig.validatorConfigs[val.Id].Mnemonic, + NodeKey: tr.testConfig.validatorConfigs[val.Id].NodeKey, ValId: fmt.Sprint(val.Id), - PrivValidatorKey: tr.validatorConfigs[val.Id].PrivValidatorKey, + PrivValidatorKey: tr.testConfig.validatorConfigs[val.Id].PrivValidatorKey, Allocation: fmt.Sprint(val.Allocation) + "stake", Stake: fmt.Sprint(val.Stake) + "stake", - IpSuffix: tr.validatorConfigs[val.Id].IpSuffix, + IpSuffix: tr.testConfig.validatorConfigs[val.Id].IpSuffix, - ConsumerMnemonic: tr.validatorConfigs[val.Id].ConsumerMnemonic, - ConsumerPrivValidatorKey: tr.validatorConfigs[val.Id].ConsumerPrivValidatorKey, + ConsumerMnemonic: tr.testConfig.validatorConfigs[val.Id].ConsumerMnemonic, + ConsumerPrivValidatorKey: tr.testConfig.validatorConfigs[val.Id].ConsumerPrivValidatorKey, // if true node will be started with consumer key for each consumer chain - StartWithConsumerKey: tr.validatorConfigs[val.Id].UseConsumerKey, + StartWithConsumerKey: tr.testConfig.validatorConfigs[val.Id].UseConsumerKey, }) } @@ -69,10 +68,10 @@ func (tr TestConfig) startSovereignChain( } isConsumer := chainConfig.BinaryName != "interchain-security-pd" - testScriptPath := target.GetTestScriptPath(isConsumer, "start-sovereign.sh") - cmd := target.ExecCommand("/bin/bash", testScriptPath, chainConfig.BinaryName, string(vals), + testScriptPath := tr.target.GetTestScriptPath(isConsumer, "start-sovereign.sh") + cmd := tr.target.ExecCommand("/bin/bash", testScriptPath, chainConfig.BinaryName, string(vals), string(chainConfig.ChainId), chainConfig.IpPrefix, genesisChanges, - tr.tendermintConfigOverride) + tr.testConfig.tendermintConfigOverride) cmdReader, err := cmd.StdoutPipe() if err != nil { @@ -101,7 +100,7 @@ func (tr TestConfig) startSovereignChain( tr.addChainToRelayer(AddChainToRelayerAction{ Chain: action.Chain, Validator: action.Validators[0].Id, - }, target, verbose) + }, verbose) } type LegacyUpgradeProposalAction struct { @@ -111,7 +110,7 @@ type LegacyUpgradeProposalAction struct { UpgradeHeight uint64 } -func (tr *TestConfig) submitLegacyUpgradeProposal(action LegacyUpgradeProposalAction, target ExecutionTarget, verbose bool) { +func (tr *Chain) submitLegacyUpgradeProposal(action LegacyUpgradeProposalAction, verbose bool) { submit := fmt.Sprintf( `%s tx gov submit-legacy-proposal software-upgrade %s \ --title %s \ @@ -127,16 +126,16 @@ func (tr *TestConfig) submitLegacyUpgradeProposal(action LegacyUpgradeProposalAc --node %s \ --no-validate \ -y`, - tr.chainConfigs[ChainID("sover")].BinaryName, + tr.testConfig.chainConfigs[ChainID("sover")].BinaryName, action.UpgradeTitle, action.UpgradeTitle, fmt.Sprint(action.UpgradeHeight), action.Proposer, - tr.chainConfigs[ChainID("sover")].ChainId, + tr.testConfig.chainConfigs[ChainID("sover")].ChainId, tr.getValidatorHome(ChainID("sover"), action.Proposer), tr.getValidatorNode(ChainID("sover"), action.Proposer), ) - cmd := target.ExecCommand("/bin/bash", "-c", submit) + cmd := tr.target.ExecCommand("/bin/bash", "-c", submit) if verbose { fmt.Println("submitUpgradeProposal cmd:", cmd.String()) @@ -155,7 +154,7 @@ type WaitUntilBlockAction struct { Chain ChainID } -func (tr *TestConfig) waitUntilBlockOnChain(action WaitUntilBlockAction) { +func (tr *Chain) waitUntilBlockOnChain(action WaitUntilBlockAction) { fmt.Println("waitUntilBlockOnChain is waiting for block:", action.Block) tr.waitUntilBlock(action.Chain, action.Block, 120*time.Second) fmt.Println("waitUntilBlockOnChain done waiting for block:", action.Block) diff --git a/tests/e2e/config.go b/tests/e2e/config.go index c48c397a51..7f6062b65c 100644 --- a/tests/e2e/config.go +++ b/tests/e2e/config.go @@ -7,6 +7,7 @@ import ( "strconv" "time" + e2e "github.com/cosmos/interchain-security/v5/tests/e2e/testlib" "golang.org/x/mod/semver" ) @@ -69,10 +70,13 @@ var hermesTemplates = map[string]string{ `, } -// TODO: Determine if user defined type (wrapping a primitive string) is desired in long run +// type aliases for shared types from e2e package type ( - ChainID string - ValidatorID string + ChainID = e2e.ChainID + ValidatorID = e2e.ValidatorID + ValidatorConfig = e2e.ValidatorConfig + ChainConfig = e2e.ChainConfig + ContainerConfig = e2e.ContainerConfig // will be moved back ) // Supported Test configurations to be used with GetTestConfig @@ -89,98 +93,6 @@ const ( CompatibilityTestCfg TestConfigType = "compatibility" ) -// Attributes that are unique to a validator. Allows us to map (part of) -// the set of strings defined above to a set of viable validators -type ValidatorConfig struct { - // Seed phrase to generate a secp256k1 key used by the validator on the provider - Mnemonic string - // Validator account address on provider marshaled to string using Bech32 - // with Bech32Prefix = ProviderAccountPrefix - DelAddress string - // Validator account address on provider marshaled to string using Bech32 - // with Bech32Prefix = ConsumerAccountPrefix - DelAddressOnConsumer string - // Validator operator address on provider marshaled to string using Bech32 - // with Bech32Prefix = ProviderAccountPrefix - ValoperAddress string - // Validator operator address on provider marshaled to string using Bech32 - // with Bech32Prefix = ConsumerAccountPrefix - ValoperAddressOnConsumer string - // Validator consensus address on provider marshaled to string using Bech32 - // with Bech32Prefix = ProviderAccountPrefix. It matches the PrivValidatorKey below. - ValconsAddress string - // Validator consensus address on provider marshaled to string using Bech32 - // with Bech32Prefix = ConsumerAccountPrefix. - ValconsAddressOnConsumer string - // Key used for consensus on provider - PrivValidatorKey string - NodeKey string - // Must be an integer greater than 0 and less than 253 - IpSuffix string - - // consumer chain key assignment data - // keys are used on a new node - - // Seed phrase to generate a secp256k1 key used by the validator on the consumer - ConsumerMnemonic string - // Validator account address on consumer marshaled to string using Bech32 - // with Bech32Prefix = ConsumerAccountPrefix - ConsumerDelAddress string - // Validator account address on consumer marshaled to string using Bech32 - // with Bech32Prefix = ProviderAccountPrefix - ConsumerDelAddressOnProvider string - // Validator operator address on consumer marshaled to string using Bech32 - // with Bech32Prefix = ConsumerAccountPrefix - ConsumerValoperAddress string - // Validator operator address on consumer marshaled to string using Bech32 - // with Bech32Prefix = ProviderAccountPrefix - ConsumerValoperAddressOnProvider string - // Validator consensus address on consumer marshaled to string using Bech32 - // with Bech32Prefix = ConsumerAccountPrefix. It matches the PrivValidatorKey below. - ConsumerValconsAddress string - // Validator consensus address on consumer marshaled to string using Bech32 - // with Bech32Prefix = ProviderAccountPrefix. - ConsumerValconsAddressOnProvider string - ConsumerValPubKey string - // Key used for consensus on consumer - ConsumerPrivValidatorKey string - ConsumerNodeKey string - UseConsumerKey bool // if true the validator node will start with consumer key -} - -// Attributes that are unique to a chain. Allows us to map (part of) -// the set of strings defined above to a set of viable chains -type ChainConfig struct { - ChainId ChainID - // The account prefix configured on the chain. For example, on the Hub, this is "cosmos" - AccountPrefix string - // Must be unique per chain - IpPrefix string - VotingWaitTime uint - // Any transformations to apply to the genesis file of all chains instantiated with this chain config, as a jq string. - // Example: ".app_state.gov.params.voting_period = \"5s\" | .app_state.slashing.params.signed_blocks_window = \"2\" | .app_state.slashing.params.min_signed_per_window = \"0.500000000000000000\"" - GenesisChanges string - BinaryName string - - // binary to use after upgrade height - UpgradeBinary string -} - -type ContainerConfig struct { - ContainerName string - InstanceName string - CcvVersion string - Now time.Time -} - -type TargetConfig struct { - gaiaTag string - localSdkPath string - useGaia bool - providerVersion string - consumerVersion string -} - type TestConfig struct { // These are the non altered values during a typical test run, where multiple test runs can exist // to validate different action sequences and corresponding state checks. @@ -221,7 +133,8 @@ func getIcsVersion(reference string) string { // remove build suffix return semver.Canonical(reference) } - for _, tag := range []string{"v2.0.0", "v2.4.0", "v2.4.0-lsm", "v3.1.0", "v3.2.0", "v3.3.0", "v4.0.0"} { + + for _, tag := range []string{"v2.0.0", "v2.4.0", "v2.4.0-lsm", "v3.1.0", "v3.2.0", "v3.3.0", "v4.0.0", "v4.1.1", "v4.1.1-lsm"} { //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments cmd := exec.Command("git", "merge-base", "--is-ancestor", reference, tag) out, err := cmd.CombinedOutput() @@ -412,7 +325,7 @@ func CompatibilityTestConfig(providerVersion, consumerVersion string) TestConfig var providerConfig, consumerConfig ChainConfig if !semver.IsValid(consumerVersion) { - fmt.Println("Using default provider chain config") + fmt.Printf("Invalid sem-version '%s' for provider.Using default provider chain config\n", consumerVersion) consumerConfig = testCfg.chainConfigs[ChainID("consu")] } else if semver.Compare(consumerVersion, "v3.0.0") < 0 { fmt.Println("Using consumer chain config for v2.0.0") @@ -442,6 +355,20 @@ func CompatibilityTestConfig(providerVersion, consumerVersion string) TestConfig ".app_state.slashing.params.downtime_jail_duration = \"60s\" | " + ".app_state.slashing.params.slash_fraction_downtime = \"0.010000000000000000\"", } + } else if semver.Compare(consumerVersion, "v5.0.0-alpha1") < 0 { // TODO: change this to first published v5 release - once it's out + fmt.Println("Using consumer chain config for v4.x.x") + consumerConfig = ChainConfig{ + ChainId: ChainID("consu"), + AccountPrefix: ConsumerAccountPrefix, + BinaryName: "interchain-security-cd", + IpPrefix: "7.7.8", + VotingWaitTime: 20, + GenesisChanges: ".app_state.gov.params.voting_period = \"20s\" | " + + ".app_state.slashing.params.signed_blocks_window = \"20\" | " + + ".app_state.slashing.params.min_signed_per_window = \"0.500000000000000000\" | " + + ".app_state.slashing.params.downtime_jail_duration = \"60s\" | " + + ".app_state.slashing.params.slash_fraction_downtime = \"0.010000000000000000\"", + } } else { fmt.Println("Using default consumer chain config") consumerConfig = testCfg.chainConfigs[ChainID("consu")] @@ -449,7 +376,7 @@ func CompatibilityTestConfig(providerVersion, consumerVersion string) TestConfig // Get the provider chain config for a specific version if !semver.IsValid(providerVersion) { - fmt.Println("Using default provider chain config") + fmt.Printf("Invalid sem-version '%s' for provider. Using default provider chain config\n", providerVersion) providerConfig = testCfg.chainConfigs[ChainID("provi")] } else if semver.Compare(providerVersion, "v3.0.0") < 0 { fmt.Println("Using provider chain config for v2.x.x") @@ -487,6 +414,25 @@ func CompatibilityTestConfig(providerVersion, consumerVersion string) TestConfig ".app_state.provider.params.slash_meter_replenish_fraction = \"1.0\" | " + // This disables slash packet throttling ".app_state.provider.params.slash_meter_replenish_period = \"3s\"", } + } else if semver.Compare(providerVersion, "v5.0.0-alpha1") < 0 { //TODO: MOV THIS BACK TO "v5.0.0" + fmt.Println("Using provider chain config for v4.1.x") + providerConfig = ChainConfig{ + ChainId: ChainID("provi"), + AccountPrefix: ProviderAccountPrefix, + BinaryName: "interchain-security-pd", + IpPrefix: "7.7.7", + VotingWaitTime: 20, + GenesisChanges: ".app_state.gov.params.voting_period = \"20s\" | " + + // Custom slashing parameters for testing validator downtime functionality + // See https://docs.cosmos.network/main/modules/slashing/04_begin_block.html#uptime-tracking + ".app_state.slashing.params.signed_blocks_window = \"10\" | " + + ".app_state.slashing.params.min_signed_per_window = \"0.500000000000000000\" | " + + ".app_state.slashing.params.downtime_jail_duration = \"60s\" | " + + ".app_state.slashing.params.slash_fraction_downtime = \"0.010000000000000000\" | " + + ".app_state.provider.params.slash_meter_replenish_fraction = \"1.0\" | " + // This disables slash packet throttling + ".app_state.provider.params.slash_meter_replenish_period = \"3s\" | " + + ".app_state.provider.params.blocks_per_epoch = 3", + } } else { fmt.Println("Using default provider chain config") providerConfig = testCfg.chainConfigs[ChainID("provi")] @@ -944,7 +890,7 @@ func getValidatorConfigFromVersion(providerVersion, consumerVersion string) map[ }, } case "v4.0.0": - fmt.Println("Using current default validator configs: ", providerVersion) + fmt.Println("Using current validator configs v4.0.0: ", providerVersion) validatorCfg = map[ValidatorID]ValidatorConfig{ ValidatorID("alice"): { Mnemonic: "pave immune ethics wrap gain ceiling always holiday employ earth tumble real ice engage false unable carbon equal fresh sick tattoo nature pupil nuclear", diff --git a/tests/e2e/json_marshal_test.go b/tests/e2e/json_marshal_test.go index 9a7694587f..1265063e69 100644 --- a/tests/e2e/json_marshal_test.go +++ b/tests/e2e/json_marshal_test.go @@ -9,6 +9,7 @@ import ( gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + e2e "github.com/cosmos/interchain-security/v5/tests/e2e/testlib" "github.com/davecgh/go-spew/spew" ) @@ -45,7 +46,7 @@ func TestProposalUnmarshal(t *testing.T) { t.Errorf("Unexpected error while unmarshalling: %v", err) } - actualProposal, err := UnmarshalProposalWithType(propAndType.RawProposal, propAndType.Type) + actualProposal, err := e2e.UnmarshalProposalWithType(propAndType.RawProposal, propAndType.Type) if err != nil { t.Errorf("Unexpected error while unmarshalling\n error: %v\n Raw proposal: %v\n Type: %v", err, spew.Sdump(propAndType.RawProposal), propAndType.Type) } diff --git a/tests/e2e/json_utils.go b/tests/e2e/json_utils.go index d94f599588..e1e0b67fc6 100644 --- a/tests/e2e/json_utils.go +++ b/tests/e2e/json_utils.go @@ -6,23 +6,6 @@ import ( "reflect" ) -// stores a proposal as a raw json, together with its type -type ProposalAndType struct { - RawProposal json.RawMessage - Type string -} - -type ( - // to have a ChainState object that does not have the overridden Marshal/Unmarshal method - ChainStateCopy ChainState - - // duplicated from the ChainState with a minor change to the Proposals field - ChainStateWithProposalTypes struct { - ChainStateCopy - Proposals *map[uint]ProposalAndType // the only thing changed from the real ChainState - } -) - // MarshalJSON marshals a step into JSON while including the type of the action. func (step Step) MarshalJSON() ([]byte, error) { actionType := reflect.TypeOf(step.Action) @@ -298,89 +281,3 @@ func UnmarshalMapToActionType(rawAction json.RawMessage, actionTypeString string } return nil, err } - -// custom marshal and unmarshal functions for the chainstate that convert proposals to/from the auxiliary type with type info - -// MarshalJSON transforms the ChainState into a ChainStateWithProposalTypes by adding type info to the proposals -func (c ChainState) MarshalJSON() ([]byte, error) { - chainStateCopy := ChainStateCopy(c) - chainStateWithProposalTypes := ChainStateWithProposalTypes{chainStateCopy, nil} - if c.Proposals != nil { - proposalsWithTypes := make(map[uint]ProposalAndType) - for k, v := range *c.Proposals { - rawMessage, err := json.Marshal(v) - if err != nil { - return nil, err - } - proposalsWithTypes[k] = ProposalAndType{rawMessage, reflect.TypeOf(v).String()} - } - chainStateWithProposalTypes.Proposals = &proposalsWithTypes - } - return json.Marshal(chainStateWithProposalTypes) -} - -// UnmarshalJSON unmarshals the ChainStateWithProposalTypes into a ChainState by removing the type info from the proposals and getting back standard proposals -func (c *ChainState) UnmarshalJSON(data []byte) error { - chainStateWithProposalTypes := ChainStateWithProposalTypes{} - err := json.Unmarshal(data, &chainStateWithProposalTypes) - if err != nil { - return err - } - - chainState := ChainState(chainStateWithProposalTypes.ChainStateCopy) - *c = chainState - - if chainStateWithProposalTypes.Proposals != nil { - proposals := make(map[uint]Proposal) - for k, v := range *chainStateWithProposalTypes.Proposals { - proposal, err := UnmarshalProposalWithType(v.RawProposal, v.Type) - if err != nil { - return err - } - proposals[k] = proposal - } - c.Proposals = &proposals - } - return nil -} - -// UnmarshalProposalWithType takes a JSON object and a proposal type and marshals into an object of the corresponding proposal. -func UnmarshalProposalWithType(inputMap json.RawMessage, proposalType string) (Proposal, error) { - var err error - switch proposalType { - case "main.TextProposal": - prop := TextProposal{} - err := json.Unmarshal(inputMap, &prop) - if err == nil { - return prop, nil - } - case "main.ConsumerAdditionProposal": - prop := ConsumerAdditionProposal{} - err := json.Unmarshal(inputMap, &prop) - if err == nil { - return prop, nil - } - case "main.UpgradeProposal": - prop := UpgradeProposal{} - err := json.Unmarshal(inputMap, &prop) - if err == nil { - return prop, nil - } - case "main.ConsumerRemovalProposal": - prop := ConsumerRemovalProposal{} - err := json.Unmarshal(inputMap, &prop) - if err == nil { - return prop, nil - } - case "main.IBCTransferParamsProposal": - prop := IBCTransferParamsProposal{} - err := json.Unmarshal(inputMap, &prop) - if err == nil { - return prop, nil - } - default: - return nil, fmt.Errorf("%s is not a known proposal type", proposalType) - } - - return nil, err -} diff --git a/tests/e2e/state.go b/tests/e2e/state.go index e4cb225392..86882ddc56 100644 --- a/tests/e2e/state.go +++ b/tests/e2e/state.go @@ -11,192 +11,105 @@ import ( "time" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + e2e "github.com/cosmos/interchain-security/v5/tests/e2e/testlib" "github.com/kylelemons/godebug/pretty" "github.com/tidwall/gjson" "gopkg.in/yaml.v2" ) -type State map[ChainID]ChainState - -type ChainState struct { - ValBalances *map[ValidatorID]uint - Proposals *map[uint]Proposal - ProposedConsumerChains *[]string - ValPowers *map[ValidatorID]uint - StakedTokens *map[ValidatorID]uint - IBCTransferParams *IBCTransferParams - Rewards *Rewards - ConsumerChains *map[ChainID]bool - AssignedKeys *map[ValidatorID]string - ProviderKeys *map[ValidatorID]string // validatorID: validator provider key - ConsumerPendingPacketQueueSize *uint // Only relevant to consumer chains - RegisteredConsumerRewardDenoms *[]string - ClientsFrozenHeights *map[string]clienttypes.Height -} - -type Proposal interface { - isProposal() -} -type TextProposal struct { - Title string - Description string - Deposit uint - Status string -} - -func (p TextProposal) isProposal() {} - -type IBCTransferParamsProposal struct { - Title string - Deposit uint - Status string - Params IBCTransferParams -} - -func (ibct IBCTransferParamsProposal) isProposal() {} - -type ConsumerAdditionProposal struct { - Deposit uint - Chain ChainID - SpawnTime int - InitialHeight clienttypes.Height - Status string -} - -type UpgradeProposal struct { - Title string - Description string - UpgradeHeight uint64 - Type string - Deposit uint - Status string -} - -func (p UpgradeProposal) isProposal() {} - -func (p ConsumerAdditionProposal) isProposal() {} - -type ConsumerRemovalProposal struct { - Deposit uint - Chain ChainID - StopTime int - Status string -} - -func (p ConsumerRemovalProposal) isProposal() {} - -type Rewards struct { - IsRewarded map[ValidatorID]bool - // if true it will calculate if the validator/delegator is rewarded between 2 successive blocks, - // otherwise it will calculate if it received any rewards since the 1st block - IsIncrementalReward bool - // if true checks rewards for "stake" token, otherwise checks rewards from - // other chains (e.g. false is used to check if provider received rewards from a consumer chain) - IsNativeDenom bool -} - -type ParamsProposal struct { - Deposit uint - Status string - Subspace string - Key string - Value string -} - -func (p ParamsProposal) isProposal() {} +// type aliases +type ( + ChainState = e2e.ChainState + Proposal = e2e.Proposal + Rewards = e2e.Rewards + TextProposal = e2e.TextProposal + UpgradeProposal = e2e.UpgradeProposal + ConsumerAdditionProposal = e2e.ConsumerAdditionProposal + ConsumerRemovalProposal = e2e.ConsumerRemovalProposal + IBCTransferParams = e2e.IBCTransferParams + IBCTransferParamsProposal = e2e.IBCTransferParamsProposal + Param = e2e.Param + ParamsProposal = e2e.ParamsProposal + TargetDriver = e2e.TargetDriver +) -type Param struct { - Subspace string - Key string - Value string -} +type State map[ChainID]ChainState -type IBCTransferParams struct { - SendEnabled bool `json:"send_enabled"` - ReceiveEnabled bool `json:"receive_enabled"` +type Chain struct { + target e2e.TargetDriver + testConfig TestConfig } -func (tr TestConfig) getState(modelState State, verbose bool) State { - systemState := State{} - for k, modelState := range modelState { - if verbose { - fmt.Println("Getting model state for chain: ", k) - } - systemState[k] = tr.getChainState(k, modelState) - } - - return systemState -} +func (tr Chain) GetChainState(chain ChainID, modelState ChainState) ChainState { -func (tr TestConfig) getChainState(chain ChainID, modelState ChainState) ChainState { chainState := ChainState{} if modelState.ValBalances != nil { - valBalances := tr.getBalances(chain, *modelState.ValBalances) + valBalances := tr.GetBalances(chain, *modelState.ValBalances) chainState.ValBalances = &valBalances } if modelState.Proposals != nil { - proposals := tr.getProposals(chain, *modelState.Proposals) + proposals := tr.GetProposals(chain, *modelState.Proposals) chainState.Proposals = &proposals } if modelState.ProposedConsumerChains != nil { - proposedConsumerChains := tr.getProposedConsumerChains(chain) + proposedConsumerChains := tr.GetProposedConsumerChains(chain) chainState.ProposedConsumerChains = &proposedConsumerChains } if modelState.ValPowers != nil { tr.waitBlocks(chain, 1, 10*time.Second) - powers := tr.getValPowers(chain, *modelState.ValPowers) + powers := tr.GetValPowers(chain, *modelState.ValPowers) chainState.ValPowers = &powers } if modelState.StakedTokens != nil { - representPowers := tr.getStakedTokens(chain, *modelState.StakedTokens) + representPowers := tr.GetStakedTokens(chain, *modelState.StakedTokens) chainState.StakedTokens = &representPowers } if modelState.IBCTransferParams != nil { - params := tr.getIBCTransferParams(chain) + params := tr.target.GetIBCTransferParams(chain) chainState.IBCTransferParams = ¶ms } if modelState.Rewards != nil { - rewards := tr.getRewards(chain, *modelState.Rewards) + rewards := tr.GetRewards(chain, *modelState.Rewards) chainState.Rewards = &rewards } if modelState.ConsumerChains != nil { - chains := tr.getConsumerChains(chain) + chains := tr.target.GetConsumerChains(chain) chainState.ConsumerChains = &chains } if modelState.AssignedKeys != nil { - assignedKeys := tr.getConsumerAddresses(chain, *modelState.AssignedKeys) + assignedKeys := tr.GetConsumerAddresses(chain, *modelState.AssignedKeys) chainState.AssignedKeys = &assignedKeys } if modelState.ProviderKeys != nil { - providerKeys := tr.getProviderAddresses(chain, *modelState.ProviderKeys) + providerKeys := tr.GetProviderAddresses(chain, *modelState.ProviderKeys) chainState.ProviderKeys = &providerKeys } if modelState.RegisteredConsumerRewardDenoms != nil { - registeredConsumerRewardDenoms := tr.getRegisteredConsumerRewardDenoms(chain) + registeredConsumerRewardDenoms := tr.target.GetRegisteredConsumerRewardDenoms(chain) chainState.RegisteredConsumerRewardDenoms = ®isteredConsumerRewardDenoms } if modelState.ClientsFrozenHeights != nil { chainClientsFrozenHeights := map[string]clienttypes.Height{} for id := range *modelState.ClientsFrozenHeights { - chainClientsFrozenHeights[id] = tr.getClientFrozenHeight(chain, id) + chainClientsFrozenHeights[id] = tr.GetClientFrozenHeight(chain, id) } chainState.ClientsFrozenHeights = &chainClientsFrozenHeights } if modelState.ConsumerPendingPacketQueueSize != nil { - pendingPacketQueueSize := tr.getPendingPacketQueueSize(chain) + pendingPacketQueueSize := tr.target.GetPendingPacketQueueSize(chain) chainState.ConsumerPendingPacketQueueSize = &pendingPacketQueueSize } @@ -207,44 +120,22 @@ func (tr TestConfig) getChainState(chain ChainID, modelState ChainState) ChainSt return chainState } -var blockHeightRegex = regexp.MustCompile(`block_height: "(\d+)"`) - -func (tr TestConfig) getBlockHeight(chain ChainID) uint { - //#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", "tendermint-validator-set", - - `--node`, tr.getQueryNode(chain), - ).CombinedOutput() - if err != nil { - log.Fatal(err, "\n", string(bz)) - } - - blockHeight, err := strconv.Atoi(blockHeightRegex.FindStringSubmatch(string(bz))[1]) - if err != nil { - log.Fatal(err) - } - - return uint(blockHeight) -} - -func (tr TestConfig) waitBlocks(chain ChainID, blocks uint, timeout time.Duration) { - if tr.useCometmock { +func (tr Chain) waitBlocks(chain ChainID, blocks uint, timeout time.Duration) { + if tr.testConfig.useCometmock { // call advance_blocks method on cometmock // curl -H 'Content-Type: application/json' -H 'Accept:application/json' --data '{"jsonrpc":"2.0","method":"advance_blocks","params":{"num_blocks": "36000000"},"id":1}' 127.0.0.1:22331 - tcpAddress := tr.getQueryNodeRPCAddress(chain) + tcpAddress := tr.target.GetQueryNodeRPCAddress(chain) method := "advance_blocks" params := fmt.Sprintf(`{"num_blocks": "%d"}`, blocks) tr.curlJsonRPCRequest(method, params, tcpAddress) return } - startBlock := tr.getBlockHeight(chain) + startBlock := tr.target.GetBlockHeight(chain) start := time.Now() for { - thisBlock := tr.getBlockHeight(chain) + thisBlock := tr.target.GetBlockHeight(chain) if thisBlock >= startBlock+blocks { return } @@ -255,10 +146,10 @@ func (tr TestConfig) waitBlocks(chain ChainID, blocks uint, timeout time.Duratio } } -func (tr TestConfig) waitUntilBlock(chain ChainID, block uint, timeout time.Duration) { +func (tr Chain) waitUntilBlock(chain ChainID, block uint, timeout time.Duration) { start := time.Now() for { - thisBlock := tr.getBlockHeight(chain) + thisBlock := tr.target.GetBlockHeight(chain) if thisBlock >= block { return } @@ -269,61 +160,181 @@ func (tr TestConfig) waitUntilBlock(chain ChainID, block uint, timeout time.Dura } } -func (tr TestConfig) getBalances(chain ChainID, modelState map[ValidatorID]uint) map[ValidatorID]uint { +func (tr Chain) GetBalances(chain ChainID, modelState map[ValidatorID]uint) map[ValidatorID]uint { actualState := map[ValidatorID]uint{} for k := range modelState { - actualState[k] = tr.getBalance(chain, k) + actualState[k] = tr.target.GetBalance(chain, k) } return actualState } -func (tr TestConfig) getProposals(chain ChainID, modelState map[uint]Proposal) map[uint]Proposal { +func (tr Chain) GetClientFrozenHeight(chain ChainID, clientID string) clienttypes.Height { + revNumber, revHeight := tr.target.GetClientFrozenHeight(chain, clientID) + return clienttypes.Height{RevisionHeight: uint64(revHeight), RevisionNumber: uint64(revNumber)} +} + +func (tr Chain) GetProposedConsumerChains(chain ChainID) []string { + tr.waitBlocks(chain, 1, 10*time.Second) + return tr.target.GetProposedConsumerChains(chain) +} + +func (tr Chain) GetProposals(chain ChainID, modelState map[uint]Proposal) map[uint]Proposal { actualState := map[uint]Proposal{} for k := range modelState { - actualState[k] = tr.getProposal(chain, k) + actualState[k] = tr.target.GetProposal(chain, k) } return actualState } -func (tr TestConfig) getValPowers(chain ChainID, modelState map[ValidatorID]uint) map[ValidatorID]uint { +func (tr Chain) GetValPowers(chain ChainID, modelState map[ValidatorID]uint) map[ValidatorID]uint { actualState := map[ValidatorID]uint{} + validatorConfigs := tr.testConfig.validatorConfigs for k := range modelState { - actualState[k] = tr.getValPower(chain, k) + valAddresses := map[string]bool{} + if chain == ChainID("provi") { + // use binary with Bech32Prefix set to ProviderAccountPrefix + valAddresses[validatorConfigs[k].ValconsAddress] = true + } else { + // use binary with Bech32Prefix set to ConsumerAccountPrefix + valAddresses[validatorConfigs[k].ValconsAddressOnConsumer] = true + valAddresses[validatorConfigs[k].ConsumerValconsAddress] = true + } + actualState[k] = tr.target.GetValPower(chain, k) } return actualState } -func (tr TestConfig) getStakedTokens(chain ChainID, modelState map[ValidatorID]uint) map[ValidatorID]uint { +func (tr Chain) GetStakedTokens(chain ChainID, modelState map[ValidatorID]uint) map[ValidatorID]uint { actualState := map[ValidatorID]uint{} - for k := range modelState { - actualState[k] = tr.getValStakedTokens(chain, k) + for validator := range modelState { + validatorConfigs := tr.testConfig.validatorConfigs + valoperAddress := validatorConfigs[validator].ValoperAddress + if chain != ChainID("provi") { + // use binary with Bech32Prefix set to ConsumerAccountPrefix + if validatorConfigs[validator].UseConsumerKey { + valoperAddress = validatorConfigs[validator].ConsumerValoperAddress + } else { + // use the same address as on the provider but with different prefix + valoperAddress = validatorConfigs[validator].ValoperAddressOnConsumer + } + } + + actualState[validator] = tr.target.GetValStakedTokens(chain, valoperAddress) } return actualState } -func (tr TestConfig) getRewards(chain ChainID, modelState Rewards) Rewards { +func (tr Chain) GetRewards(chain ChainID, modelState Rewards) Rewards { receivedRewards := map[ValidatorID]bool{} - currentBlock := tr.getBlockHeight(chain) + currentBlock := tr.target.GetBlockHeight(chain) tr.waitBlocks(chain, 1, 10*time.Second) - nextBlock := tr.getBlockHeight(chain) + nextBlock := tr.target.GetBlockHeight(chain) tr.waitBlocks(chain, 1, 10*time.Second) if !modelState.IsIncrementalReward { currentBlock = 1 } for k := range modelState.IsRewarded { - receivedRewards[k] = tr.getReward(chain, k, nextBlock, modelState.IsNativeDenom) > tr.getReward(chain, k, currentBlock, modelState.IsNativeDenom) + receivedRewards[k] = tr.target.GetReward(chain, k, nextBlock, modelState.IsNativeDenom) > tr.target.GetReward(chain, k, currentBlock, modelState.IsNativeDenom) } return Rewards{IsRewarded: receivedRewards, IsIncrementalReward: modelState.IsIncrementalReward, IsNativeDenom: modelState.IsNativeDenom} } -func (tr TestConfig) getReward(chain ChainID, validator ValidatorID, blockHeight uint, isNativeDenom bool) float64 { +func (tr Chain) GetConsumerAddresses(chain ChainID, modelState map[ValidatorID]string) map[ValidatorID]string { + actualState := map[ValidatorID]string{} + for k := range modelState { + actualState[k] = tr.target.GetConsumerAddress(chain, k) + } + + return actualState +} + +func (tr Chain) GetProviderAddresses(chain ChainID, modelState map[ValidatorID]string) map[ValidatorID]string { + actualState := map[ValidatorID]string{} + for k := range modelState { + actualState[k] = tr.target.GetProviderAddressFromConsumer(chain, k) + } + + return actualState +} + +func (tr Chain) getValidatorNode(chain ChainID, validator ValidatorID) string { + // for CometMock, validatorNodes are all the same address as the query node (which is CometMocks address) + if tr.testConfig.useCometmock { + return tr.target.GetQueryNode(chain) + } + + return "tcp://" + tr.getValidatorIP(chain, validator) + ":26658" +} + +func (tr Chain) getValidatorIP(chain ChainID, validator ValidatorID) string { + return tr.testConfig.chainConfigs[chain].IpPrefix + "." + tr.testConfig.validatorConfigs[validator].IpSuffix +} + +func (tr Chain) getValidatorHome(chain ChainID, validator ValidatorID) string { + return `/` + string(tr.testConfig.chainConfigs[chain].ChainId) + `/validator` + fmt.Sprint(validator) +} + +func (tr Chain) curlJsonRPCRequest(method, params, address string) { + cmd_template := `curl -H 'Content-Type: application/json' -H 'Accept:application/json' --data '{"jsonrpc":"2.0","method":"%s","params":%s,"id":1}' %s` + + cmd := tr.target.ExecCommand("bash", "-c", fmt.Sprintf(cmd_template, method, params, address)) + + verbosity := false + e2e.ExecuteCommandWithVerbosity(cmd, "curlJsonRPCRequest", verbosity) +} + +func uintPtr(i uint) *uint { + return &i +} + +type Commands struct { + containerConfig ContainerConfig // FIXME only needed for 'Now' time tracking + validatorConfigs map[ValidatorID]ValidatorConfig + chainConfigs map[ChainID]ChainConfig + target e2e.PlatformDriver +} + +func (tr Commands) ExecCommand(name string, arg ...string) *exec.Cmd { + return tr.target.ExecCommand(name, arg...) +} + +func (tr Commands) ExecDetachedCommand(name string, args ...string) *exec.Cmd { + return tr.target.ExecDetachedCommand(name, args...) +} + +func (tr Commands) GetTestScriptPath(isConsumer bool, script string) string { + return tr.target.GetTestScriptPath(isConsumer, script) +} + +func (tr Commands) GetBlockHeight(chain ChainID) uint { + binaryName := tr.chainConfigs[chain].BinaryName + bz, err := tr.target.ExecCommand(binaryName, + + "query", "tendermint-validator-set", + + `--node`, tr.GetQueryNode(chain), + ).CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + blockHeightRegex := regexp.MustCompile(`block_height: "(\d+)"`) + blockHeight, err := strconv.Atoi(blockHeightRegex.FindStringSubmatch(string(bz))[1]) + if err != nil { + log.Fatal(err) + } + + return uint(blockHeight) +} + +func (tr Commands) GetReward(chain ChainID, validator ValidatorID, blockHeight uint, isNativeDenom bool) float64 { valCfg := tr.validatorConfigs[validator] delAddresss := valCfg.DelAddress if chain != ChainID("provi") { @@ -336,12 +347,12 @@ func (tr TestConfig) getReward(chain ChainID, validator ValidatorID, blockHeight } } - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, + binaryName := tr.chainConfigs[chain].BinaryName + cmd := tr.target.ExecCommand(binaryName, "query", "distribution", "delegation-total-rewards", "--delegator-address", delAddresss, `--height`, fmt.Sprint(blockHeight), - `--node`, tr.getQueryNode(chain), + `--node`, tr.GetQueryNode(chain), `-o`, `json`, ) @@ -359,47 +370,15 @@ func (tr TestConfig) getReward(chain ChainID, validator ValidatorID, blockHeight return gjson.Get(string(bz), denomCondition).Float() } -func (tr TestConfig) getBalance(chain ChainID, validator ValidatorID) uint { - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - valCfg := tr.validatorConfigs[validator] - valDelAddress := valCfg.DelAddress - if chain != ChainID("provi") { - // use binary with Bech32Prefix set to ConsumerAccountPrefix - if valCfg.UseConsumerKey { - valDelAddress = valCfg.ConsumerDelAddress - } else { - // use the same address as on the provider but with different prefix - valDelAddress = valCfg.DelAddressOnConsumer - } - } - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, - - "query", "bank", "balances", - valDelAddress, - - `--node`, tr.getQueryNode(chain), - `-o`, `json`, - ) - bz, err := cmd.CombinedOutput() - if err != nil { - log.Fatal("getBalance() failed: ", cmd, ": ", err, "\n", string(bz)) - } - - amount := gjson.Get(string(bz), `balances.#(denom=="stake").amount`) - - return uint(amount.Uint()) -} - -var noProposalRegex = regexp.MustCompile(`doesn't exist: key not found`) - // interchain-securityd query gov proposals -func (tr TestConfig) getProposal(chain ChainID, proposal uint) Proposal { - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - bz, err := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, +func (tr Commands) GetProposal(chain ChainID, proposal uint) Proposal { + var noProposalRegex = regexp.MustCompile(`doesn't exist: key not found`) + + binaryName := tr.chainConfigs[chain].BinaryName + bz, err := tr.target.ExecCommand(binaryName, "query", "gov", "proposal", fmt.Sprint(proposal), - `--node`, tr.getQueryNode(chain), + `--node`, tr.GetQueryNode(chain), `-o`, `json`, ).CombinedOutput() @@ -502,7 +481,7 @@ func (tr TestConfig) getProposal(chain ChainID, proposal uint) Proposal { } } - log.Fatal("received unknosn proposal type: ", propType, "proposal JSON:", string(bz)) + log.Fatal("received unknown proposal type: ", propType, "proposal JSON:", string(bz)) return nil } @@ -525,16 +504,16 @@ type ValPubKey struct { } // TODO (mpoke) Return powers for multiple validators -func (tr TestConfig) getValPower(chain ChainID, validator ValidatorID) uint { +func (tr Commands) GetValPower(chain ChainID, validator ValidatorID) uint { if *verbose { log.Println("getting validator power for chain: ", chain, " validator: ", validator) } - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - command := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, + binaryName := tr.chainConfigs[chain].BinaryName + command := tr.target.ExecCommand(binaryName, "query", "tendermint-validator-set", - `--node`, tr.getQueryNode(chain), + `--node`, tr.GetQueryNode(chain), ) bz, err := command.CombinedOutput() if err != nil { @@ -550,7 +529,8 @@ func (tr TestConfig) getValPower(chain ChainID, validator ValidatorID) uint { total, err := strconv.Atoi(valset.Pagination.Total) if err != nil { - log.Fatalf("strconv.Atoi returned an error while coonverting total for validator set: %v, input: %s, validator set: %s", err, valset.Pagination.Total, pretty.Sprint(valset)) + log.Fatalf("strconv.Atoi returned an error while converting total for validator set: %v, input: %s, validator set: %s, src:%s", + err, valset.Pagination.Total, pretty.Sprint(valset), string(bz)) } if total != len(valset.Validators) { @@ -584,25 +564,46 @@ func (tr TestConfig) getValPower(chain ChainID, validator ValidatorID) uint { return 0 } -func (tr TestConfig) getValStakedTokens(chain ChainID, validator ValidatorID) uint { - valoperAddress := tr.validatorConfigs[validator].ValoperAddress +func (tr Commands) GetBalance(chain ChainID, validator ValidatorID) uint { + valCfg := tr.validatorConfigs[validator] + valDelAddress := valCfg.DelAddress if chain != ChainID("provi") { // use binary with Bech32Prefix set to ConsumerAccountPrefix - if tr.validatorConfigs[validator].UseConsumerKey { - valoperAddress = tr.validatorConfigs[validator].ConsumerValoperAddress + if valCfg.UseConsumerKey { + valDelAddress = valCfg.ConsumerDelAddress } else { // use the same address as on the provider but with different prefix - valoperAddress = tr.validatorConfigs[validator].ValoperAddressOnConsumer + valDelAddress = valCfg.DelAddressOnConsumer } } - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - bz, err := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, + binaryName := tr.chainConfigs[chain].BinaryName + cmd := tr.target.ExecCommand(binaryName, + + "query", "bank", "balances", + valDelAddress, + + `--node`, tr.GetQueryNode(chain), + `-o`, `json`, + ) + bz, err := cmd.CombinedOutput() + if err != nil { + log.Fatal("getBalance() failed: ", cmd, ": ", err, "\n", string(bz)) + } + + amount := gjson.Get(string(bz), `balances.#(denom=="stake").amount`) + + return uint(amount.Uint()) +} + +func (tr Commands) GetValStakedTokens(chain ChainID, valoperAddress string) uint { + binaryName := tr.chainConfigs[chain].BinaryName + bz, err := tr.target.ExecCommand(binaryName, "query", "staking", "validator", valoperAddress, - `--node`, tr.getQueryNode(chain), + `--node`, tr.GetQueryNode(chain), `-o`, `json`, ).CombinedOutput() if err != nil { @@ -614,15 +615,14 @@ func (tr TestConfig) getValStakedTokens(chain ChainID, validator ValidatorID) ui return uint(amount.Uint()) } -func (tr TestConfig) getParam(chain ChainID, param Param) string { - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - bz, err := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, - +func (tr Commands) GetParam(chain ChainID, param Param) string { + binaryName := tr.chainConfigs[chain].BinaryName + bz, err := tr.target.ExecCommand(binaryName, "query", "params", "subspace", param.Subspace, param.Key, - `--node`, tr.getQueryNode(chain), + `--node`, tr.GetQueryNode(chain), `-o`, `json`, ).CombinedOutput() if err != nil { @@ -634,11 +634,11 @@ func (tr TestConfig) getParam(chain ChainID, param Param) string { return value.String() } -func (tr TestConfig) getIBCTransferParams(chain ChainID) IBCTransferParams { - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - bz, err := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, +func (tr Commands) GetIBCTransferParams(chain ChainID) IBCTransferParams { + binaryName := tr.chainConfigs[chain].BinaryName + bz, err := tr.target.ExecCommand(binaryName, "query", "ibc-transfer", "params", - `--node`, tr.getQueryNode(chain), + `--node`, tr.GetQueryNode(chain), `-o`, `json`, ).CombinedOutput() if err != nil { @@ -653,14 +653,14 @@ func (tr TestConfig) getIBCTransferParams(chain ChainID) IBCTransferParams { return params } -// getConsumerChains returns a list of consumer chains that're being secured by the provider chain, +// GetConsumerChains returns a list of consumer chains that're being secured by the provider chain, // determined by querying the provider chain. -func (tr TestConfig) getConsumerChains(chain ChainID) map[ChainID]bool { - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, +func (tr Commands) GetConsumerChains(chain ChainID) map[ChainID]bool { + binaryName := tr.chainConfigs[chain].BinaryName + cmd := tr.target.ExecCommand(binaryName, "query", "provider", "list-consumer-chains", - `--node`, tr.getQueryNode(chain), + `--node`, tr.GetQueryNode(chain), `-o`, `json`, ) @@ -679,31 +679,13 @@ func (tr TestConfig) getConsumerChains(chain ChainID) map[ChainID]bool { return chains } -func (tr TestConfig) getConsumerAddresses(chain ChainID, modelState map[ValidatorID]string) map[ValidatorID]string { - actualState := map[ValidatorID]string{} - for k := range modelState { - actualState[k] = tr.getConsumerAddress(chain, k) - } - - return actualState -} - -func (tr TestConfig) getProviderAddresses(chain ChainID, modelState map[ValidatorID]string) map[ValidatorID]string { - actualState := map[ValidatorID]string{} - for k := range modelState { - actualState[k] = tr.getProviderAddressFromConsumer(chain, k) - } - - return actualState -} - -func (tr TestConfig) getConsumerAddress(consumerChain ChainID, validator ValidatorID) string { - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[ChainID("provi")].BinaryName, +func (tr Commands) GetConsumerAddress(consumerChain ChainID, validator ValidatorID) string { + binaryName := tr.chainConfigs[ChainID("provi")].BinaryName + cmd := tr.target.ExecCommand(binaryName, "query", "provider", "validator-consumer-key", string(consumerChain), tr.validatorConfigs[validator].ValconsAddress, - `--node`, tr.getQueryNode(ChainID("provi")), + `--node`, tr.GetQueryNode(ChainID("provi")), `-o`, `json`, ) bz, err := cmd.CombinedOutput() @@ -715,13 +697,13 @@ func (tr TestConfig) getConsumerAddress(consumerChain ChainID, validator Validat return addr } -func (tr TestConfig) getProviderAddressFromConsumer(consumerChain ChainID, validator ValidatorID) string { - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[ChainID("provi")].BinaryName, +func (tr Commands) GetProviderAddressFromConsumer(consumerChain ChainID, validator ValidatorID) string { + binaryName := tr.chainConfigs[ChainID("provi")].BinaryName + cmd := tr.target.ExecCommand(binaryName, "query", "provider", "validator-provider-key", string(consumerChain), tr.validatorConfigs[validator].ConsumerValconsAddressOnProvider, - `--node`, tr.getQueryNode(ChainID("provi")), + `--node`, tr.GetQueryNode(ChainID("provi")), `-o`, `json`, ) @@ -735,13 +717,12 @@ func (tr TestConfig) getProviderAddressFromConsumer(consumerChain ChainID, valid return addr } -func (tr TestConfig) getSlashMeter() int64 { - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - cmd := exec.Command("docker", "exec", - tr.containerConfig.InstanceName, tr.chainConfigs[ChainID("provi")].BinaryName, +func (tr Commands) GetSlashMeter() int64 { + binaryName := tr.chainConfigs[ChainID("provi")].BinaryName + cmd := tr.target.ExecCommand(binaryName, "query", "provider", "throttle-state", - `--node`, tr.getQueryNode(ChainID("provi")), + `--node`, tr.GetQueryNode(ChainID("provi")), `-o`, `json`, ) bz, err := cmd.CombinedOutput() @@ -753,12 +734,12 @@ func (tr TestConfig) getSlashMeter() int64 { return slashMeter.Int() } -func (tr TestConfig) getRegisteredConsumerRewardDenoms(chain ChainID) []string { - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, +func (tr Commands) GetRegisteredConsumerRewardDenoms(chain ChainID) []string { + binaryName := tr.chainConfigs[chain].BinaryName + cmd := tr.target.ExecCommand(binaryName, "query", "provider", "registered-consumer-reward-denoms", - `--node`, tr.getQueryNode(chain), + `--node`, tr.GetQueryNode(chain), `-o`, `json`, ) bz, err := cmd.CombinedOutput() @@ -775,12 +756,12 @@ func (tr TestConfig) getRegisteredConsumerRewardDenoms(chain ChainID) []string { return rewardDenoms } -func (tr TestConfig) getPendingPacketQueueSize(chain ChainID) uint { - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, +func (tr Commands) GetPendingPacketQueueSize(chain ChainID) uint { + binaryName := tr.chainConfigs[chain].BinaryName + cmd := tr.target.ExecCommand(binaryName, "query", "ccvconsumer", "throttle-state", - `--node`, tr.getQueryNode(chain), + `--node`, tr.GetQueryNode(chain), `-o`, `json`, ) bz, err := cmd.CombinedOutput() @@ -796,62 +777,13 @@ func (tr TestConfig) getPendingPacketQueueSize(chain ChainID) uint { return uint(len(packetData)) } -func (tr TestConfig) getValidatorNode(chain ChainID, validator ValidatorID) string { - // for CometMock, validatorNodes are all the same address as the query node (which is CometMocks address) - if tr.useCometmock { - return tr.getQueryNode(chain) - } - - return "tcp://" + tr.getValidatorIP(chain, validator) + ":26658" -} - -func (tr TestConfig) getValidatorIP(chain ChainID, validator ValidatorID) string { - return tr.chainConfigs[chain].IpPrefix + "." + tr.validatorConfigs[validator].IpSuffix -} - -func (tr TestConfig) getValidatorHome(chain ChainID, validator ValidatorID) string { - return `/` + string(tr.chainConfigs[chain].ChainId) + `/validator` + fmt.Sprint(validator) -} - -// getQueryNode returns query node tcp address on chain. -func (tr TestConfig) getQueryNode(chain ChainID) string { - return fmt.Sprintf("tcp://%s", tr.getQueryNodeRPCAddress(chain)) -} - -func (tr TestConfig) getQueryNodeRPCAddress(chain ChainID) string { - return fmt.Sprintf("%s:26658", tr.getQueryNodeIP(chain)) -} - -// getQueryNodeIP returns query node IP for chain, -// ipSuffix is hardcoded to be 253 on all query nodes -// except for "sover" chain where there's only one node -func (tr TestConfig) getQueryNodeIP(chain ChainID) string { - if chain == ChainID("sover") { - // return address of first and only validator - return fmt.Sprintf("%s.%s", - tr.chainConfigs[chain].IpPrefix, - tr.validatorConfigs[ValidatorID("alice")].IpSuffix) - } - return fmt.Sprintf("%s.253", tr.chainConfigs[chain].IpPrefix) -} - -func (tr TestConfig) curlJsonRPCRequest(method, params, address string) { - cmd_template := `curl -H 'Content-Type: application/json' -H 'Accept:application/json' --data '{"jsonrpc":"2.0","method":"%s","params":%s,"id":1}' %s` - - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, "bash", "-c", fmt.Sprintf(cmd_template, method, params, address)) - - verbosity := false - executeCommandWithVerbosity(cmd, "curlJsonRPCRequest", verbosity) -} - -// getClientFrozenHeight returns the frozen height for a client with the given client ID +// GetClientFrozenHeight returns the frozen height for a client with the given client ID // by querying the hosting chain with the given chainID -func (tc TestConfig) getClientFrozenHeight(chain ChainID, clientID string) clienttypes.Height { - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - cmd := exec.Command("docker", "exec", tc.containerConfig.InstanceName, tc.chainConfigs[ChainID("provi")].BinaryName, +func (tr Commands) GetClientFrozenHeight(chain ChainID, clientID string) (uint64, uint64) { + binaryName := tr.chainConfigs[ChainID("provi")].BinaryName + cmd := tr.target.ExecCommand(binaryName, "query", "ibc", "client", "state", clientID, - `--node`, tc.getQueryNode(ChainID("provi")), + `--node`, tr.GetQueryNode(ChainID("provi")), `-o`, `json`, ) @@ -872,16 +804,15 @@ func (tc TestConfig) getClientFrozenHeight(chain ChainID, clientID string) clien log.Fatal(err, "\n", string(bz)) } - return clienttypes.Height{RevisionHeight: uint64(revHeight), RevisionNumber: uint64(revNumber)} + return uint64(revHeight), uint64(revNumber) } -func (tc TestConfig) getTrustedHeight( +func (tr Commands) GetTrustedHeight( chain ChainID, clientID string, index int, -) clienttypes.Height { - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - configureNodeCmd := exec.Command("docker", "exec", tc.containerConfig.InstanceName, "hermes", +) (uint64, uint64) { + configureNodeCmd := tr.target.ExecCommand("hermes", "--json", "query", "client", "consensus", "--chain", string(chain), `--client`, clientID, ) @@ -919,15 +850,14 @@ func (tc TestConfig) getTrustedHeight( if err != nil { log.Fatal(err) } - return clienttypes.Height{RevisionHeight: uint64(revHeight), RevisionNumber: uint64(revNumber)} + return uint64(revHeight), uint64(revNumber) } -func (tr TestConfig) getProposedConsumerChains(chain ChainID) []string { - 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, +func (tr Commands) GetProposedConsumerChains(chain ChainID) []string { + binaryName := tr.chainConfigs[chain].BinaryName + bz, err := tr.target.ExecCommand(binaryName, "query", "provider", "list-proposed-consumer-chains", - `--node`, tr.getQueryNode(chain), + `--node`, tr.GetQueryNode(chain), `-o`, `json`, ).CombinedOutput() if err != nil { @@ -944,6 +874,24 @@ func (tr TestConfig) getProposedConsumerChains(chain ChainID) []string { return chains } -func uintPtr(i uint) *uint { - return &i +// getQueryNode returns query node tcp address on chain. +func (tr Commands) GetQueryNode(chain ChainID) string { + return fmt.Sprintf("tcp://%s", tr.GetQueryNodeRPCAddress(chain)) +} + +func (tr Commands) GetQueryNodeRPCAddress(chain ChainID) string { + return fmt.Sprintf("%s:26658", tr.GetQueryNodeIP(chain)) +} + +// getQueryNodeIP returns query node IP for chain, +// ipSuffix is hardcoded to be 253 on all query nodes +// except for "sover" chain where there's only one node +func (tr Commands) GetQueryNodeIP(chain ChainID) string { + if chain == ChainID("sover") { + // return address of first and only validator + return fmt.Sprintf("%s.%s", + tr.chainConfigs[chain].IpPrefix, + tr.validatorConfigs[ValidatorID("alice")].IpSuffix) + } + return fmt.Sprintf("%s.253", tr.chainConfigs[chain].IpPrefix) } diff --git a/tests/e2e/steps_compatibility.go b/tests/e2e/steps_compatibility.go index a3d639267e..3eaf1eae9c 100644 --- a/tests/e2e/steps_compatibility.go +++ b/tests/e2e/steps_compatibility.go @@ -57,7 +57,7 @@ func compstepsStartConsumerChain(consumerName string, proposalIndex, chainIndex Chain: ChainID(consumerName), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, - Status: "PROPOSAL_STATUS_VOTING_PERIOD", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), // breaking change in SDK: gov.ProposalStatus(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD).String(), }, }, // not supported across major versions @@ -138,7 +138,7 @@ func compstepsStartConsumerChain(consumerName string, proposalIndex, chainIndex Chain: ChainID(consumerName), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, - Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), //TODO: CHECK if this is bug on SDK SIDE!!!: should be as before gov.ProposalStatus(gov.ProposalStatus_PROPOSAL_STATUS_PASSED).String(), }, }, ValBalances: &map[ValidatorID]uint{ diff --git a/tests/e2e/test_driver.go b/tests/e2e/test_driver.go index 0ca3bc29ed..a4c2424ff5 100644 --- a/tests/e2e/test_driver.go +++ b/tests/e2e/test_driver.go @@ -5,7 +5,9 @@ import ( "log" "reflect" + v4 "github.com/cosmos/interchain-security/v5/tests/e2e/v4" "github.com/kylelemons/godebug/pretty" + "golang.org/x/mod/semver" ) // TestCaseDriver knows how different TC can be executed @@ -47,7 +49,7 @@ func (td *DefaultDriver) runStep(step Step) error { return err } modelState := step.State - actualState := td.testCfg.getState(modelState, td.verbose) + actualState := td.getState(modelState) // Check state if !reflect.DeepEqual(actualState, modelState) { @@ -60,84 +62,145 @@ func (td *DefaultDriver) runStep(step Step) error { return nil } +func (td *DefaultDriver) getIcsVersion(chainID ChainID) string { + version := "" + if td.testCfg.chainConfigs[chainID].BinaryName == "interchain-security-pd" { + version = td.testCfg.providerVersion + } else { + version = td.testCfg.consumerVersion + } + ics := getIcsVersion(version) + if !semver.IsValid(ics) { + return "" + } else { + return semver.Major(ics) + } +} + +func (td *DefaultDriver) getTargetDriver(chainID ChainID) Chain { + target := Chain{ + testConfig: td.testCfg, + } + icsVersion := td.getIcsVersion(chainID) + switch icsVersion { + case "v4": + if td.verbose { + fmt.Println("Using 'v4' driver for chain ", chainID) + } + target.target = v4.Commands{ + ContainerConfig: td.testCfg.containerConfig, + ValidatorConfigs: td.testCfg.validatorConfigs, + ChainConfigs: td.testCfg.chainConfigs, + Target: td.target, + } + default: + target.target = Commands{ + containerConfig: td.testCfg.containerConfig, + validatorConfigs: td.testCfg.validatorConfigs, + chainConfigs: td.testCfg.chainConfigs, + target: td.target, + } + if td.verbose { + fmt.Println("Using default driver ", icsVersion, " for chain ", chainID) + } + } + + return target +} + +func (td *DefaultDriver) getState(modelState State) State { + systemState := State{} + for chainID, modelState := range modelState { + target := td.getTargetDriver(chainID) + + if td.verbose { + fmt.Println("Getting model state for chain: ", chainID) + } + systemState[chainID] = target.GetChainState(chainID, modelState) + } + + return systemState +} + func (td *DefaultDriver) runAction(action interface{}) error { + target := td.getTargetDriver("") switch action := action.(type) { case StartChainAction: - td.testCfg.startChain(action, td.target, td.verbose) + target.startChain(action, td.verbose) case StartSovereignChainAction: - td.testCfg.startSovereignChain(action, td.target, td.verbose) + target.startSovereignChain(action, td.verbose) case LegacyUpgradeProposalAction: - td.testCfg.submitLegacyUpgradeProposal(action, td.target, td.verbose) + target.submitLegacyUpgradeProposal(action, td.verbose) case WaitUntilBlockAction: - td.testCfg.waitUntilBlockOnChain(action) + target.waitUntilBlockOnChain(action) case ChangeoverChainAction: - td.testCfg.changeoverChain(action, td.target, td.verbose) + target.changeoverChain(action, td.verbose) case SendTokensAction: - td.testCfg.sendTokens(action, td.target, td.verbose) + target.sendTokens(action, td.verbose) case SubmitTextProposalAction: - td.testCfg.submitTextProposal(action, td.target, td.verbose) + target.submitTextProposal(action, td.verbose) case SubmitConsumerAdditionProposalAction: - td.testCfg.submitConsumerAdditionProposal(action, td.target, td.verbose) + target.submitConsumerAdditionProposal(action, td.verbose) case SubmitConsumerRemovalProposalAction: - td.testCfg.submitConsumerRemovalProposal(action, td.target, td.verbose) + target.submitConsumerRemovalProposal(action, td.verbose) case SubmitEnableTransfersProposalAction: - td.testCfg.submitEnableTransfersProposalAction(action, td.target, td.verbose) + target.submitEnableTransfersProposalAction(action, td.verbose) case VoteGovProposalAction: - td.testCfg.voteGovProposal(action, td.target, td.verbose) + target.voteGovProposal(action, td.verbose) case StartConsumerChainAction: - td.testCfg.startConsumerChain(action, td.target, td.verbose) + target.startConsumerChain(action, td.verbose) case AddChainToRelayerAction: - td.testCfg.addChainToRelayer(action, td.target, td.verbose) + target.addChainToRelayer(action, td.verbose) case CreateIbcClientsAction: - td.testCfg.createIbcClientsHermes(action, td.target, td.verbose) + target.createIbcClientsHermes(action, td.verbose) case AddIbcConnectionAction: - td.testCfg.addIbcConnection(action, td.target, td.verbose) + target.addIbcConnection(action, td.verbose) case AddIbcChannelAction: - td.testCfg.addIbcChannel(action, td.target, td.verbose) + target.addIbcChannel(action, td.verbose) case TransferChannelCompleteAction: - td.testCfg.transferChannelComplete(action, td.target, td.verbose) + target.transferChannelComplete(action, td.verbose) case RelayPacketsAction: - td.testCfg.relayPackets(action, td.target, td.verbose) + target.relayPackets(action, td.verbose) case RelayRewardPacketsToProviderAction: - td.testCfg.relayRewardPacketsToProvider(action, td.target, td.verbose) + target.relayRewardPacketsToProvider(action, td.verbose) case DelegateTokensAction: - td.testCfg.delegateTokens(action, td.target, td.verbose) + target.delegateTokens(action, td.verbose) case UnbondTokensAction: - td.testCfg.unbondTokens(action, td.target, td.verbose) + target.unbondTokens(action, td.verbose) case CancelUnbondTokensAction: - td.testCfg.cancelUnbondTokens(action, td.target, td.verbose) + target.cancelUnbondTokens(action, td.verbose) case RedelegateTokensAction: - td.testCfg.redelegateTokens(action, td.target, td.verbose) + target.redelegateTokens(action, td.verbose) case DowntimeSlashAction: - td.testCfg.invokeDowntimeSlash(action, td.target, td.verbose) + target.invokeDowntimeSlash(action, td.verbose) case UnjailValidatorAction: - td.testCfg.unjailValidator(action, td.target, td.verbose) + target.unjailValidator(action, td.verbose) case DoublesignSlashAction: - td.testCfg.invokeDoublesignSlash(action, td.target, td.verbose) + target.invokeDoublesignSlash(action, td.verbose) case LightClientAmnesiaAttackAction: - td.testCfg.lightClientAmnesiaAttack(action, td.verbose) + target.lightClientAmnesiaAttack(action, td.verbose) case LightClientEquivocationAttackAction: - td.testCfg.lightClientEquivocationAttack(action, td.verbose) + target.lightClientEquivocationAttack(action, td.verbose) case LightClientLunaticAttackAction: - td.testCfg.lightClientLunaticAttack(action, td.verbose) + target.lightClientLunaticAttack(action, td.verbose) case RegisterRepresentativeAction: - td.testCfg.registerRepresentative(action, td.target, td.verbose) + target.registerRepresentative(action, td.verbose) case AssignConsumerPubKeyAction: - td.testCfg.assignConsumerPubKey(action, td.target, td.verbose) + target.assignConsumerPubKey(action, td.verbose) case SlashMeterReplenishmentAction: - td.testCfg.waitForSlashMeterReplenishment(action, td.verbose) + target.waitForSlashMeterReplenishment(action, td.verbose) case WaitTimeAction: - td.testCfg.waitForTime(action, td.verbose) + target.waitForTime(action, td.verbose) case StartRelayerAction: - td.testCfg.startRelayer(action, td.target, td.verbose) + target.startRelayer(action, td.verbose) case ForkConsumerChainAction: - td.testCfg.forkConsumerChain(action, td.verbose) + target.forkConsumerChain(action, td.verbose) case UpdateLightClientAction: - td.testCfg.updateLightClient(action, td.verbose) + target.updateLightClient(action, td.verbose) case StartConsumerEvidenceDetectorAction: - td.testCfg.startConsumerEvidenceDetector(action, td.target, td.verbose) + target.startConsumerEvidenceDetector(action, td.verbose) case SubmitChangeRewardDenomsProposalAction: - td.testCfg.submitChangeRewardDenomsProposal(action, td.target, td.verbose) + target.submitChangeRewardDenomsProposal(action, td.verbose) default: log.Fatalf("unknown action in testRun %s: %#v", td.testCfg.name, action) } diff --git a/tests/e2e/test_target.go b/tests/e2e/test_target.go index 421be1d1fa..140ed565e6 100644 --- a/tests/e2e/test_target.go +++ b/tests/e2e/test_target.go @@ -24,7 +24,13 @@ type ExecutionTarget interface { Delete() error Info() string } - +type TargetConfig struct { + gaiaTag string + localSdkPath string + useGaia bool + providerVersion string + consumerVersion string +} type DockerContainer struct { targetConfig TargetConfig containerCfg ContainerConfig diff --git a/tests/e2e/testlib/types.go b/tests/e2e/testlib/types.go new file mode 100644 index 0000000000..dd600bb624 --- /dev/null +++ b/tests/e2e/testlib/types.go @@ -0,0 +1,339 @@ +package e2e + +import ( + "encoding/json" + "fmt" + "os/exec" + "reflect" + "time" + + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" +) + +type ( + ChainID string + ValidatorID string +) + +type ChainCommands interface { + GetBlockHeight(chain ChainID) uint + GetBalance(chain ChainID, validator ValidatorID) uint + GetConsumerChains(chain ChainID) map[ChainID]bool + GetConsumerAddress(consumerChain ChainID, validator ValidatorID) string + GetClientFrozenHeight(chain ChainID, clientID string) (RevisionNumber, RevisionHeight uint64) + GetIBCTransferParams(chain ChainID) IBCTransferParams + GetProposal(chain ChainID, proposal uint) Proposal + GetParam(chain ChainID, param Param) string + GetProviderAddressFromConsumer(consumerChain ChainID, validator ValidatorID) string + GetReward(chain ChainID, validator ValidatorID, blockHeight uint, isNativeDenom bool) float64 + GetRegisteredConsumerRewardDenoms(chain ChainID) []string + GetSlashMeter() int64 + GetPendingPacketQueueSize(chain ChainID) uint + GetProposedConsumerChains(chain ChainID) []string + GetQueryNode(chain ChainID) string + GetQueryNodeRPCAddress(chain ChainID) string + GetTrustedHeight(chain ChainID, clientID string, index int) (uint64, uint64) + GetValPower(chain ChainID, validator ValidatorID) uint + GetValStakedTokens(chain ChainID, validatorAddress string) uint + GetQueryNodeIP(chain ChainID) string +} + +// TODO: replace ExecutionTarget with new TargetDriver interface +type PlatformDriver interface { + ExecCommand(name string, arg ...string) *exec.Cmd + // ExecDetachedCommand: when executed the command will be run in the background and call will return immediately + ExecDetachedCommand(name string, args ...string) *exec.Cmd + GetTestScriptPath(isConsumer bool, script string) string +} +type TargetDriver interface { + // ChainCommands + ChainCommands + PlatformDriver +} + +// TODO: this should not be here. mv 'Now' to a better suited type here and then move ContainerConfig back +type ContainerConfig struct { + ContainerName string + InstanceName string + CcvVersion string + Now time.Time +} + +// Attributes that are unique to a validator. Allows us to map (part of) +// the set of strings defined above to a set of viable validators +type ValidatorConfig struct { + // Seed phrase to generate a secp256k1 key used by the validator on the provider + Mnemonic string + // Validator account address on provider marshaled to string using Bech32 + // with Bech32Prefix = ProviderAccountPrefix + DelAddress string + // Validator account address on provider marshaled to string using Bech32 + // with Bech32Prefix = ConsumerAccountPrefix + DelAddressOnConsumer string + // Validator operator address on provider marshaled to string using Bech32 + // with Bech32Prefix = ProviderAccountPrefix + ValoperAddress string + // Validator operator address on provider marshaled to string using Bech32 + // with Bech32Prefix = ConsumerAccountPrefix + ValoperAddressOnConsumer string + // Validator consensus address on provider marshaled to string using Bech32 + // with Bech32Prefix = ProviderAccountPrefix. It matches the PrivValidatorKey below. + ValconsAddress string + // Validator consensus address on provider marshaled to string using Bech32 + // with Bech32Prefix = ConsumerAccountPrefix. + ValconsAddressOnConsumer string + // Key used for consensus on provider + PrivValidatorKey string + NodeKey string + // Must be an integer greater than 0 and less than 253 + IpSuffix string + + // consumer chain key assignment data + // keys are used on a new node + + // Seed phrase to generate a secp256k1 key used by the validator on the consumer + ConsumerMnemonic string + // Validator account address on consumer marshaled to string using Bech32 + // with Bech32Prefix = ConsumerAccountPrefix + ConsumerDelAddress string + // Validator account address on consumer marshaled to string using Bech32 + // with Bech32Prefix = ProviderAccountPrefix + ConsumerDelAddressOnProvider string + // Validator operator address on consumer marshaled to string using Bech32 + // with Bech32Prefix = ConsumerAccountPrefix + ConsumerValoperAddress string + // Validator operator address on consumer marshaled to string using Bech32 + // with Bech32Prefix = ProviderAccountPrefix + ConsumerValoperAddressOnProvider string + // Validator consensus address on consumer marshaled to string using Bech32 + // with Bech32Prefix = ConsumerAccountPrefix. It matches the PrivValidatorKey below. + ConsumerValconsAddress string + // Validator consensus address on consumer marshaled to string using Bech32 + // with Bech32Prefix = ProviderAccountPrefix. + ConsumerValconsAddressOnProvider string + ConsumerValPubKey string + // Key used for consensus on consumer + ConsumerPrivValidatorKey string + ConsumerNodeKey string + UseConsumerKey bool // if true the validator node will start with consumer key +} + +// Attributes that are unique to a chain. Allows us to map (part of) +// the set of strings defined above to a set of viable chains +type ChainConfig struct { + ChainId ChainID + // The account prefix configured on the chain. For example, on the Hub, this is "cosmos" + AccountPrefix string + // Must be unique per chain + IpPrefix string + VotingWaitTime uint + // Any transformations to apply to the genesis file of all chains instantiated with this chain config, as a jq string. + // Example: ".app_state.gov.params.voting_period = \"5s\" | .app_state.slashing.params.signed_blocks_window = \"2\" | .app_state.slashing.params.min_signed_per_window = \"0.500000000000000000\"" + GenesisChanges string + BinaryName string + + // binary to use after upgrade height + UpgradeBinary string +} + +type ( + // to have a ChainState object that does not have the overridden Marshal/Unmarshal method + ChainStateCopy ChainState + + // duplicated from the ChainState with a minor change to the Proposals field + ChainStateWithProposalTypes struct { + ChainStateCopy + Proposals *map[uint]ProposalAndType // the only thing changed from the real ChainState + } +) + +// stores a proposal as a raw json, together with its type +type ProposalAndType struct { + RawProposal json.RawMessage + Type string +} + +type ChainState struct { + ValBalances *map[ValidatorID]uint + Proposals *map[uint]Proposal + ProposedConsumerChains *[]string + ValPowers *map[ValidatorID]uint + StakedTokens *map[ValidatorID]uint + IBCTransferParams *IBCTransferParams + Params *[]Param + Rewards *Rewards + ConsumerChains *map[ChainID]bool + AssignedKeys *map[ValidatorID]string + ProviderKeys *map[ValidatorID]string // validatorID: validator provider key + ConsumerPendingPacketQueueSize *uint // Only relevant to consumer chains + RegisteredConsumerRewardDenoms *[]string + ClientsFrozenHeights *map[string]clienttypes.Height +} + +// custom marshal and unmarshal functions for the chainstate that convert proposals to/from the auxiliary type with type info + +// MarshalJSON transforms the ChainState into a ChainStateWithProposalTypes by adding type info to the proposals +func (c ChainState) MarshalJSON() ([]byte, error) { + chainStateCopy := ChainStateCopy(c) + chainStateWithProposalTypes := ChainStateWithProposalTypes{chainStateCopy, nil} + if c.Proposals != nil { + proposalsWithTypes := make(map[uint]ProposalAndType) + for k, v := range *c.Proposals { + rawMessage, err := json.Marshal(v) + if err != nil { + return nil, err + } + proposalsWithTypes[k] = ProposalAndType{rawMessage, reflect.TypeOf(v).String()} + } + chainStateWithProposalTypes.Proposals = &proposalsWithTypes + } + return json.Marshal(chainStateWithProposalTypes) +} + +// UnmarshalJSON unmarshals the ChainStateWithProposalTypes into a ChainState by removing the type info from the proposals and getting back standard proposals +func (c *ChainState) UnmarshalJSON(data []byte) error { + chainStateWithProposalTypes := ChainStateWithProposalTypes{} + err := json.Unmarshal(data, &chainStateWithProposalTypes) + if err != nil { + return err + } + + chainState := ChainState(chainStateWithProposalTypes.ChainStateCopy) + *c = chainState + + if chainStateWithProposalTypes.Proposals != nil { + proposals := make(map[uint]Proposal) + for k, v := range *chainStateWithProposalTypes.Proposals { + proposal, err := UnmarshalProposalWithType(v.RawProposal, v.Type) + if err != nil { + return err + } + proposals[k] = proposal + } + c.Proposals = &proposals + } + return nil +} + +// UnmarshalProposalWithType takes a JSON object and a proposal type and marshals into an object of the corresponding proposal. +func UnmarshalProposalWithType(inputMap json.RawMessage, proposalType string) (Proposal, error) { + var err error + switch proposalType { + case "main.TextProposal": + prop := TextProposal{} + err := json.Unmarshal(inputMap, &prop) + if err == nil { + return prop, nil + } + case "main.ConsumerAdditionProposal": + prop := ConsumerAdditionProposal{} + err := json.Unmarshal(inputMap, &prop) + if err == nil { + return prop, nil + } + case "main.UpgradeProposal": + prop := UpgradeProposal{} + err := json.Unmarshal(inputMap, &prop) + if err == nil { + return prop, nil + } + case "main.ConsumerRemovalProposal": + prop := ConsumerRemovalProposal{} + err := json.Unmarshal(inputMap, &prop) + if err == nil { + return prop, nil + } + case "main.IBCTransferParamsProposal": + prop := IBCTransferParamsProposal{} + err := json.Unmarshal(inputMap, &prop) + if err == nil { + return prop, nil + } + default: + return nil, fmt.Errorf("%s is not a known proposal type", proposalType) + } + + return nil, err +} + +type Proposal interface { + isProposal() +} +type TextProposal struct { + Title string + Description string + Deposit uint + Status string +} + +func (p TextProposal) isProposal() {} + +type IBCTransferParamsProposal struct { + Title string + Deposit uint + Status string + Params IBCTransferParams +} + +func (ibct IBCTransferParamsProposal) isProposal() {} + +type ConsumerAdditionProposal struct { + Deposit uint + Chain ChainID + SpawnTime int + InitialHeight clienttypes.Height + Status string +} + +type UpgradeProposal struct { + Title string + Description string + UpgradeHeight uint64 + Type string + Deposit uint + Status string +} + +func (p UpgradeProposal) isProposal() {} + +func (p ConsumerAdditionProposal) isProposal() {} + +type ConsumerRemovalProposal struct { + Deposit uint + Chain ChainID + StopTime int + Status string +} + +func (p ConsumerRemovalProposal) isProposal() {} + +type Rewards struct { + IsRewarded map[ValidatorID]bool + // if true it will calculate if the validator/delegator is rewarded between 2 successive blocks, + // otherwise it will calculate if it received any rewards since the 1st block + IsIncrementalReward bool + // if true checks rewards for "stake" token, otherwise checks rewards from + // other chains (e.g. false is used to check if provider received rewards from a consumer chain) + IsNativeDenom bool +} + +type ParamsProposal struct { + Deposit uint + Status string + Subspace string + Key string + Value string +} + +func (p ParamsProposal) isProposal() {} + +type Param struct { + Subspace string + Key string + Value string +} + +type IBCTransferParams struct { + SendEnabled bool `json:"send_enabled"` + ReceiveEnabled bool `json:"receive_enabled"` +} diff --git a/tests/e2e/testlib/utils.go b/tests/e2e/testlib/utils.go new file mode 100644 index 0000000000..8b68c25947 --- /dev/null +++ b/tests/e2e/testlib/utils.go @@ -0,0 +1,43 @@ +package e2e + +import ( + "bufio" + "fmt" + "log" + "os/exec" +) + +var verbose *bool //TODO: remove hack + +func ExecuteCommandWithVerbosity(cmd *exec.Cmd, cmdName string, verbose bool) { + if verbose { + fmt.Println(cmdName+" cmd:", cmd.String()) + } + + cmdReader, err := cmd.StdoutPipe() + if err != nil { + log.Fatal(err) + } + cmd.Stderr = cmd.Stdout + + if err := cmd.Start(); err != nil { + log.Fatal(err) + } + + scanner := bufio.NewScanner(cmdReader) + + for scanner.Scan() { + out := scanner.Text() + if verbose { + fmt.Println(cmdName + ": " + out) + } + } + if err := scanner.Err(); err != nil { + log.Fatal(err) + } +} + +// Executes a command with verbosity specified by CLI flag +func ExecuteCommand(cmd *exec.Cmd, cmdName string) { + ExecuteCommandWithVerbosity(cmd, cmdName, *verbose) +} diff --git a/tests/e2e/v4/state.go b/tests/e2e/v4/state.go new file mode 100644 index 0000000000..9ee3c7ec97 --- /dev/null +++ b/tests/e2e/v4/state.go @@ -0,0 +1,654 @@ +package v4 + +import ( + "bufio" + "fmt" + "log" + "os/exec" + "regexp" + "strconv" + "time" + + gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + e2e "github.com/cosmos/interchain-security/v5/tests/e2e/testlib" + "gopkg.in/yaml.v2" + + "github.com/kylelemons/godebug/pretty" + "github.com/tidwall/gjson" +) + +type ( + ChainID = e2e.ChainID + ValidatorID = e2e.ValidatorID + ChainState = e2e.ChainState + Proposal = e2e.Proposal + Rewards = e2e.Rewards + TextProposal = e2e.TextProposal + UpgradeProposal = e2e.UpgradeProposal + ConsumerAdditionProposal = e2e.ConsumerAdditionProposal + ConsumerRemovalProposal = e2e.ConsumerRemovalProposal + IBCTransferParams = e2e.IBCTransferParams + IBCTransferParamsProposal = e2e.IBCTransferParamsProposal + Param = e2e.Param + ParamsProposal = e2e.ParamsProposal + ValidatorConfig = e2e.ValidatorConfig + ChainConfig = e2e.ChainConfig + ContainerConfig = e2e.ContainerConfig + TargetDriver = e2e.TargetDriver +) + +type State map[ChainID]ChainState + +type Commands struct { + ContainerConfig ContainerConfig // FIXME only needed for 'Now' time tracking + ValidatorConfigs map[ValidatorID]ValidatorConfig + ChainConfigs map[ChainID]ChainConfig + Target e2e.PlatformDriver +} + +func (tr Commands) ExecCommand(name string, arg ...string) *exec.Cmd { + return tr.Target.ExecCommand(name, arg...) +} + +func (tr Commands) ExecDetachedCommand(name string, args ...string) *exec.Cmd { + return tr.Target.ExecDetachedCommand(name, args...) +} + +func (tr Commands) GetTestScriptPath(isConsumer bool, script string) string { + return tr.Target.GetTestScriptPath(isConsumer, script) +} + +func (tr Commands) GetBlockHeight(chain ChainID) uint { + binaryName := tr.ChainConfigs[chain].BinaryName + bz, err := tr.Target.ExecCommand(binaryName, + + "query", "tendermint-validator-set", + + `--node`, tr.GetQueryNode(chain), + ).CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + blockHeightRegex := regexp.MustCompile(`block_height: "(\d+)"`) + blockHeight, err := strconv.Atoi(blockHeightRegex.FindStringSubmatch(string(bz))[1]) + if err != nil { + log.Fatal(err) + } + + return uint(blockHeight) +} + +func (tr Commands) waitUntilBlock(chain ChainID, block uint, timeout time.Duration) { + start := time.Now() + for { + thisBlock := tr.GetBlockHeight(chain) + if thisBlock >= block { + return + } + if time.Since(start) > timeout { + panic(fmt.Sprintf("\n\n\nwaitBlocks method has timed out after: %s\n\n", timeout)) + } + time.Sleep(500 * time.Millisecond) + } +} + +type ValPubKey struct { + Value string `yaml:"value"` +} + +type TmValidatorSetYaml struct { + Total string `yaml:"total"` + Validators []struct { + Address string `yaml:"address"` + VotingPower string `yaml:"voting_power"` + PubKey ValPubKey `yaml:"pub_key"` + } +} + +func (tr Commands) GetValPower(chain ChainID, validator ValidatorID) uint { + /* if *verbose { + log.Println("getting validator power for chain: ", chain, " validator: ", validator) + } + */ + binaryName := tr.ChainConfigs[chain].BinaryName + command := tr.Target.ExecCommand(binaryName, + + "query", "tendermint-validator-set", + + `--node`, tr.GetQueryNode(chain), + ) + bz, err := command.CombinedOutput() + if err != nil { + log.Fatalf("encountered an error when executing command '%s': %v, output: %s", command.String(), err, string(bz)) + } + + valset := TmValidatorSetYaml{} + err = yaml.Unmarshal(bz, &valset) + if err != nil { + log.Fatalf("yaml.Unmarshal returned an error while unmarshalling validator set: %v, input: %s", err, string(bz)) + } + + total, err := strconv.Atoi(valset.Total) + if err != nil { + log.Fatalf("v4: strconv.Atoi returned an error while converting total for validator set: %v, input: %s, validator set: %s, src: %s", + err, valset.Total, pretty.Sprint(valset), string(bz)) + } + + if total != len(valset.Validators) { + log.Fatalf("Total number of validators %v does not match number of validators in list %v. Probably a query pagination issue. Validator set: %v", + valset.Total, uint(len(valset.Validators)), pretty.Sprint(valset)) + } + + for _, val := range valset.Validators { + if chain == ChainID("provi") { + // use binary with Bech32Prefix set to ProviderAccountPrefix + if val.Address != tr.ValidatorConfigs[validator].ValconsAddress { + continue + } + } else { + // use binary with Bech32Prefix set to ConsumerAccountPrefix + if val.Address != tr.ValidatorConfigs[validator].ValconsAddressOnConsumer && + val.Address != tr.ValidatorConfigs[validator].ConsumerValconsAddress { + continue + } + } + + votingPower, err := strconv.Atoi(val.VotingPower) + if err != nil { + log.Fatalf("strconv.Atoi returned an error while converting validator voting power: %v, voting power string: %s, validator set: %s", err, val.VotingPower, pretty.Sprint(valset)) + } + + return uint(votingPower) + } + + // Validator not in set, its validator power is zero. + return 0 +} + +func (tr Commands) GetReward(chain ChainID, validator ValidatorID, blockHeight uint, isNativeDenom bool) float64 { + valCfg := tr.ValidatorConfigs[validator] + delAddresss := valCfg.DelAddress + if chain != ChainID("provi") { + // use binary with Bech32Prefix set to ConsumerAccountPrefix + if valCfg.UseConsumerKey { + delAddresss = valCfg.ConsumerDelAddress + } else { + // use the same address as on the provider but with different prefix + delAddresss = valCfg.DelAddressOnConsumer + } + } + + binaryName := tr.ChainConfigs[chain].BinaryName + bz, err := tr.Target.ExecCommand(binaryName, + + "query", "distribution", "rewards", + delAddresss, + + `--height`, fmt.Sprint(blockHeight), + `--node`, tr.GetQueryNode(chain), + `-o`, `json`, + ).CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + denomCondition := `total.#(denom!="stake").amount` + if isNativeDenom { + denomCondition = `total.#(denom=="stake").amount` + } + + return gjson.Get(string(bz), denomCondition).Float() +} + +func (tr Commands) GetBalance(chain ChainID, validator ValidatorID) uint { + valCfg := tr.ValidatorConfigs[validator] + valDelAddress := valCfg.DelAddress + if chain != ChainID("provi") { + // use binary with Bech32Prefix set to ConsumerAccountPrefix + if valCfg.UseConsumerKey { + valDelAddress = valCfg.ConsumerDelAddress + } else { + // use the same address as on the provider but with different prefix + valDelAddress = valCfg.DelAddressOnConsumer + } + } + + binaryName := tr.ChainConfigs[chain].BinaryName + cmd := tr.Target.ExecCommand(binaryName, + + "query", "bank", "balances", + valDelAddress, + + `--node`, tr.GetQueryNode(chain), + `-o`, `json`, + ) + bz, err := cmd.CombinedOutput() + if err != nil { + log.Fatal("getBalance() failed: ", cmd, ": ", err, "\n", string(bz)) + } + + amount := gjson.Get(string(bz), `balances.#(denom=="stake").amount`) + + return uint(amount.Uint()) +} + +// interchain-securityd query gov proposals +func (tr Commands) GetProposal(chain ChainID, proposal uint) Proposal { + var noProposalRegex = regexp.MustCompile(`doesn't exist: key not found`) + + binaryName := tr.ChainConfigs[chain].BinaryName + bz, err := tr.Target.ExecCommand(binaryName, + + "query", "gov", "proposal", + fmt.Sprint(proposal), + + `--node`, tr.GetQueryNode(chain), + `-o`, `json`, + ).CombinedOutput() + + prop := TextProposal{} + + if err != nil { + if noProposalRegex.Match(bz) { + return prop + } + + log.Fatal(err, "\n", string(bz)) + } + + propType := gjson.Get(string(bz), `messages.0.content.@type`).String() + deposit := gjson.Get(string(bz), `total_deposit.#(denom=="stake").amount`).Uint() + status := gjson.Get(string(bz), `status`).String() + + // This is a breaking change in the query output for proposals: bug in SDK?? + proposal_value, exists := gov.ProposalStatus_value[status] + if !exists { + panic("invalid proposal status value: " + status) + } + status = strconv.Itoa(int(proposal_value)) + + chainConfigs := tr.ChainConfigs + containerConfig := tr.ContainerConfig + + switch propType { + case "/cosmos.gov.v1beta1.TextProposal": + title := gjson.Get(string(bz), `content.title`).String() + description := gjson.Get(string(bz), `content.description`).String() + + return TextProposal{ + Deposit: uint(deposit), + Status: status, + Title: title, + Description: description, + } + case "/interchain_security.ccv.provider.v1.ConsumerAdditionProposal": + chainId := gjson.Get(string(bz), `messages.0.content.chain_id`).String() + spawnTime := gjson.Get(string(bz), `messages.0.content.spawn_time`).Time().Sub(containerConfig.Now) + + var chain ChainID + for i, conf := range chainConfigs { + if string(conf.ChainId) == chainId { + chain = i + break + } + } + + return ConsumerAdditionProposal{ + Deposit: uint(deposit), + Status: status, + Chain: chain, + SpawnTime: int(spawnTime.Milliseconds()), + InitialHeight: clienttypes.Height{ + RevisionNumber: gjson.Get(string(bz), `messages.0.content.initial_height.revision_number`).Uint(), + RevisionHeight: gjson.Get(string(bz), `messages.0.content.initial_height.revision_height`).Uint(), + }, + } + case "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal": + height := gjson.Get(string(bz), `messages.0.content.plan.height`).Uint() + title := gjson.Get(string(bz), `messages.0.content.plan.name`).String() + return UpgradeProposal{ + Deposit: uint(deposit), + Status: status, + UpgradeHeight: height, + Title: title, + Type: "/cosmos.upgrade.v1beta1.SoftwareUpgradeProposal", + } + case "/interchain_security.ccv.provider.v1.ConsumerRemovalProposal": + chainId := gjson.Get(string(bz), `messages.0.content.chain_id`).String() + stopTime := gjson.Get(string(bz), `messages.0.content.stop_time`).Time().Sub(containerConfig.Now) + + var chain ChainID + for i, conf := range chainConfigs { + if string(conf.ChainId) == chainId { + chain = i + break + } + } + + return ConsumerRemovalProposal{ + Deposit: uint(deposit), + Status: status, + Chain: chain, + StopTime: int(stopTime.Milliseconds()), + } + case "/cosmos.params.v1beta1.ParameterChangeProposal": + return ParamsProposal{ + Deposit: uint(deposit), + Status: status, + Subspace: gjson.Get(string(bz), `messages.0.content.changes.0.subspace`).String(), + Key: gjson.Get(string(bz), `messages.0.content.changes.0.key`).String(), + Value: gjson.Get(string(bz), `messages.0.content.changes.0.value`).String(), + } + } + + log.Fatal("unknown proposal type", string(bz)) + + return nil +} + +func (tr Commands) GetValStakedTokens(chain ChainID, valoperAddress string) uint { + binaryName := tr.ChainConfigs[chain].BinaryName + bz, err := tr.Target.ExecCommand(binaryName, + + "query", "staking", "validator", + valoperAddress, + + `--node`, tr.GetQueryNode(chain), + `-o`, `json`, + ).CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + amount := gjson.Get(string(bz), `tokens`) + + return uint(amount.Uint()) +} + +func (tr Commands) GetParam(chain ChainID, param Param) string { + binaryName := tr.ChainConfigs[chain].BinaryName + bz, err := tr.Target.ExecCommand(binaryName, + "query", "params", "subspace", + param.Subspace, + param.Key, + + `--node`, tr.GetQueryNode(chain), + `-o`, `json`, + ).CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + value := gjson.Get(string(bz), `value`) + + return value.String() +} + +// GetConsumerChains returns a list of consumer chains that're being secured by the provider chain, +// determined by querying the provider chain. +func (tr Commands) GetConsumerChains(chain ChainID) map[ChainID]bool { + binaryName := tr.ChainConfigs[chain].BinaryName + cmd := tr.Target.ExecCommand(binaryName, + + "query", "provider", "list-consumer-chains", + `--node`, tr.GetQueryNode(chain), + `-o`, `json`, + ) + + bz, err := cmd.CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + arr := gjson.Get(string(bz), "chains").Array() + chains := make(map[ChainID]bool) + for _, c := range arr { + id := c.Get("chain_id").String() + chains[ChainID(id)] = true + } + + return chains +} +func (tr Commands) GetConsumerAddress(consumerChain ChainID, validator ValidatorID) string { + binaryName := tr.ChainConfigs[ChainID("provi")].BinaryName + cmd := tr.Target.ExecCommand(binaryName, + + "query", "provider", "validator-consumer-key", + string(consumerChain), tr.ValidatorConfigs[validator].ValconsAddress, + `--node`, tr.GetQueryNode(ChainID("provi")), + `-o`, `json`, + ) + bz, err := cmd.CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + addr := gjson.Get(string(bz), "consumer_address").String() + return addr +} + +func (tr Commands) GetProviderAddressFromConsumer(consumerChain ChainID, validator ValidatorID) string { + binaryName := tr.ChainConfigs[ChainID("provi")].BinaryName + cmd := tr.Target.ExecCommand(binaryName, + + "query", "provider", "validator-provider-key", + string(consumerChain), tr.ValidatorConfigs[validator].ConsumerValconsAddressOnProvider, + `--node`, tr.GetQueryNode(ChainID("provi")), + `-o`, `json`, + ) + + bz, err := cmd.CombinedOutput() + if err != nil { + log.Println("error running ", cmd) + log.Fatal(err, "\n", string(bz)) + } + + addr := gjson.Get(string(bz), "provider_address").String() + return addr +} + +func (tr Commands) GetSlashMeter() int64 { + binaryName := tr.ChainConfigs[ChainID("provi")].BinaryName + cmd := tr.Target.ExecCommand(binaryName, + + "query", "provider", "throttle-state", + `--node`, tr.GetQueryNode(ChainID("provi")), + `-o`, `json`, + ) + bz, err := cmd.CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + slashMeter := gjson.Get(string(bz), "slash_meter") + return slashMeter.Int() +} + +func (tr Commands) GetRegisteredConsumerRewardDenoms(chain ChainID) []string { + binaryName := tr.ChainConfigs[chain].BinaryName + cmd := tr.Target.ExecCommand(binaryName, + "query", "provider", "registered-consumer-reward-denoms", + `--node`, tr.GetQueryNode(chain), + `-o`, `json`, + ) + bz, err := cmd.CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + denoms := gjson.Get(string(bz), "denoms").Array() + rewardDenoms := make([]string, len(denoms)) + for i, d := range denoms { + rewardDenoms[i] = d.String() + } + + return rewardDenoms +} + +func (tr Commands) GetPendingPacketQueueSize(chain ChainID) uint { + binaryName := tr.ChainConfigs[chain].BinaryName + cmd := tr.Target.ExecCommand(binaryName, + "query", "ccvconsumer", "throttle-state", + `--node`, tr.GetQueryNode(chain), + `-o`, `json`, + ) + bz, err := cmd.CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + if !gjson.ValidBytes(bz) { + panic("invalid json response from query ccvconsumer throttle-state: " + string(bz)) + } + + packetData := gjson.Get(string(bz), "packet_data_queue").Array() + return uint(len(packetData)) +} + +func (tr Commands) GetValidatorIP(chain ChainID, validator ValidatorID) string { + return tr.ChainConfigs[chain].IpPrefix + "." + tr.ValidatorConfigs[validator].IpSuffix +} + +// getQueryNode returns query node tcp address on chain. +func (tr Commands) GetQueryNode(chain ChainID) string { + return fmt.Sprintf("tcp://%s", tr.GetQueryNodeRPCAddress(chain)) +} + +func (tr Commands) GetQueryNodeRPCAddress(chain ChainID) string { + return fmt.Sprintf("%s:26658", tr.GetQueryNodeIP(chain)) +} + +// getQueryNodeIP returns query node IP for chain, +// ipSuffix is hardcoded to be 253 on all query nodes +// except for "sover" chain where there's only one node +func (tr Commands) GetQueryNodeIP(chain ChainID) string { + if chain == ChainID("sover") { + // return address of first and only validator + return fmt.Sprintf("%s.%s", + tr.ChainConfigs[chain].IpPrefix, + tr.ValidatorConfigs[ValidatorID("alice")].IpSuffix) + } + return fmt.Sprintf("%s.253", tr.ChainConfigs[chain].IpPrefix) +} + +func (tr Commands) curlJsonRPCRequest(method, params, address string) { + cmd_template := `curl -H 'Content-Type: application/json' -H 'Accept:application/json' --data '{"jsonrpc":"2.0","method":"%s","params":%s,"id":1}' %s` + cmd := tr.Target.ExecCommand("bash", "-c", fmt.Sprintf(cmd_template, method, params, address)) + + verbosity := false + e2e.ExecuteCommandWithVerbosity(cmd, "curlJsonRPCRequest", verbosity) +} + +// GetClientFrozenHeight returns the frozen height for a client with the given client ID +// by querying the hosting chain with the given chainID +func (tr Commands) GetClientFrozenHeight(chain ChainID, clientID string) (uint64, uint64) { + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + //cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[ChainID("provi")].BinaryName, + binaryName := tr.ChainConfigs[ChainID("provi")].BinaryName + cmd := tr.Target.ExecCommand(binaryName, + "query", "ibc", "client", "state", clientID, + `--node`, tr.GetQueryNode(ChainID("provi")), + `-o`, `json`, + ) + + bz, err := cmd.CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + frozenHeight := gjson.Get(string(bz), "client_state.frozen_height") + + revHeight, err := strconv.Atoi(frozenHeight.Get("revision_height").String()) + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + revNumber, err := strconv.Atoi(frozenHeight.Get("revision_number").String()) + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + return uint64(revHeight), uint64(revNumber) +} + +func (tr Commands) GetTrustedHeight( + chain ChainID, + clientID string, + index int, +) (uint64, uint64) { + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + //configureNodeCmd := exec.Command("docker", "exec", tc.testConfig.containerConfig.InstanceName, "hermes", + configureNodeCmd := tr.Target.ExecCommand("hermes", + "--json", "query", "client", "consensus", "--chain", string(chain), + `--client`, clientID, + ) + + cmdReader, err := configureNodeCmd.StdoutPipe() + if err != nil { + log.Fatal(err) + } + + configureNodeCmd.Stderr = configureNodeCmd.Stdout + + if err := configureNodeCmd.Start(); err != nil { + log.Fatal(err) + } + + scanner := bufio.NewScanner(cmdReader) + + var trustedHeight gjson.Result + // iterate on the relayer's response + // and parse the the command "result" + for scanner.Scan() { + out := scanner.Text() + if len(gjson.Get(out, "result").Array()) > 0 { + trustedHeight = gjson.Get(out, "result").Array()[index] + break + } + } + + revHeight, err := strconv.Atoi(trustedHeight.Get("revision_height").String()) + if err != nil { + log.Fatal(err) + } + + revNumber, err := strconv.Atoi(trustedHeight.Get("revision_number").String()) + if err != nil { + log.Fatal(err) + } + return uint64(revHeight), uint64(revNumber) +} + +func (tr Commands) GetProposedConsumerChains(chain ChainID) []string { + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + //bz, err := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, + binaryName := tr.ChainConfigs[chain].BinaryName + bz, err := tr.Target.ExecCommand(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 +} + +// Breaking forward compatibility +func (tr Commands) GetIBCTransferParams(chain ChainID) IBCTransferParams { + panic("'GetIBCTransferParams' is not implemented in this version") +} + +func uintPtr(i uint) *uint { + return &i +} From 0a466e737fe6783c15e36e8eba204a53c379446b Mon Sep 17 00:00:00 2001 From: MSalopek Date: Thu, 9 May 2024 15:04:51 +0200 Subject: [PATCH 17/35] chore: add v5 changelogs (#1872) * chore: add v5 changelogs * rm old changelogs --- .changelog/epilogue.md | 198 +----------------- .changelog/unreleased/.gitkeep | 0 .../consumer/1146-pending-packets.md | 2 - .../consumer/1150-revert-wire-breaking.md | 2 - .../consumer/1244-validate-transfer.md | 2 - .../bug-fixes/consumer/1262-fee-pool-addr.md | 2 - .../bug-fixes/consumer/1295-migration.md | 2 - .../v3.2.0/dependencies/1196-bump-ibc.md | 3 - .../v3.2.0/dependencies/1258-bump-ibc.md | 3 - .../v3.2.0/dependencies/1258-bump-sdk.md | 3 - .../v3.2.0/dependencies/1259-bump-sdk.md | 3 - .../consumer/1024-jail-throttling-v2.md | 2 - .../consumer/1164-provider-info-query.md | 4 - .../provider/1076-export-timestamps.md | 2 - .../features/provider/1280-reward-denoms.md | 3 - .../improvements/1244-consumer-unbonding.md | 2 - .../consumer/1037-optimize-storage.md | 2 - .../v3.2.0/state-breaking/1196-bump-ibc.md | 3 - .../state-breaking/1244-consumer-unbonding.md | 2 - .../v3.2.0/state-breaking/1258-bump-ibc.md | 3 - .../v3.2.0/state-breaking/1258-bump-sdk.md | 3 - .../v3.2.0/state-breaking/1259-bump-sdk.md | 3 - .../consumer/1024-jail-throttling-v2.md | 2 - .../consumer/1037-optimize-storage.md | 2 - .../consumer/1146-pending-packets.md | 2 - .../consumer/1150-revert-wire-breaking.md | 2 - .../consumer/1244-validate-transfer.md | 2 - .../consumer/1262-fee-pool-addr.md | 2 - .../state-breaking/consumer/1295-migration.md | 2 - .../provider/1280-reward-denoms.md | 3 - .changelog/v3.2.0/summary.md | 1 - ...ic-verification-of-equivocation-feature.md | 2 - .../v3.3.0/dependencies/1373-bump-ibc.md | 3 - .../v3.3.0/features/1336-quint-model.md | 2 - .../1339-check-key-assignment-in-use.md | 3 - ...1340-cryptographic-equivocation-feature.md | 4 - .../improvements/1324-consumer-genesis.md | 16 -- .../v3.3.0/improvements/1350-cleanup-types.md | 3 - .../provider/1503-query-key-assignment.md | 1 - .../state-breaking/1324-consumer-genesis.md | 2 - .../state-breaking/1460-msg-validation.md | 3 - .../1339-check-key-assignment-in-use.md | 3 - ...1340-cryptographic-equivocation-feature.md | 4 - .changelog/v3.3.0/summary.md | 1 - .../consumer/1458-consumer-genesis-cli-fix.md | 2 - .../1458-consumer-genesis-cli-fix.md | 2 - .../v4.0.0/bug-fixes/1460-msg-validation.md | 3 - .../bug-fixes/consumer/1549-soft-opt-out.md | 3 - .../consumer/1570-slashack-bech32.md | 2 - .../v4.0.0/dependencies/1557-bump-go.md | 2 - .../v4.0.0/dependencies/1558-bump-comet.md | 3 - .../v4.0.0/dependencies/1558-bump-sdk.md | 3 - .../provider/1321-jail-throttling-v2.md | 2 - .../consumer/1549-soft-opt-out.md | 3 - .../consumer/1570-slashack-bech32.md | 2 - .../provider/1321-jail-throttling-v2.md | 2 - .changelog/v4.0.0/summary.md | 1 - .../v4.1.0/dependencies/1663-bump-sdk.md | 3 - .../v4.1.0/dependencies/1764-bump-ibc.md | 3 - .../provider/1516-introduce-epochs.md | 3 - .../1740-oldest-unconfirm-vsc-query.md | 4 - .../1445-query-provider-parameters.md | 2 - .../v4.1.0/state-breaking/1764-bump-ibc.md | 3 - .../provider/1516-introduce-epochs.md | 3 - .changelog/v4.1.0/summary.md | 1 - .../provider/1722-query-valcons-format.md | 2 - .changelog/v4.1.1/summary.md | 1 - .../v5.0.0/dependencies/1698-bump-comet.md | 3 + .../v5.0.0/dependencies/1698-bump-ibc.md | 3 + .../v5.0.0/dependencies/1698-bump-sdk.md | 3 + .../1814-add-update-consumer-params-msg.md | 2 + .../1698-add-update-provider-params-msg.md | 2 + .../v5.0.0/state-breaking/1698-bump-comet.md | 3 + .../v5.0.0/state-breaking/1698-bump-ibc.md | 3 + .../v5.0.0/state-breaking/1698-bump-sdk.md | 3 + .../1819-revert-put-unbonding-on-hold.md | 2 + .changelog/v5.0.0/summary.md | 2 + CHANGELOG.md | 39 ++++ 78 files changed, 67 insertions(+), 367 deletions(-) create mode 100644 .changelog/unreleased/.gitkeep delete mode 100644 .changelog/v3.2.0/bug-fixes/consumer/1146-pending-packets.md delete mode 100644 .changelog/v3.2.0/bug-fixes/consumer/1150-revert-wire-breaking.md delete mode 100644 .changelog/v3.2.0/bug-fixes/consumer/1244-validate-transfer.md delete mode 100644 .changelog/v3.2.0/bug-fixes/consumer/1262-fee-pool-addr.md delete mode 100644 .changelog/v3.2.0/bug-fixes/consumer/1295-migration.md delete mode 100644 .changelog/v3.2.0/dependencies/1196-bump-ibc.md delete mode 100644 .changelog/v3.2.0/dependencies/1258-bump-ibc.md delete mode 100644 .changelog/v3.2.0/dependencies/1258-bump-sdk.md delete mode 100644 .changelog/v3.2.0/dependencies/1259-bump-sdk.md delete mode 100644 .changelog/v3.2.0/features/consumer/1024-jail-throttling-v2.md delete mode 100644 .changelog/v3.2.0/features/consumer/1164-provider-info-query.md delete mode 100644 .changelog/v3.2.0/features/provider/1076-export-timestamps.md delete mode 100644 .changelog/v3.2.0/features/provider/1280-reward-denoms.md delete mode 100644 .changelog/v3.2.0/improvements/1244-consumer-unbonding.md delete mode 100644 .changelog/v3.2.0/improvements/consumer/1037-optimize-storage.md delete mode 100644 .changelog/v3.2.0/state-breaking/1196-bump-ibc.md delete mode 100644 .changelog/v3.2.0/state-breaking/1244-consumer-unbonding.md delete mode 100644 .changelog/v3.2.0/state-breaking/1258-bump-ibc.md delete mode 100644 .changelog/v3.2.0/state-breaking/1258-bump-sdk.md delete mode 100644 .changelog/v3.2.0/state-breaking/1259-bump-sdk.md delete mode 100644 .changelog/v3.2.0/state-breaking/consumer/1024-jail-throttling-v2.md delete mode 100644 .changelog/v3.2.0/state-breaking/consumer/1037-optimize-storage.md delete mode 100644 .changelog/v3.2.0/state-breaking/consumer/1146-pending-packets.md delete mode 100644 .changelog/v3.2.0/state-breaking/consumer/1150-revert-wire-breaking.md delete mode 100644 .changelog/v3.2.0/state-breaking/consumer/1244-validate-transfer.md delete mode 100644 .changelog/v3.2.0/state-breaking/consumer/1262-fee-pool-addr.md delete mode 100644 .changelog/v3.2.0/state-breaking/consumer/1295-migration.md delete mode 100644 .changelog/v3.2.0/state-breaking/provider/1280-reward-denoms.md delete mode 100644 .changelog/v3.2.0/summary.md delete mode 100644 .changelog/v3.3.0/api-breaking/provider/1340-add-cryptographic-verification-of-equivocation-feature.md delete mode 100644 .changelog/v3.3.0/dependencies/1373-bump-ibc.md delete mode 100644 .changelog/v3.3.0/features/1336-quint-model.md delete mode 100644 .changelog/v3.3.0/features/provider/1339-check-key-assignment-in-use.md delete mode 100644 .changelog/v3.3.0/features/provider/1340-cryptographic-equivocation-feature.md delete mode 100644 .changelog/v3.3.0/improvements/1324-consumer-genesis.md delete mode 100644 .changelog/v3.3.0/improvements/1350-cleanup-types.md delete mode 100644 .changelog/v3.3.0/improvements/provider/1503-query-key-assignment.md delete mode 100644 .changelog/v3.3.0/state-breaking/1324-consumer-genesis.md delete mode 100644 .changelog/v3.3.0/state-breaking/1460-msg-validation.md delete mode 100644 .changelog/v3.3.0/state-breaking/provider/1339-check-key-assignment-in-use.md delete mode 100644 .changelog/v3.3.0/state-breaking/provider/1340-cryptographic-equivocation-feature.md delete mode 100644 .changelog/v3.3.0/summary.md delete mode 100644 .changelog/v4.0.0/api-breaking/consumer/1458-consumer-genesis-cli-fix.md delete mode 100644 .changelog/v4.0.0/bug-fixes/1458-consumer-genesis-cli-fix.md delete mode 100644 .changelog/v4.0.0/bug-fixes/1460-msg-validation.md delete mode 100644 .changelog/v4.0.0/bug-fixes/consumer/1549-soft-opt-out.md delete mode 100644 .changelog/v4.0.0/bug-fixes/consumer/1570-slashack-bech32.md delete mode 100644 .changelog/v4.0.0/dependencies/1557-bump-go.md delete mode 100644 .changelog/v4.0.0/dependencies/1558-bump-comet.md delete mode 100644 .changelog/v4.0.0/dependencies/1558-bump-sdk.md delete mode 100644 .changelog/v4.0.0/features/provider/1321-jail-throttling-v2.md delete mode 100644 .changelog/v4.0.0/state-breaking/consumer/1549-soft-opt-out.md delete mode 100644 .changelog/v4.0.0/state-breaking/consumer/1570-slashack-bech32.md delete mode 100644 .changelog/v4.0.0/state-breaking/provider/1321-jail-throttling-v2.md delete mode 100644 .changelog/v4.0.0/summary.md delete mode 100644 .changelog/v4.1.0/dependencies/1663-bump-sdk.md delete mode 100644 .changelog/v4.1.0/dependencies/1764-bump-ibc.md delete mode 100644 .changelog/v4.1.0/features/provider/1516-introduce-epochs.md delete mode 100644 .changelog/v4.1.0/features/provider/1740-oldest-unconfirm-vsc-query.md delete mode 100644 .changelog/v4.1.0/improvements/provider/1445-query-provider-parameters.md delete mode 100644 .changelog/v4.1.0/state-breaking/1764-bump-ibc.md delete mode 100644 .changelog/v4.1.0/state-breaking/provider/1516-introduce-epochs.md delete mode 100644 .changelog/v4.1.0/summary.md delete mode 100644 .changelog/v4.1.1/bug-fixes/provider/1722-query-valcons-format.md delete mode 100644 .changelog/v4.1.1/summary.md create mode 100644 .changelog/v5.0.0/dependencies/1698-bump-comet.md create mode 100644 .changelog/v5.0.0/dependencies/1698-bump-ibc.md create mode 100644 .changelog/v5.0.0/dependencies/1698-bump-sdk.md create mode 100644 .changelog/v5.0.0/features/consumer/1814-add-update-consumer-params-msg.md create mode 100644 .changelog/v5.0.0/features/provider/1698-add-update-provider-params-msg.md create mode 100644 .changelog/v5.0.0/state-breaking/1698-bump-comet.md create mode 100644 .changelog/v5.0.0/state-breaking/1698-bump-ibc.md create mode 100644 .changelog/v5.0.0/state-breaking/1698-bump-sdk.md create mode 100644 .changelog/v5.0.0/state-breaking/1819-revert-put-unbonding-on-hold.md create mode 100644 .changelog/v5.0.0/summary.md diff --git a/.changelog/epilogue.md b/.changelog/epilogue.md index 88987ef0a0..3a080d16b9 100644 --- a/.changelog/epilogue.md +++ b/.changelog/epilogue.md @@ -1,197 +1,3 @@ -## v3.1.0 +## Previous Versions -Date July 11th, 2023 - -A minor upgrade to v3.0.0, which removes the panic in the consumer ccv module which would occur in an emergency scenario where the ccv channel is closed. This release also fixes how a distribution related event is emitted, and bumps cometbft. - -* (feat) [#1127](https://github.com/cosmos/interchain-security/pull/1127) Remove consumer panic when ccv channel is closed -* (fix) [#720](https://github.com/cosmos/interchain-security/issues/720) Fix the attribute `AttributeDistributionTotal` value in `FeeDistribution` event emit. -* (deps) [#1119](https://github.com/cosmos/interchain-security/pull/1119) bump cometbft from `v0.37.1` to `0.37.2`. - -## v3.0.0 - -Date: June 21st, 2023 - -Interchain Security v3 uses SDK 0.47 and IBC 7. - -* (fix) [#1093](https://github.com/cosmos/interchain-security/pull/1093) Make SlashPacketData backward compatible when sending data over the wire -* (deps) [#1019](https://github.com/cosmos/interchain-security/pull/1019) Bump multiple dependencies. - * Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to [v0.47.3](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.3). - * Bump [ibc-go](https://github.com/cosmos/ibc-go) to [v7.1.0](https://github.com/cosmos/ibc-go/releases/tag/v7.1.0). - * Bump [CometBFT](https://github.com/cometbft/cometbft) to [v0.37.1](https://github.com/cometbft/cometbft/releases/tag/v0.37.1). -* `[x/ccv/provider]` (fix) [#945](https://github.com/cosmos/interchain-security/issues/945) Refactor `AfterUnbondingInitiated` to not panic when `PutUnbondingOnHold` returns error. -* `[x/ccv/provider]` (fix) [#977](https://github.com/cosmos/interchain-security/pull/977) Avoids panicking the provider when an unbonding delegation was removed through a `CancelUnbondingDelegation` message. -* `[x/ccv/democracy]` (feat) [#1019](https://github.com/cosmos/interchain-security/pull/1019) Whitelisting non-legacy params in the "democracy module" require the entire module to be whitelisted. - -## v2.4.0-lsm - -*November 20, 2023* - -* (fix) [#1439](https://github.com/cosmos/interchain-security/pull/1439) Fix unmarshaling for the CLI consumer double vote cmd. -* (feat!) [#1435](https://github.com/cosmos/interchain-security/pull/1435) Add height-base filter for consumer equivocation evidence. - -## v2.3.0-provider-lsm - -*November 15, 2023* - -❗ *This release is deprecated and should not be used in production.* - -* (fix!) [#1422](https://github.com/cosmos/interchain-security/pull/1422) Fix the misbehaviour handling by verifying the signatures of byzantine validators. - -## v2.2.0-provider-lsm - -❗ *This release is deprecated and should not be used in production.* - -### Cryptographic verification of equivocation -* New feature enabling the provider chain to verify equivocation evidence on its own instead of trusting consumer chains, see [EPIC](https://github.com/cosmos/interchain-security/issues/732). - -## v2.1.0-provider-lsm - -Date: September 15th, 2023 - -* (feature!) [#1280](https://github.com/cosmos/interchain-security/pull/1280) provider proposal for changing reward denoms - -## v2.0.0-lsm - -Date: August 18th, 2023 - -* (deps!) [#1120](https://github.com/cosmos/interchain-security/pull/1120) Bump [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) to [v0.45.16-ics-lsm](https://github.com/cosmos/cosmos-sdk/tree/v0.45.16-ics-lsm). This requires adapting ICS to support this SDK release. Changes are state breaking. -* (fix) [#720](https://github.com/cosmos/interchain-security/issues/720) Fix the attribute `AttributeDistributionTotal` value in `FeeDistribution` event emit. - -## v2.0.0 - -Date: June 1st, 2023 - -Unlike prior releases, the ICS `v2.0.0` release will be based on the main branch. `v2.0.0` will contain all the accumulated PRs from the various releases below, along with other PRs that were merged, but not released to production. After `v2.0.0`, we plan to revamp release practices, and how we modularize the repo for consumer/provider. - -Upgrading a provider from `v1.1.0-multiden` to `v2.0.0` will require state migrations. See [migration.go](https://github.com/cosmos/interchain-security/blob/v2.0.0/x/ccv/provider/keeper/migration.go). - -Upgrading a consumer from `v1.2.0-multiden` to `v2.0.0` will NOT require state migrations. - -Some PRs from v2.0.0 may reappear from other releases below. This is due to the fact that ICS v1.1.0 deviates from the commit ordering of the main branch, and other releases thereafter are based on v1.1.0. - -### High level changes included in v2.0.0 - -* MVP for standalone to consumer changeover, see [EPIC](https://github.com/cosmos/interchain-security/issues/756) -* MVP for soft opt out, see [EPIC](https://github.com/cosmos/interchain-security/issues/851) -* Various fixes, critical and non-critical -* Docs updates which should not affect production code - -## Notable PRs included in v2.0.0 - -* (feat!) Add DistributionTransmissionChannel to ConsumerAdditionProposal [#965](https://github.com/cosmos/interchain-security/pull/965) -* (feat/fix) limit vsc matured packets handled per endblocker [#1004](https://github.com/cosmos/interchain-security/pull/1004) -* (fix) consumer key prefix order to avoid complex migrations [#963](https://github.com/cosmos/interchain-security/pull/963) and [#991](https://github.com/cosmos/interchain-security/pull/991). The latter PR is the proper fix. -* (feat) v1->v2 migrations to accommodate a bugfix having to do with store keys, introduce new params, and deal with consumer genesis state schema changes [#975](https://github.com/cosmos/interchain-security/pull/975) and [#997](https://github.com/cosmos/interchain-security/pull/997) -* (deps) Bump github.com/cosmos/ibc-go/v4 from 4.4.0 to 4.4.2 [#982](https://github.com/cosmos/interchain-security/pull/982) -* (fix) partially revert key assignment type safety PR [#980](https://github.com/cosmos/interchain-security/pull/980) -* (fix) Remove panics on failure to send IBC packets [#876](https://github.com/cosmos/interchain-security/pull/876) -* (fix) Prevent denom DOS [#931](https://github.com/cosmos/interchain-security/pull/931) -* (fix) multisig for assigning consumer key, use json [#916](https://github.com/cosmos/interchain-security/pull/916) -* (deps) Bump github.com/cosmos/ibc-go/v4 from 4.3.0 to 4.4.0 [#902](https://github.com/cosmos/interchain-security/pull/902) -* (feat) Add warnings when provider unbonding is shorter than consumer unbonding [#858](https://github.com/cosmos/interchain-security/pull/858) -* (chore) use go 1.19 [#899](https://github.com/cosmos/interchain-security/pull/899), [#840](https://github.com/cosmos/interchain-security/pull/840) -* (feat) Standalone to consumer changeover - recycle existing transfer channel [#832](https://github.com/cosmos/interchain-security/pull/832) -* (deps) Bump IBC [862](https://github.com/cosmos/interchain-security/pull/862) -* (testing) Add tests for soft opt out [#857](https://github.com/cosmos/interchain-security/pull/857) -* (feat) Standalone to consumer changeover - staking functionalities [#794](https://github.com/cosmos/interchain-security/pull/794) -* (fix) prevent provider from sending VSCPackets with multiple updates for the same validator [#850](https://github.com/cosmos/interchain-security/pull/850) -* (feat) Soft opt out [#833](https://github.com/cosmos/interchain-security/issues/833) -* (fix) Correctly handle VSC packet with duplicate val updates on consumer [#846](https://github.com/cosmos/interchain-security/pull/846) -* (deps) bump sdk to v0.45.15.ics [#805](https://github.com/cosmos/interchain-security/pull/805) -* (refactor) Remove spm module [#812](https://github.com/cosmos/interchain-security/pull/812) -* (feat) Standalone to consumer changeover part 1 [#757](https://github.com/cosmos/interchain-security/pull/757) -* (chore) Swap names of e2e and integration tests [#681](https://github.com/cosmos/interchain-security/pull/681) -* (fix) fix StopConsumerChain not running in cachedContext [#802](https://github.com/cosmos/interchain-security/pull/802). Also in earlier releases with different commit order! -* (docs) Introduce docs website [#759](https://github.com/cosmos/interchain-security/pull/759) -* (fix) Serialize correct byte prefix for SlashLogKey [#786](https://github.com/cosmos/interchain-security/pull/786) -* (feature) Improve keeper field validation [#766](https://github.com/cosmos/interchain-security/pull/766) -* (docs) Contributing guidelines [#744](https://github.com/cosmos/interchain-security/pull/744) -* (refactor) Key assignment type safety [#725](https://github.com/cosmos/interchain-security/pull/725) -* (fix) Update protos and fix deps [#752](https://github.com/cosmos/interchain-security/pull/752) -* (api) Add consumer QueryParams [#746](https://github.com/cosmos/interchain-security/pull/746) -* (feature) New validation for keeper fields [#740](https://github.com/cosmos/interchain-security/pull/740) - -## v1.2.0-multiden - -The first release candidate for a fix built on top of v1.2.0, intended for consumers. This release adds a list of denoms on the consumer that are allowed to be sent to the provider as rewards. This prevents a potential DOS attack that was discovered during the audit of Replicated Security performed by Oak Security and funded by the Cosmos Hub community through Proposal 687. In an effort to move quickly, this release also includes a multisig fix that is effective only for provider. It shouldn't affect the consumer module. - -Note PRs were made in a private security repo. - -[full diff](https://github.com/cosmos/interchain-security/compare/v1.2.0...v1.2.0-multiden-rc0) - -## v1.1.0-multiden - -This release combines two fixes on top of v1.1.0, that we judged were urgent to get onto the Cosmos Hub before the launch of the first ICS consumer chain. This is an emergency release intended for providers. - -The first fix is to enable the use of multisigs and Ledger devices when assigning keys for consumer chains. The second is to prevent a possible DOS vector involving the reward distribution system. - -Note PRs were made in a private security repo. - -[full diff](https://github.com/cosmos/interchain-security/compare/v1.1.0...release/v1.1.0-multiden) - -### Multisig fix - -On April 25th (a week and a half ago), we began receiving reports that validators using multisigs and Ledger devices were getting errors reading Error: unable to resolve type URL /interchain_security.ccv.provider.v1.MsgAssignConsumerKey: tx parse error when attempting to assign consensus keys for consumer chains. - -We quickly narrowed the problem down to issues having to do with using the PubKey type directly in the MsgAssignConsumerKey transaction, and Amino (a deprecated serialization library still used in Ledger devices and multisigs) not being able to handle this. We attempted to fix this with the assistance of the Cosmos-SDK team, but after making no headway for a few days, we decided to simply use a JSON representation of the PubKey in the transaction. This is how it is usually represented anyway. We have verified that this fixes the problem. - -### Distribution fix - -The ICS distribution system works by allowing consumer chains to send rewards to a module address on the provider called the FeePoolAddress. From here they are automatically distributed to all validators and delegators through the distribution system that already exists to distribute staking rewards. The FeePoolAddress is usually blocked so that no tokens can be sent to it, but to enable ICS distribution we had to unblock it. - -We recently realized that unblocking the FeePoolAddress could enable an attacker to send a huge number of different denoms into the distribution system. The distribution system would then attempt to distribute them all, leading to out of memory errors. Fixing a similar attack vector that existed in the distribution system before ICS led us to this realization. - -To fix this problem, we have re-blocked the FeePoolAddress and created a new address called the ConsumerRewardsPool. Consumer chains now send rewards to this new address. There is also a new transaction type called RegisterConsumerRewardDenom. This transaction allows people to register denoms to be used as rewards from consumer chains. It costs 10 Atoms to run this transaction.The Atoms are transferred to the community pool. Only denoms registered with this command are then transferred to the FeePoolAddress and distributed out to delegators and validators. - -## v1.2.1 - -* (fix) Remove SPM [#812](https://github.com/cosmos/interchain-security/pull/812) -* (refactor) Key assignment type safety [#725](https://github.com/cosmos/interchain-security/pull/725) - -## v1.2.0 - -Date: April 13th, 2023 - -* (feat) Soft opt-out [#833](https://github.com/cosmos/interchain-security/pull/833) -* (fix) Correctly handle VSC packet with duplicate val updates on consumer [#846](https://github.com/cosmos/interchain-security/pull/846) -* (chore) bump: sdk v0.45.15-ics [#805](https://github.com/cosmos/interchain-security/pull/805) -* (api) add interchain security consumer QueryParams [#746](https://github.com/cosmos/interchain-security/pull/746) - -## v1.1.1 - -* (fix) Remove SPM [#812](https://github.com/cosmos/interchain-security/pull/812) -* (refactor) Key assignment type safety [#725](https://github.com/cosmos/interchain-security/pull/725) - -## v1.1.0 - -Date: March 24th, 2023 - -* (fix) StopConsumerChain not running in cachedContext [#802](https://github.com/cosmos/interchain-security/pull/802) - -## v1.0.0 - -Date: February 6th, 2023 - -This is the first version of Interchain Security (ICS), also known as _Replicated Security_ (RS). -Replicated Security is a feature which will allow a chain -- referred to as the _provider_ -- to share security with other chains -- referred to as _consumers_. -This means that the provider's validator set will be granted the right to validate consumer chains. -The communication between the provider and the consumer chains is done through the IBC protocol over a unique, ordered channel (one for each consumer chain). Thus, RS is an IBC application. - -### Features / sub-protocols - -RS consist of the following core features: - -- **Channel Initialization**: Enables the provider to add new consumer chains. This process is governance-gated, i.e., to add a new consumer chain, a `ConsumerAdditionProposal` governance proposal must be sent to the provider and it must receive the necessary votes. -- **Validator Set Update**: Enables the provider to - (1) update the consumers on the voting power granted to validators (based on the changes in the active validator set on the provider chain), - and (2) ensure the timely completion of unbonding operations (e.g., undelegations). -- **Consumer Initiated Slashing**: Enables the provider to jail validators for downtime infractions on the consumer chains. -- **Reward Distribution**: Enables the consumers to transfer to the provider (over IBC) a portion of their block rewards as payment for the security provided. Once transferred, these rewards are distributed on the provider using the protocol in the [distribution module of Cosmos SDK](https://docs.cosmos.network/v0.45/modules/distribution/). -- **Consumer Chain Removal**: Enables the provider to remove a consumer either after a `ConsumerRemovalProposal` passes governance or after one of the timeout periods elapses -- `InitTimeoutPeriod`, `VscTimeoutPeriod`, `IBCTimeoutPeriod`. -- **Social Slashing**: Equivocation offenses (double signing etc.) on consumer chains are logged, and then can be used in a governance proposal to slash the validators responsible. - -In addition, RS has the following features: - -- **Key Assignment**: Enables validator operators to use different consensus keys for each consumer chain validator node that they operate. -- **Jail Throttling**: Enables the provider to slow down a "worst case scenario" attack where a malicious consumer binary attempts to jail a significant amount (> 2/3) of the voting power, effectively taking control of the provider. \ No newline at end of file +[CHANGELOG of previous versions](https://github.com/cosmos/interchain-security/blob/main/CHANGELOG.md) diff --git a/.changelog/unreleased/.gitkeep b/.changelog/unreleased/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.changelog/v3.2.0/bug-fixes/consumer/1146-pending-packets.md b/.changelog/v3.2.0/bug-fixes/consumer/1146-pending-packets.md deleted file mode 100644 index 0bab707fec..0000000000 --- a/.changelog/v3.2.0/bug-fixes/consumer/1146-pending-packets.md +++ /dev/null @@ -1,2 +0,0 @@ -- Fix deletion of pending packets that may cause duplicate sends - ([\#1146](https://github.com/cosmos/interchain-security/pull/1146)) \ No newline at end of file diff --git a/.changelog/v3.2.0/bug-fixes/consumer/1150-revert-wire-breaking.md b/.changelog/v3.2.0/bug-fixes/consumer/1150-revert-wire-breaking.md deleted file mode 100644 index 067448e770..0000000000 --- a/.changelog/v3.2.0/bug-fixes/consumer/1150-revert-wire-breaking.md +++ /dev/null @@ -1,2 +0,0 @@ -- Remove `idx` field from the `ccv.ConsumerPacketData` type as this would break the - wire ([\#1150](https://github.com/cosmos/interchain-security/pull/1150)) \ No newline at end of file diff --git a/.changelog/v3.2.0/bug-fixes/consumer/1244-validate-transfer.md b/.changelog/v3.2.0/bug-fixes/consumer/1244-validate-transfer.md deleted file mode 100644 index 2d94c79c75..0000000000 --- a/.changelog/v3.2.0/bug-fixes/consumer/1244-validate-transfer.md +++ /dev/null @@ -1,2 +0,0 @@ -- Validate token transfer messages before calling `Transfer()`. - ([\#1244](https://github.com/cosmos/interchain-security/pull/1244)) \ No newline at end of file diff --git a/.changelog/v3.2.0/bug-fixes/consumer/1262-fee-pool-addr.md b/.changelog/v3.2.0/bug-fixes/consumer/1262-fee-pool-addr.md deleted file mode 100644 index bbb54db2e3..0000000000 --- a/.changelog/v3.2.0/bug-fixes/consumer/1262-fee-pool-addr.md +++ /dev/null @@ -1,2 +0,0 @@ -- Remove incorrect address validation on `ProviderFeePoolAddrStr` param. - ([\#1262](https://github.com/cosmos/interchain-security/pull/1262)) \ No newline at end of file diff --git a/.changelog/v3.2.0/bug-fixes/consumer/1295-migration.md b/.changelog/v3.2.0/bug-fixes/consumer/1295-migration.md deleted file mode 100644 index 739b08dc39..0000000000 --- a/.changelog/v3.2.0/bug-fixes/consumer/1295-migration.md +++ /dev/null @@ -1,2 +0,0 @@ -- Increment consumer consensus version and register consumer migration. - ([\#1295](https://github.com/cosmos/interchain-security/pull/1295)) \ No newline at end of file diff --git a/.changelog/v3.2.0/dependencies/1196-bump-ibc.md b/.changelog/v3.2.0/dependencies/1196-bump-ibc.md deleted file mode 100644 index fcf4450150..0000000000 --- a/.changelog/v3.2.0/dependencies/1196-bump-ibc.md +++ /dev/null @@ -1,3 +0,0 @@ -- Bump [ibc-go](https://github.com/cosmos/ibc-go) to - [v7.2.0](https://github.com/cosmos/ibc-go/releases/tag/v7.2.0). - ([\#1196](https://github.com/cosmos/interchain-security/pull/1196)) \ No newline at end of file diff --git a/.changelog/v3.2.0/dependencies/1258-bump-ibc.md b/.changelog/v3.2.0/dependencies/1258-bump-ibc.md deleted file mode 100644 index 68c6e2b104..0000000000 --- a/.changelog/v3.2.0/dependencies/1258-bump-ibc.md +++ /dev/null @@ -1,3 +0,0 @@ -- Bump [ibc-go](https://github.com/cosmos/ibc-go) to - [v7.3.0](https://github.com/cosmos/ibc-go/releases/tag/v7.3.0). - ([\#1258](https://github.com/cosmos/interchain-security/pull/1258)) \ No newline at end of file diff --git a/.changelog/v3.2.0/dependencies/1258-bump-sdk.md b/.changelog/v3.2.0/dependencies/1258-bump-sdk.md deleted file mode 100644 index 7344fac97e..0000000000 --- a/.changelog/v3.2.0/dependencies/1258-bump-sdk.md +++ /dev/null @@ -1,3 +0,0 @@ -- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to - [v0.47.4](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.4). - ([\#1258](https://github.com/cosmos/interchain-security/pull/1258)) \ No newline at end of file diff --git a/.changelog/v3.2.0/dependencies/1259-bump-sdk.md b/.changelog/v3.2.0/dependencies/1259-bump-sdk.md deleted file mode 100644 index 247c623b7d..0000000000 --- a/.changelog/v3.2.0/dependencies/1259-bump-sdk.md +++ /dev/null @@ -1,3 +0,0 @@ -- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to - [v0.47.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.5). - ([\#1259](https://github.com/cosmos/interchain-security/pull/1259)) \ No newline at end of file diff --git a/.changelog/v3.2.0/features/consumer/1024-jail-throttling-v2.md b/.changelog/v3.2.0/features/consumer/1024-jail-throttling-v2.md deleted file mode 100644 index 7570facb34..0000000000 --- a/.changelog/v3.2.0/features/consumer/1024-jail-throttling-v2.md +++ /dev/null @@ -1,2 +0,0 @@ -- Add the consumer-side changes for jail throttling with retries (cf. ADR 008). - ([\#1024](https://github.com/cosmos/interchain-security/pull/1024)) \ No newline at end of file diff --git a/.changelog/v3.2.0/features/consumer/1164-provider-info-query.md b/.changelog/v3.2.0/features/consumer/1164-provider-info-query.md deleted file mode 100644 index a3609baa03..0000000000 --- a/.changelog/v3.2.0/features/consumer/1164-provider-info-query.md +++ /dev/null @@ -1,4 +0,0 @@ -- Introduce the gRPC query `/interchain_security/ccv/consumer/provider-info` - and CLI command `interchain-security-cd q ccvconsumer provider-info` - to retrieve provider info from the consumer chain. - ([\#1164](https://github.com/cosmos/interchain-security/pull/1164)) \ No newline at end of file diff --git a/.changelog/v3.2.0/features/provider/1076-export-timestamps.md b/.changelog/v3.2.0/features/provider/1076-export-timestamps.md deleted file mode 100644 index f2a8608f8b..0000000000 --- a/.changelog/v3.2.0/features/provider/1076-export-timestamps.md +++ /dev/null @@ -1,2 +0,0 @@ -- Add `InitTimeoutTimestamps` and `ExportedVscSendTimestamps` to exported - genesis. ([\#1076](https://github.com/cosmos/interchain-security/pull/1076)) \ No newline at end of file diff --git a/.changelog/v3.2.0/features/provider/1280-reward-denoms.md b/.changelog/v3.2.0/features/provider/1280-reward-denoms.md deleted file mode 100644 index c1f3659a44..0000000000 --- a/.changelog/v3.2.0/features/provider/1280-reward-denoms.md +++ /dev/null @@ -1,3 +0,0 @@ -- Add a governance proposal for setting on the provider the denominations for - rewards from consumer chains. - ([\#1280](https://github.com/cosmos/interchain-security/pull/1280)) \ No newline at end of file diff --git a/.changelog/v3.2.0/improvements/1244-consumer-unbonding.md b/.changelog/v3.2.0/improvements/1244-consumer-unbonding.md deleted file mode 100644 index 4a8504e4ce..0000000000 --- a/.changelog/v3.2.0/improvements/1244-consumer-unbonding.md +++ /dev/null @@ -1,2 +0,0 @@ -- Update the default consumer unbonding period to 2 weeks. - ([\#1244](https://github.com/cosmos/interchain-security/pull/1244)) \ No newline at end of file diff --git a/.changelog/v3.2.0/improvements/consumer/1037-optimize-storage.md b/.changelog/v3.2.0/improvements/consumer/1037-optimize-storage.md deleted file mode 100644 index 726906420b..0000000000 --- a/.changelog/v3.2.0/improvements/consumer/1037-optimize-storage.md +++ /dev/null @@ -1,2 +0,0 @@ -- Optimize pending packets storage on consumer, with migration. - ([\#1037](https://github.com/cosmos/interchain-security/pull/1037)) \ No newline at end of file diff --git a/.changelog/v3.2.0/state-breaking/1196-bump-ibc.md b/.changelog/v3.2.0/state-breaking/1196-bump-ibc.md deleted file mode 100644 index fcf4450150..0000000000 --- a/.changelog/v3.2.0/state-breaking/1196-bump-ibc.md +++ /dev/null @@ -1,3 +0,0 @@ -- Bump [ibc-go](https://github.com/cosmos/ibc-go) to - [v7.2.0](https://github.com/cosmos/ibc-go/releases/tag/v7.2.0). - ([\#1196](https://github.com/cosmos/interchain-security/pull/1196)) \ No newline at end of file diff --git a/.changelog/v3.2.0/state-breaking/1244-consumer-unbonding.md b/.changelog/v3.2.0/state-breaking/1244-consumer-unbonding.md deleted file mode 100644 index 4a8504e4ce..0000000000 --- a/.changelog/v3.2.0/state-breaking/1244-consumer-unbonding.md +++ /dev/null @@ -1,2 +0,0 @@ -- Update the default consumer unbonding period to 2 weeks. - ([\#1244](https://github.com/cosmos/interchain-security/pull/1244)) \ No newline at end of file diff --git a/.changelog/v3.2.0/state-breaking/1258-bump-ibc.md b/.changelog/v3.2.0/state-breaking/1258-bump-ibc.md deleted file mode 100644 index 68c6e2b104..0000000000 --- a/.changelog/v3.2.0/state-breaking/1258-bump-ibc.md +++ /dev/null @@ -1,3 +0,0 @@ -- Bump [ibc-go](https://github.com/cosmos/ibc-go) to - [v7.3.0](https://github.com/cosmos/ibc-go/releases/tag/v7.3.0). - ([\#1258](https://github.com/cosmos/interchain-security/pull/1258)) \ No newline at end of file diff --git a/.changelog/v3.2.0/state-breaking/1258-bump-sdk.md b/.changelog/v3.2.0/state-breaking/1258-bump-sdk.md deleted file mode 100644 index 7344fac97e..0000000000 --- a/.changelog/v3.2.0/state-breaking/1258-bump-sdk.md +++ /dev/null @@ -1,3 +0,0 @@ -- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to - [v0.47.4](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.4). - ([\#1258](https://github.com/cosmos/interchain-security/pull/1258)) \ No newline at end of file diff --git a/.changelog/v3.2.0/state-breaking/1259-bump-sdk.md b/.changelog/v3.2.0/state-breaking/1259-bump-sdk.md deleted file mode 100644 index 247c623b7d..0000000000 --- a/.changelog/v3.2.0/state-breaking/1259-bump-sdk.md +++ /dev/null @@ -1,3 +0,0 @@ -- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to - [v0.47.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.5). - ([\#1259](https://github.com/cosmos/interchain-security/pull/1259)) \ No newline at end of file diff --git a/.changelog/v3.2.0/state-breaking/consumer/1024-jail-throttling-v2.md b/.changelog/v3.2.0/state-breaking/consumer/1024-jail-throttling-v2.md deleted file mode 100644 index 7570facb34..0000000000 --- a/.changelog/v3.2.0/state-breaking/consumer/1024-jail-throttling-v2.md +++ /dev/null @@ -1,2 +0,0 @@ -- Add the consumer-side changes for jail throttling with retries (cf. ADR 008). - ([\#1024](https://github.com/cosmos/interchain-security/pull/1024)) \ No newline at end of file diff --git a/.changelog/v3.2.0/state-breaking/consumer/1037-optimize-storage.md b/.changelog/v3.2.0/state-breaking/consumer/1037-optimize-storage.md deleted file mode 100644 index 726906420b..0000000000 --- a/.changelog/v3.2.0/state-breaking/consumer/1037-optimize-storage.md +++ /dev/null @@ -1,2 +0,0 @@ -- Optimize pending packets storage on consumer, with migration. - ([\#1037](https://github.com/cosmos/interchain-security/pull/1037)) \ No newline at end of file diff --git a/.changelog/v3.2.0/state-breaking/consumer/1146-pending-packets.md b/.changelog/v3.2.0/state-breaking/consumer/1146-pending-packets.md deleted file mode 100644 index a10d75a505..0000000000 --- a/.changelog/v3.2.0/state-breaking/consumer/1146-pending-packets.md +++ /dev/null @@ -1,2 +0,0 @@ -- Fix deletion of pending packets that may cause duplicate sends - ([\#1146](https://github.com/cosmos/interchain-security/pull/1146)) \ No newline at end of file diff --git a/.changelog/v3.2.0/state-breaking/consumer/1150-revert-wire-breaking.md b/.changelog/v3.2.0/state-breaking/consumer/1150-revert-wire-breaking.md deleted file mode 100644 index 067448e770..0000000000 --- a/.changelog/v3.2.0/state-breaking/consumer/1150-revert-wire-breaking.md +++ /dev/null @@ -1,2 +0,0 @@ -- Remove `idx` field from the `ccv.ConsumerPacketData` type as this would break the - wire ([\#1150](https://github.com/cosmos/interchain-security/pull/1150)) \ No newline at end of file diff --git a/.changelog/v3.2.0/state-breaking/consumer/1244-validate-transfer.md b/.changelog/v3.2.0/state-breaking/consumer/1244-validate-transfer.md deleted file mode 100644 index 2d94c79c75..0000000000 --- a/.changelog/v3.2.0/state-breaking/consumer/1244-validate-transfer.md +++ /dev/null @@ -1,2 +0,0 @@ -- Validate token transfer messages before calling `Transfer()`. - ([\#1244](https://github.com/cosmos/interchain-security/pull/1244)) \ No newline at end of file diff --git a/.changelog/v3.2.0/state-breaking/consumer/1262-fee-pool-addr.md b/.changelog/v3.2.0/state-breaking/consumer/1262-fee-pool-addr.md deleted file mode 100644 index bbb54db2e3..0000000000 --- a/.changelog/v3.2.0/state-breaking/consumer/1262-fee-pool-addr.md +++ /dev/null @@ -1,2 +0,0 @@ -- Remove incorrect address validation on `ProviderFeePoolAddrStr` param. - ([\#1262](https://github.com/cosmos/interchain-security/pull/1262)) \ No newline at end of file diff --git a/.changelog/v3.2.0/state-breaking/consumer/1295-migration.md b/.changelog/v3.2.0/state-breaking/consumer/1295-migration.md deleted file mode 100644 index 739b08dc39..0000000000 --- a/.changelog/v3.2.0/state-breaking/consumer/1295-migration.md +++ /dev/null @@ -1,2 +0,0 @@ -- Increment consumer consensus version and register consumer migration. - ([\#1295](https://github.com/cosmos/interchain-security/pull/1295)) \ No newline at end of file diff --git a/.changelog/v3.2.0/state-breaking/provider/1280-reward-denoms.md b/.changelog/v3.2.0/state-breaking/provider/1280-reward-denoms.md deleted file mode 100644 index c1f3659a44..0000000000 --- a/.changelog/v3.2.0/state-breaking/provider/1280-reward-denoms.md +++ /dev/null @@ -1,3 +0,0 @@ -- Add a governance proposal for setting on the provider the denominations for - rewards from consumer chains. - ([\#1280](https://github.com/cosmos/interchain-security/pull/1280)) \ No newline at end of file diff --git a/.changelog/v3.2.0/summary.md b/.changelog/v3.2.0/summary.md deleted file mode 100644 index e7b2c7d6d4..0000000000 --- a/.changelog/v3.2.0/summary.md +++ /dev/null @@ -1 +0,0 @@ -*November 24, 2023* diff --git a/.changelog/v3.3.0/api-breaking/provider/1340-add-cryptographic-verification-of-equivocation-feature.md b/.changelog/v3.3.0/api-breaking/provider/1340-add-cryptographic-verification-of-equivocation-feature.md deleted file mode 100644 index c50662be72..0000000000 --- a/.changelog/v3.3.0/api-breaking/provider/1340-add-cryptographic-verification-of-equivocation-feature.md +++ /dev/null @@ -1,2 +0,0 @@ -- Deprecate equivocation proposals. -([\#1340](https://github.com/cosmos/interchain-security/pull/1340)) \ No newline at end of file diff --git a/.changelog/v3.3.0/dependencies/1373-bump-ibc.md b/.changelog/v3.3.0/dependencies/1373-bump-ibc.md deleted file mode 100644 index efe4e0c286..0000000000 --- a/.changelog/v3.3.0/dependencies/1373-bump-ibc.md +++ /dev/null @@ -1,3 +0,0 @@ -- Bump [ibc-go](https://github.com/cosmos/ibc-go) to - [v7.3.1](https://github.com/cosmos/ibc-go/releases/tag/v7.3.1). - ([\#1373](https://github.com/cosmos/interchain-security/pull/1373)) \ No newline at end of file diff --git a/.changelog/v3.3.0/features/1336-quint-model.md b/.changelog/v3.3.0/features/1336-quint-model.md deleted file mode 100644 index 96c4562b32..0000000000 --- a/.changelog/v3.3.0/features/1336-quint-model.md +++ /dev/null @@ -1,2 +0,0 @@ -- Add Quint model of Replicated Security. - ([\#1336](https://github.com/cosmos/interchain-security/pull/1336)) \ No newline at end of file diff --git a/.changelog/v3.3.0/features/provider/1339-check-key-assignment-in-use.md b/.changelog/v3.3.0/features/provider/1339-check-key-assignment-in-use.md deleted file mode 100644 index 9f274f7bb4..0000000000 --- a/.changelog/v3.3.0/features/provider/1339-check-key-assignment-in-use.md +++ /dev/null @@ -1,3 +0,0 @@ -- Update how consumer-assigned keys are checked when a validator is - created on the provider. - ([\#1339](https://github.com/cosmos/interchain-security/pull/1339)) \ No newline at end of file diff --git a/.changelog/v3.3.0/features/provider/1340-cryptographic-equivocation-feature.md b/.changelog/v3.3.0/features/provider/1340-cryptographic-equivocation-feature.md deleted file mode 100644 index 5437fba186..0000000000 --- a/.changelog/v3.3.0/features/provider/1340-cryptographic-equivocation-feature.md +++ /dev/null @@ -1,4 +0,0 @@ -- Introduce the cryptographic verification of equivocation feature to the provider - (cf. [ADR-005](docs/docs/adrs/adr-005-cryptographic-equivocation-verification.md) - & [ADR-013](docs/docs/adrs/adr-013-equivocation-slashing.md)). - ([\#1340](https://github.com/cosmos/interchain-security/pull/1340)) \ No newline at end of file diff --git a/.changelog/v3.3.0/improvements/1324-consumer-genesis.md b/.changelog/v3.3.0/improvements/1324-consumer-genesis.md deleted file mode 100644 index a727be8341..0000000000 --- a/.changelog/v3.3.0/improvements/1324-consumer-genesis.md +++ /dev/null @@ -1,16 +0,0 @@ -- Split out consumer genesis state to reduce shared data between provider and - consumer. ([\#1324](https://github.com/cosmos/interchain-security/pull/1324)) - - Note: This breaks json format used by augmenting Genesis files of consumer - chains with consumer genesis content exported from provider chain. Consumer - Genesis content exported from a provider chain using major version 1, 2 or 3 - of the provider module needs to be transformed with the transformation command - introduced by this PR: - ``` - Transform the consumer genesis file from a provider version v1, v2 or v3 to a version supported by this consumer. Result is printed to STDOUT. - - Example: - $ transform /path/to/ccv_consumer_genesis.json - - Usage: - interchain-security-cd genesis transform [genesis-file] [flags] - ``` \ No newline at end of file diff --git a/.changelog/v3.3.0/improvements/1350-cleanup-types.md b/.changelog/v3.3.0/improvements/1350-cleanup-types.md deleted file mode 100644 index 6e26fc3992..0000000000 --- a/.changelog/v3.3.0/improvements/1350-cleanup-types.md +++ /dev/null @@ -1,3 +0,0 @@ -- Refactor shared events, codecs and errors assign to - consumer and provider dedicated types where possible. - ([\#1350](https://github.com/cosmos/interchain-security/pull/1350)) \ No newline at end of file diff --git a/.changelog/v3.3.0/improvements/provider/1503-query-key-assignment.md b/.changelog/v3.3.0/improvements/provider/1503-query-key-assignment.md deleted file mode 100644 index 62b505ec01..0000000000 --- a/.changelog/v3.3.0/improvements/provider/1503-query-key-assignment.md +++ /dev/null @@ -1 +0,0 @@ -- Add `QueryAllPairsValConAddrByConsumerChainID` method to get list of all pairs `valConsensus` address by `Consummer chainID`. ([\#1503](https://github.com/cosmos/interchain-security/pull/1503)) \ No newline at end of file diff --git a/.changelog/v3.3.0/state-breaking/1324-consumer-genesis.md b/.changelog/v3.3.0/state-breaking/1324-consumer-genesis.md deleted file mode 100644 index b47f7199fd..0000000000 --- a/.changelog/v3.3.0/state-breaking/1324-consumer-genesis.md +++ /dev/null @@ -1,2 +0,0 @@ -- Split out consumer genesis state to reduce shared data between provider and - consumer. ([\#1324](https://github.com/cosmos/interchain-security/pull/1324)) \ No newline at end of file diff --git a/.changelog/v3.3.0/state-breaking/1460-msg-validation.md b/.changelog/v3.3.0/state-breaking/1460-msg-validation.md deleted file mode 100644 index 46d18bd4c9..0000000000 --- a/.changelog/v3.3.0/state-breaking/1460-msg-validation.md +++ /dev/null @@ -1,3 +0,0 @@ -- Improve validation of IBC packet data and provider messages. Also, - enable the provider to validate consumer packets before handling them. - ([\#1460](https://github.com/cosmos/interchain-security/pull/1460)) \ No newline at end of file diff --git a/.changelog/v3.3.0/state-breaking/provider/1339-check-key-assignment-in-use.md b/.changelog/v3.3.0/state-breaking/provider/1339-check-key-assignment-in-use.md deleted file mode 100644 index 2890582ba8..0000000000 --- a/.changelog/v3.3.0/state-breaking/provider/1339-check-key-assignment-in-use.md +++ /dev/null @@ -1,3 +0,0 @@ -- Change the states by adding a consumer key for each chain that is - not yet registered meaning for which the gov proposal has not passed. - ([\#1339](https://github.com/cosmos/interchain-security/pull/1339)) \ No newline at end of file diff --git a/.changelog/v3.3.0/state-breaking/provider/1340-cryptographic-equivocation-feature.md b/.changelog/v3.3.0/state-breaking/provider/1340-cryptographic-equivocation-feature.md deleted file mode 100644 index 5437fba186..0000000000 --- a/.changelog/v3.3.0/state-breaking/provider/1340-cryptographic-equivocation-feature.md +++ /dev/null @@ -1,4 +0,0 @@ -- Introduce the cryptographic verification of equivocation feature to the provider - (cf. [ADR-005](docs/docs/adrs/adr-005-cryptographic-equivocation-verification.md) - & [ADR-013](docs/docs/adrs/adr-013-equivocation-slashing.md)). - ([\#1340](https://github.com/cosmos/interchain-security/pull/1340)) \ No newline at end of file diff --git a/.changelog/v3.3.0/summary.md b/.changelog/v3.3.0/summary.md deleted file mode 100644 index e556c0f0ca..0000000000 --- a/.changelog/v3.3.0/summary.md +++ /dev/null @@ -1 +0,0 @@ -*January 5, 2024* diff --git a/.changelog/v4.0.0/api-breaking/consumer/1458-consumer-genesis-cli-fix.md b/.changelog/v4.0.0/api-breaking/consumer/1458-consumer-genesis-cli-fix.md deleted file mode 100644 index 0db9ccb072..0000000000 --- a/.changelog/v4.0.0/api-breaking/consumer/1458-consumer-genesis-cli-fix.md +++ /dev/null @@ -1,2 +0,0 @@ -- Fix a bug in consmer genesis file transform CLI command. -([\#1458](https://github.com/cosmos/interchain-security/pull/1458)) \ No newline at end of file diff --git a/.changelog/v4.0.0/bug-fixes/1458-consumer-genesis-cli-fix.md b/.changelog/v4.0.0/bug-fixes/1458-consumer-genesis-cli-fix.md deleted file mode 100644 index 0db9ccb072..0000000000 --- a/.changelog/v4.0.0/bug-fixes/1458-consumer-genesis-cli-fix.md +++ /dev/null @@ -1,2 +0,0 @@ -- Fix a bug in consmer genesis file transform CLI command. -([\#1458](https://github.com/cosmos/interchain-security/pull/1458)) \ No newline at end of file diff --git a/.changelog/v4.0.0/bug-fixes/1460-msg-validation.md b/.changelog/v4.0.0/bug-fixes/1460-msg-validation.md deleted file mode 100644 index 46d18bd4c9..0000000000 --- a/.changelog/v4.0.0/bug-fixes/1460-msg-validation.md +++ /dev/null @@ -1,3 +0,0 @@ -- Improve validation of IBC packet data and provider messages. Also, - enable the provider to validate consumer packets before handling them. - ([\#1460](https://github.com/cosmos/interchain-security/pull/1460)) \ No newline at end of file diff --git a/.changelog/v4.0.0/bug-fixes/consumer/1549-soft-opt-out.md b/.changelog/v4.0.0/bug-fixes/consumer/1549-soft-opt-out.md deleted file mode 100644 index 6fa3d674cf..0000000000 --- a/.changelog/v4.0.0/bug-fixes/consumer/1549-soft-opt-out.md +++ /dev/null @@ -1,3 +0,0 @@ -- Avoid jailing validators immediately once they can no longer opt-out from - validating consumer chains. - ([\#1549](https://github.com/cosmos/interchain-security/pull/1549)) \ No newline at end of file diff --git a/.changelog/v4.0.0/bug-fixes/consumer/1570-slashack-bech32.md b/.changelog/v4.0.0/bug-fixes/consumer/1570-slashack-bech32.md deleted file mode 100644 index a0e9fe9262..0000000000 --- a/.changelog/v4.0.0/bug-fixes/consumer/1570-slashack-bech32.md +++ /dev/null @@ -1,2 +0,0 @@ -- Fix the validation of VSCPackets to not fail due to marshaling to string using Bech32. - ([\#1570](https://github.com/cosmos/interchain-security/pull/1570)) \ No newline at end of file diff --git a/.changelog/v4.0.0/dependencies/1557-bump-go.md b/.changelog/v4.0.0/dependencies/1557-bump-go.md deleted file mode 100644 index 0af0beb3c4..0000000000 --- a/.changelog/v4.0.0/dependencies/1557-bump-go.md +++ /dev/null @@ -1,2 +0,0 @@ -- Bump Golang to v1.21 - ([\#1557](https://github.com/cosmos/interchain-security/pull/1557)) \ No newline at end of file diff --git a/.changelog/v4.0.0/dependencies/1558-bump-comet.md b/.changelog/v4.0.0/dependencies/1558-bump-comet.md deleted file mode 100644 index ef8f50c631..0000000000 --- a/.changelog/v4.0.0/dependencies/1558-bump-comet.md +++ /dev/null @@ -1,3 +0,0 @@ -- Bump [CometBFT](https://github.com/cometbft/cometbft) to - [v0.37.4](https://github.com/cometbft/cometbft/releases/tag/v0.37.4). - ([\#1558](https://github.com/cosmos/interchain-security/pull/1558)) \ No newline at end of file diff --git a/.changelog/v4.0.0/dependencies/1558-bump-sdk.md b/.changelog/v4.0.0/dependencies/1558-bump-sdk.md deleted file mode 100644 index f4afb11072..0000000000 --- a/.changelog/v4.0.0/dependencies/1558-bump-sdk.md +++ /dev/null @@ -1,3 +0,0 @@ -- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to - [v0.47.7](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.7). - ([\#1558](https://github.com/cosmos/interchain-security/pull/1558)) \ No newline at end of file diff --git a/.changelog/v4.0.0/features/provider/1321-jail-throttling-v2.md b/.changelog/v4.0.0/features/provider/1321-jail-throttling-v2.md deleted file mode 100644 index dd3b1a2852..0000000000 --- a/.changelog/v4.0.0/features/provider/1321-jail-throttling-v2.md +++ /dev/null @@ -1,2 +0,0 @@ -- Add the provider-side changes for jail throttling with retries (cf. ADR 008). - ([\#1321](https://github.com/cosmos/interchain-security/pull/1321)) \ No newline at end of file diff --git a/.changelog/v4.0.0/state-breaking/consumer/1549-soft-opt-out.md b/.changelog/v4.0.0/state-breaking/consumer/1549-soft-opt-out.md deleted file mode 100644 index 6fa3d674cf..0000000000 --- a/.changelog/v4.0.0/state-breaking/consumer/1549-soft-opt-out.md +++ /dev/null @@ -1,3 +0,0 @@ -- Avoid jailing validators immediately once they can no longer opt-out from - validating consumer chains. - ([\#1549](https://github.com/cosmos/interchain-security/pull/1549)) \ No newline at end of file diff --git a/.changelog/v4.0.0/state-breaking/consumer/1570-slashack-bech32.md b/.changelog/v4.0.0/state-breaking/consumer/1570-slashack-bech32.md deleted file mode 100644 index a0e9fe9262..0000000000 --- a/.changelog/v4.0.0/state-breaking/consumer/1570-slashack-bech32.md +++ /dev/null @@ -1,2 +0,0 @@ -- Fix the validation of VSCPackets to not fail due to marshaling to string using Bech32. - ([\#1570](https://github.com/cosmos/interchain-security/pull/1570)) \ No newline at end of file diff --git a/.changelog/v4.0.0/state-breaking/provider/1321-jail-throttling-v2.md b/.changelog/v4.0.0/state-breaking/provider/1321-jail-throttling-v2.md deleted file mode 100644 index dd3b1a2852..0000000000 --- a/.changelog/v4.0.0/state-breaking/provider/1321-jail-throttling-v2.md +++ /dev/null @@ -1,2 +0,0 @@ -- Add the provider-side changes for jail throttling with retries (cf. ADR 008). - ([\#1321](https://github.com/cosmos/interchain-security/pull/1321)) \ No newline at end of file diff --git a/.changelog/v4.0.0/summary.md b/.changelog/v4.0.0/summary.md deleted file mode 100644 index 8a69aefd10..0000000000 --- a/.changelog/v4.0.0/summary.md +++ /dev/null @@ -1 +0,0 @@ -*January 22, 2024* diff --git a/.changelog/v4.1.0/dependencies/1663-bump-sdk.md b/.changelog/v4.1.0/dependencies/1663-bump-sdk.md deleted file mode 100644 index a4d2a6bd9c..0000000000 --- a/.changelog/v4.1.0/dependencies/1663-bump-sdk.md +++ /dev/null @@ -1,3 +0,0 @@ -- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to - [v0.47.10](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.10). - ([\#1663](https://github.com/cosmos/interchain-security/pull/1663)) \ No newline at end of file diff --git a/.changelog/v4.1.0/dependencies/1764-bump-ibc.md b/.changelog/v4.1.0/dependencies/1764-bump-ibc.md deleted file mode 100644 index ba4a90bf44..0000000000 --- a/.changelog/v4.1.0/dependencies/1764-bump-ibc.md +++ /dev/null @@ -1,3 +0,0 @@ -- Bump [ibc-go](https://github.com/cosmos/ibc-go) to - [v7.4.0](https://github.com/cosmos/ibc-go/releases/tag/v7.4.0). - ([\#1764](https://github.com/cosmos/interchain-security/pull/1764)) \ No newline at end of file diff --git a/.changelog/v4.1.0/features/provider/1516-introduce-epochs.md b/.changelog/v4.1.0/features/provider/1516-introduce-epochs.md deleted file mode 100644 index 1ebce4000b..0000000000 --- a/.changelog/v4.1.0/features/provider/1516-introduce-epochs.md +++ /dev/null @@ -1,3 +0,0 @@ -- Introduce epochs (i.e., send a VSCPacket every X blocks instead of in every - block) so that we reduce the cost of relaying IBC packets needed for ICS. - ([\#1516](https://github.com/cosmos/interchain-security/pull/1516)) \ No newline at end of file diff --git a/.changelog/v4.1.0/features/provider/1740-oldest-unconfirm-vsc-query.md b/.changelog/v4.1.0/features/provider/1740-oldest-unconfirm-vsc-query.md deleted file mode 100644 index b8c20d7ebf..0000000000 --- a/.changelog/v4.1.0/features/provider/1740-oldest-unconfirm-vsc-query.md +++ /dev/null @@ -1,4 +0,0 @@ -- Introduce the gRPC query `/interchain_security/ccv/provider/oldest_unconfirmed_vsc/{chain_id}` - and CLI command `interchain-security-pd q provider oldest_unconfirmed_vsc` - to retrieve the send timestamp of the oldest unconfirmed VSCPacket by chain id. - ([\#1740](https://github.com/cosmos/interchain-security/pull/1740)) \ No newline at end of file diff --git a/.changelog/v4.1.0/improvements/provider/1445-query-provider-parameters.md b/.changelog/v4.1.0/improvements/provider/1445-query-provider-parameters.md deleted file mode 100644 index f7ec62399d..0000000000 --- a/.changelog/v4.1.0/improvements/provider/1445-query-provider-parameters.md +++ /dev/null @@ -1,2 +0,0 @@ -- Added query for current values of all provider parameters - ([\#1605](https://github.com/cosmos/interchain-security/pull/1605)) \ No newline at end of file diff --git a/.changelog/v4.1.0/state-breaking/1764-bump-ibc.md b/.changelog/v4.1.0/state-breaking/1764-bump-ibc.md deleted file mode 100644 index ba4a90bf44..0000000000 --- a/.changelog/v4.1.0/state-breaking/1764-bump-ibc.md +++ /dev/null @@ -1,3 +0,0 @@ -- Bump [ibc-go](https://github.com/cosmos/ibc-go) to - [v7.4.0](https://github.com/cosmos/ibc-go/releases/tag/v7.4.0). - ([\#1764](https://github.com/cosmos/interchain-security/pull/1764)) \ No newline at end of file diff --git a/.changelog/v4.1.0/state-breaking/provider/1516-introduce-epochs.md b/.changelog/v4.1.0/state-breaking/provider/1516-introduce-epochs.md deleted file mode 100644 index 1ebce4000b..0000000000 --- a/.changelog/v4.1.0/state-breaking/provider/1516-introduce-epochs.md +++ /dev/null @@ -1,3 +0,0 @@ -- Introduce epochs (i.e., send a VSCPacket every X blocks instead of in every - block) so that we reduce the cost of relaying IBC packets needed for ICS. - ([\#1516](https://github.com/cosmos/interchain-security/pull/1516)) \ No newline at end of file diff --git a/.changelog/v4.1.0/summary.md b/.changelog/v4.1.0/summary.md deleted file mode 100644 index 25da253514..0000000000 --- a/.changelog/v4.1.0/summary.md +++ /dev/null @@ -1 +0,0 @@ -*April 17, 2024* \ No newline at end of file diff --git a/.changelog/v4.1.1/bug-fixes/provider/1722-query-valcons-format.md b/.changelog/v4.1.1/bug-fixes/provider/1722-query-valcons-format.md deleted file mode 100644 index 3cf2e930e4..0000000000 --- a/.changelog/v4.1.1/bug-fixes/provider/1722-query-valcons-format.md +++ /dev/null @@ -1,2 +0,0 @@ -- Fix the output format of QueryAllPairsValConAddrByConsumerChainID to be consumer addresses instead of bytes - ([\#1722](https://github.com/cosmos/interchain-security/pull/1722)) \ No newline at end of file diff --git a/.changelog/v4.1.1/summary.md b/.changelog/v4.1.1/summary.md deleted file mode 100644 index c5601d7f30..0000000000 --- a/.changelog/v4.1.1/summary.md +++ /dev/null @@ -1 +0,0 @@ -*April 22, 2024* diff --git a/.changelog/v5.0.0/dependencies/1698-bump-comet.md b/.changelog/v5.0.0/dependencies/1698-bump-comet.md new file mode 100644 index 0000000000..7e750b5120 --- /dev/null +++ b/.changelog/v5.0.0/dependencies/1698-bump-comet.md @@ -0,0 +1,3 @@ +- Bump [CometBFT](https://github.com/cometbft/cometbft) to + [v0.38.4\5](https://github.com/cometbft/cometbft/releases/tag/v0.38.5). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) \ No newline at end of file diff --git a/.changelog/v5.0.0/dependencies/1698-bump-ibc.md b/.changelog/v5.0.0/dependencies/1698-bump-ibc.md new file mode 100644 index 0000000000..40fe475f7b --- /dev/null +++ b/.changelog/v5.0.0/dependencies/1698-bump-ibc.md @@ -0,0 +1,3 @@ +- Bump [ibc-go](https://github.com/cosmos/ibc-go) to + [v8.1.x](https://github.com/cosmos/ibc-go/releases/tag/v8.1.0). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) \ No newline at end of file diff --git a/.changelog/v5.0.0/dependencies/1698-bump-sdk.md b/.changelog/v5.0.0/dependencies/1698-bump-sdk.md new file mode 100644 index 0000000000..ec22555002 --- /dev/null +++ b/.changelog/v5.0.0/dependencies/1698-bump-sdk.md @@ -0,0 +1,3 @@ +- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to +[v0.50.x](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.4) +([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) \ No newline at end of file diff --git a/.changelog/v5.0.0/features/consumer/1814-add-update-consumer-params-msg.md b/.changelog/v5.0.0/features/consumer/1814-add-update-consumer-params-msg.md new file mode 100644 index 0000000000..811c56401b --- /dev/null +++ b/.changelog/v5.0.0/features/consumer/1814-add-update-consumer-params-msg.md @@ -0,0 +1,2 @@ +- Add consumer `MsgUpdateParams` from [cosmos-sdk](https://github.com/cosmos/cosmos-sdk). +([\#1814](https://github.com/cosmos/interchain-security/pull/1814)). \ No newline at end of file diff --git a/.changelog/v5.0.0/features/provider/1698-add-update-provider-params-msg.md b/.changelog/v5.0.0/features/provider/1698-add-update-provider-params-msg.md new file mode 100644 index 0000000000..ca2ce372e2 --- /dev/null +++ b/.changelog/v5.0.0/features/provider/1698-add-update-provider-params-msg.md @@ -0,0 +1,2 @@ +- Add provider `MsgUpdateParams` from [cosmos-sdk](https://github.com/cosmos/cosmos-sdk). +([\#1698](https://github.com/cosmos/interchain-security/pull/1698)). \ No newline at end of file diff --git a/.changelog/v5.0.0/state-breaking/1698-bump-comet.md b/.changelog/v5.0.0/state-breaking/1698-bump-comet.md new file mode 100644 index 0000000000..7e750b5120 --- /dev/null +++ b/.changelog/v5.0.0/state-breaking/1698-bump-comet.md @@ -0,0 +1,3 @@ +- Bump [CometBFT](https://github.com/cometbft/cometbft) to + [v0.38.4\5](https://github.com/cometbft/cometbft/releases/tag/v0.38.5). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) \ No newline at end of file diff --git a/.changelog/v5.0.0/state-breaking/1698-bump-ibc.md b/.changelog/v5.0.0/state-breaking/1698-bump-ibc.md new file mode 100644 index 0000000000..40fe475f7b --- /dev/null +++ b/.changelog/v5.0.0/state-breaking/1698-bump-ibc.md @@ -0,0 +1,3 @@ +- Bump [ibc-go](https://github.com/cosmos/ibc-go) to + [v8.1.x](https://github.com/cosmos/ibc-go/releases/tag/v8.1.0). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) \ No newline at end of file diff --git a/.changelog/v5.0.0/state-breaking/1698-bump-sdk.md b/.changelog/v5.0.0/state-breaking/1698-bump-sdk.md new file mode 100644 index 0000000000..ec22555002 --- /dev/null +++ b/.changelog/v5.0.0/state-breaking/1698-bump-sdk.md @@ -0,0 +1,3 @@ +- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to +[v0.50.x](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.4) +([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) \ No newline at end of file diff --git a/.changelog/v5.0.0/state-breaking/1819-revert-put-unbonding-on-hold.md b/.changelog/v5.0.0/state-breaking/1819-revert-put-unbonding-on-hold.md new file mode 100644 index 0000000000..126b04f4f3 --- /dev/null +++ b/.changelog/v5.0.0/state-breaking/1819-revert-put-unbonding-on-hold.md @@ -0,0 +1,2 @@ +- Revert `PutUnbondingOnHold` behavior to ICS@v1 +([\#1819](https://github.com/cosmos/interchain-security/pull/1819)) \ No newline at end of file diff --git a/.changelog/v5.0.0/summary.md b/.changelog/v5.0.0/summary.md new file mode 100644 index 0000000000..98cfdacda8 --- /dev/null +++ b/.changelog/v5.0.0/summary.md @@ -0,0 +1,2 @@ +*May 9, 2024* + diff --git a/CHANGELOG.md b/CHANGELOG.md index 8629fe32df..893f65a76b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,44 @@ # CHANGELOG +## v5.0.0 + +*May 9, 2024* + +### DEPENDENCIES + +- Bump [ibc-go](https://github.com/cosmos/ibc-go) to + [v8.1.x](https://github.com/cosmos/ibc-go/releases/tag/v8.1.0). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) +- Bump [CometBFT](https://github.com/cometbft/cometbft) to + [v0.38.4\5](https://github.com/cometbft/cometbft/releases/tag/v0.38.5). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) +- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to +[v0.50.x](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.4) +([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) + +### FEATURES + +- [Consumer](x/ccv/consumer) + - Add consumer `MsgUpdateParams` from [cosmos-sdk](https://github.com/cosmos/cosmos-sdk). + ([\#1814](https://github.com/cosmos/interchain-security/pull/1814)). +- [Provider](x/ccv/provider) + - Add provider `MsgUpdateParams` from [cosmos-sdk](https://github.com/cosmos/cosmos-sdk). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)). + +### STATE BREAKING + +- Bump [ibc-go](https://github.com/cosmos/ibc-go) to + [v8.1.x](https://github.com/cosmos/ibc-go/releases/tag/v8.1.0). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) +- Bump [CometBFT](https://github.com/cometbft/cometbft) to + [v0.38.4\5](https://github.com/cometbft/cometbft/releases/tag/v0.38.5). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) +- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to +[v0.50.x](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.4) +([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) +- Revert `PutUnbondingOnHold` behavior to ICS@v1 +([\#1819](https://github.com/cosmos/interchain-security/pull/1819)) + ## v4.1.1 *April 22, 2024* From 6a4e3f6df897be9ec9f83e29c87bd659b7c2afa0 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Thu, 16 May 2024 22:30:09 +0800 Subject: [PATCH 18/35] chore: bump ecosystem libs (#1883) bump ecosystem libs --- go.mod | 49 +++++++++++------------- go.sum | 118 +++++++++++++++++++++++---------------------------------- 2 files changed, 71 insertions(+), 96 deletions(-) diff --git a/go.mod b/go.mod index 6c4bf956be..033903e160 100644 --- a/go.mod +++ b/go.mod @@ -1,19 +1,17 @@ module github.com/cosmos/interchain-security/v5 -go 1.21.1 - -toolchain go1.21.6 +go 1.22.2 require ( cosmossdk.io/errors v1.0.1 - cosmossdk.io/math v1.2.0 - github.com/cometbft/cometbft v0.38.5 - github.com/cometbft/cometbft-db v0.10.0 // indirect - github.com/cosmos/cosmos-sdk v0.50.4 + cosmossdk.io/math v1.3.0 + github.com/cometbft/cometbft v0.38.7 + github.com/cometbft/cometbft-db v0.12.0 // indirect + github.com/cosmos/cosmos-sdk v0.50.5 github.com/cosmos/gogoproto v1.4.11 github.com/cosmos/ics23/go v0.10.0 github.com/golang/mock v1.6.0 - github.com/golang/protobuf v1.5.3 + github.com/golang/protobuf v1.5.4 github.com/gorilla/mux v1.8.1 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/kylelemons/godebug v1.1.0 @@ -22,13 +20,13 @@ require ( github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - golang.org/x/crypto v0.19.0 // indirect - golang.org/x/exp v0.0.0-20240213143201-ec583247a57a - golang.org/x/net v0.20.0 // indirect - golang.org/x/sys v0.17.0 // indirect - google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe // indirect - google.golang.org/grpc v1.61.1 - google.golang.org/protobuf v1.32.0 + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 + golang.org/x/net v0.23.0 // indirect + golang.org/x/sys v0.18.0 // indirect + google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect + google.golang.org/grpc v1.62.0 + google.golang.org/protobuf v1.33.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -50,7 +48,6 @@ require ( github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect - github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect @@ -64,9 +61,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect - github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect - github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -103,10 +98,10 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/klauspost/compress v1.17.6 // indirect + github.com/klauspost/compress v1.17.7 // indirect github.com/lib/pq v1.10.7 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/linxGnu/grocksdb v1.8.12 // indirect + github.com/linxGnu/grocksdb v1.8.14 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -137,10 +132,10 @@ require ( github.com/ulikunitz/xz v0.5.11 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect - go.etcd.io/bbolt v1.3.8 // indirect + go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect go.opencensus.io v0.24.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/term v0.17.0 // indirect + golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/api v0.162.0 // indirect google.golang.org/appengine v1.6.8 // indirect @@ -159,11 +154,11 @@ require ( cosmossdk.io/tools/confix v0.1.1 cosmossdk.io/x/evidence v0.1.0 cosmossdk.io/x/feegrant v0.1.0 - cosmossdk.io/x/tx v0.13.0 + cosmossdk.io/x/tx v0.13.1 cosmossdk.io/x/upgrade v0.1.1 - github.com/cosmos/cosmos-db v1.0.0 + github.com/cosmos/cosmos-db v1.0.2 github.com/cosmos/ibc-go/modules/capability v1.0.0 - github.com/cosmos/ibc-go/v8 v8.1.0 + github.com/cosmos/ibc-go/v8 v8.2.1 github.com/informalsystems/itf-go v0.0.1 github.com/spf13/viper v1.18.2 golang.org/x/mod v0.15.0 @@ -182,11 +177,13 @@ require ( github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/creachadair/atomicfile v0.3.1 // indirect github.com/creachadair/tomledit v0.0.24 // indirect + github.com/dgraph-io/badger/v4 v4.2.0 // indirect github.com/emicklei/dot v1.6.1 // indirect github.com/fatih/color v1.15.0 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/google/flatbuffers v1.12.1 // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-metrics v0.5.2 // indirect @@ -212,7 +209,7 @@ require ( go.uber.org/multierr v1.10.0 // indirect golang.org/x/sync v0.6.0 // indirect golang.org/x/time v0.5.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c // indirect gotest.tools/v3 v3.5.1 // indirect ) diff --git a/go.sum b/go.sum index c053eb905c..fab474f5d0 100644 --- a/go.sum +++ b/go.sum @@ -198,8 +198,8 @@ cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= -cosmossdk.io/math v1.2.0 h1:8gudhTkkD3NxOP2YyyJIYYmt6dQ55ZfJkDOaxXpy7Ig= -cosmossdk.io/math v1.2.0/go.mod h1:l2Gnda87F0su8a/7FEKJfFdJrM0JZRXQaohlgJeyQh0= +cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= +cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= cosmossdk.io/store v1.0.2 h1:lSg5BTvJBHUDwswNNyeh4K/CbqiHER73VU4nDNb8uk0= cosmossdk.io/store v1.0.2/go.mod h1:EFtENTqVTuWwitGW1VwaBct+yDagk7oG/axBMPH+FXs= cosmossdk.io/tools/confix v0.1.1 h1:aexyRv9+y15veH3Qw16lxQwo+ki7r2I+g0yNTEFEQM8= @@ -210,8 +210,8 @@ cosmossdk.io/x/evidence v0.1.0 h1:J6OEyDl1rbykksdGynzPKG5R/zm6TacwW2fbLTW4nCk= cosmossdk.io/x/evidence v0.1.0/go.mod h1:hTaiiXsoiJ3InMz1uptgF0BnGqROllAN8mwisOMMsfw= cosmossdk.io/x/feegrant v0.1.0 h1:c7s3oAq/8/UO0EiN1H5BIjwVntujVTkYs35YPvvrdQk= cosmossdk.io/x/feegrant v0.1.0/go.mod h1:4r+FsViJRpcZif/yhTn+E0E6OFfg4n0Lx+6cCtnZElU= -cosmossdk.io/x/tx v0.13.0 h1:8lzyOh3zONPpZv2uTcUmsv0WTXy6T1/aCVDCqShmpzU= -cosmossdk.io/x/tx v0.13.0/go.mod h1:CpNQtmoqbXa33/DVxWQNx5Dcnbkv2xGUhL7tYQ5wUsY= +cosmossdk.io/x/tx v0.13.1 h1:Mg+EMp67Pz+NukbJqYxuo8uRp7N/a9uR+oVS9pONtj8= +cosmossdk.io/x/tx v0.13.1/go.mod h1:CBCU6fsRVz23QGFIQBb1DNX2DztJCf3jWyEkHY2nJQ0= cosmossdk.io/x/upgrade v0.1.1 h1:aoPe2gNvH+Gwt/Pgq3dOxxQVU3j5P6Xf+DaUJTDZATc= cosmossdk.io/x/upgrade v0.1.1/go.mod h1:MNLptLPcIFK9CWt7Ra//8WUZAxweyRDNcbs5nkOcQy0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -234,7 +234,6 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= @@ -252,7 +251,6 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= @@ -289,7 +287,6 @@ github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInq github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -317,8 +314,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY= -github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= +github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= @@ -335,26 +332,24 @@ github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/cometbft/cometbft v0.38.5 h1:4lOcK5VTPrfbLOhNHmPYe6c7eDXHtBdMCQuKbAfFJdU= -github.com/cometbft/cometbft v0.38.5/go.mod h1:0tqKin+KQs8zDwzYD8rPHzSBIDNPuB4NrwwGDNb/hUg= -github.com/cometbft/cometbft-db v0.10.0 h1:VMBQh88zXn64jXVvj39tlu/IgsGR84T7ImjS523DCiU= -github.com/cometbft/cometbft-db v0.10.0/go.mod h1:7RR7NRv99j7keWJ5IkE9iZibUTKYdtepXTp7Ra0FxKk= +github.com/cometbft/cometbft v0.38.7 h1:ULhIOJ9+LgSy6nLekhq9ae3juX3NnQUMMPyVdhZV6Hk= +github.com/cometbft/cometbft v0.38.7/go.mod h1:HIyf811dFMI73IE0F7RrnY/Fr+d1+HuJAgtkEpQjCMY= +github.com/cometbft/cometbft-db v0.12.0 h1:v77/z0VyfSU7k682IzZeZPFZrQAKiQwkqGN0QzAjMi0= +github.com/cometbft/cometbft-db v0.12.0/go.mod h1:aX2NbCrjNVd2ZajYxt1BsiFf/Z+TQ2MN0VxdicheYuw= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-db v1.0.0 h1:EVcQZ+qYag7W6uorBKFPvX6gRjw6Uq2hIh4hCWjuQ0E= -github.com/cosmos/cosmos-db v1.0.0/go.mod h1:iBvi1TtqaedwLdcrZVYRSSCb6eSy61NLj4UNmdIgs0U= +github.com/cosmos/cosmos-db v1.0.2 h1:hwMjozuY1OlJs/uh6vddqnk9j7VamLv+0DBlbEXbAKs= +github.com/cosmos/cosmos-db v1.0.2/go.mod h1:Z8IXcFJ9PqKK6BIsVOB3QXtkKoqUOp1vRvPT39kOXEA= github.com/cosmos/cosmos-proto v1.0.0-beta.4 h1:aEL7tU/rLOmxZQ9z4i7mzxcLbSCY48OdY7lIWTLG7oU= github.com/cosmos/cosmos-proto v1.0.0-beta.4/go.mod h1:oeB+FyVzG3XrQJbJng0EnV8Vljfk9XvTIpGILNU/9Co= -github.com/cosmos/cosmos-sdk v0.50.4 h1:hQT5/+Z1XXNF7skaPq0i247Ts2dzzqg/j2WO/BPHSto= -github.com/cosmos/cosmos-sdk v0.50.4/go.mod h1:UbShFs6P8Ly29xxJvkNGaNaL/UGj5a686NRtb1Cqra0= +github.com/cosmos/cosmos-sdk v0.50.5 h1:MOEi+DKYgW67YaPgB+Pf+nHbD3V9S/ayitRKJYLfGIA= +github.com/cosmos/cosmos-sdk v0.50.5/go.mod h1:oV/k6GJgXV9QPoM2fsYDPPsyPBgQbdotv532O6Mz1OQ= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= @@ -366,13 +361,12 @@ github.com/cosmos/iavl v1.0.1 h1:D+mYbcRO2wptYzOM1Hxl9cpmmHU1ZEt9T2Wv5nZTeUw= github.com/cosmos/iavl v1.0.1/go.mod h1:8xIUkgVvwvVrBu81scdPty+/Dx9GqwHnAvXz4cwF7RY= github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= -github.com/cosmos/ibc-go/v8 v8.1.0 h1:pf1106wl0Cf+p1+FjXzV6odlS9DnqVunPVWCH1Uz+lQ= -github.com/cosmos/ibc-go/v8 v8.1.0/go.mod h1:o1ipS95xpdjqNcB8Drq0eI3Sn4FRLigjll42ec1ECuU= +github.com/cosmos/ibc-go/v8 v8.2.1 h1:MTsnZZjxvGD4Fv5pYyx5UkELafSX0rlPt6IfsE2BpTQ= +github.com/cosmos/ibc-go/v8 v8.2.1/go.mod h1:wj3qx75iC/XNnsMqbPDCIGs0G6Y3E/lo3bdqCyoCy+8= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creachadair/atomicfile v0.3.1 h1:yQORkHjSYySh/tv5th1dkKcn02NEW5JleB84sjt+W4Q= @@ -393,9 +387,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etly github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= -github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= -github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= -github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/badger/v4 v4.2.0 h1:kJrlajbXXL9DFTNuhhu9yCx7JJa4qpYWxtE8BzuWsEs= +github.com/dgraph-io/badger/v4 v4.2.0/go.mod h1:qfCqhPoWDFJRx1gp5QwwyGo8xk1lbHUxvK9nK0OGAak= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -429,8 +422,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= -github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= +github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= +github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= @@ -548,8 +541,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= @@ -558,6 +551,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= +github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -744,10 +739,9 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= -github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= +github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -769,10 +763,9 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6 github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/linxGnu/grocksdb v1.8.12 h1:1/pCztQUOa3BX/1gR3jSZDoaKFpeHFvQ1XrqZpSvZVo= -github.com/linxGnu/grocksdb v1.8.12/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkVUR7vp4WY= +github.com/linxGnu/grocksdb v1.8.14 h1:HTgyYalNwBSG/1qCQUIott44wU5b2Y9Kr3z7SK5OfGQ= +github.com/linxGnu/grocksdb v1.8.14/go.mod h1:QYiYypR2d4v63Wj1adOOfzglnoII0gLj3PNh4fZkcFA= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= @@ -875,7 +868,6 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= @@ -943,7 +935,6 @@ github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -969,24 +960,16 @@ github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJ github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -1029,7 +1012,6 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1 github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= @@ -1039,7 +1021,6 @@ github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0o github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1052,8 +1033,8 @@ github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWp github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= -go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 h1:qxen9oVGzDdIRP6ejyAJc760RwW4SnVDiTYTzwnXuxo= +go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5/go.mod h1:eW0HG9/oHQhvRCvb1/pIXW4cOvtDqeQK+XSi3TnwaXY= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -1097,7 +1078,6 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1106,8 +1086,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1119,8 +1099,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1210,8 +1190,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1263,7 +1243,6 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1273,7 +1252,6 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1353,13 +1331,13 @@ golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1620,12 +1598,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe h1:USL2DhxfgRchafRvt/wYyyQNzwgL7ZiURcozOE/Pkvo= -google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014 h1:x9PwdEgd11LgK+orcck69WVRo7DezSO4VUMPI4xpc8A= google.golang.org/genproto/googleapis/api v0.0.0-20240205150955-31a09d347014/go.mod h1:rbHMSEDyoYX62nRVLOCc4Qt1HbsdytAYoVwgjiOhF3I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe h1:bQnxqljG/wqi4NTXu2+DJ3n7APcEA882QZ1JvhQAq9o= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c h1:NUsgEN92SQQqzfA+YtqYNqYmB3DMMYLlIwUZAQFVFbo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240221002015-b0ce06bbee7c/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1667,8 +1645,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= -google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= +google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk= +google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1685,8 +1663,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From de6da2a6907ebc5722057f828e1ddfafe643282d Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 24 May 2024 14:30:03 +0200 Subject: [PATCH 19/35] docs: document democracy modules in more detail (backport #1915) (#1919) docs: document democracy modules in more detail (#1915) * docs: document democracy modules in more detail * docs: add diff to config * Update docs/docs/features/democracy-modules.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update docs/docs/features/democracy-modules.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update docs/docs/features/democracy-modules.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * cleanup after applying bot comments --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> (cherry picked from commit 417c8990da207f9f274c61c5ac930b27629f2686) Co-authored-by: MSalopek --- docs/docs/features/democracy-modules.md | 521 ++++++++++++++++++++++++ docs/docusaurus.config.js | 2 +- 2 files changed, 522 insertions(+), 1 deletion(-) create mode 100644 docs/docs/features/democracy-modules.md diff --git a/docs/docs/features/democracy-modules.md b/docs/docs/features/democracy-modules.md new file mode 100644 index 0000000000..a138bb0413 --- /dev/null +++ b/docs/docs/features/democracy-modules.md @@ -0,0 +1,521 @@ +# Democracy modules + +This section is relevant for chains transitioning from a standalone chain and new consumer chains that require some functionality from the `x/staking` module. + +The democracy modules comprise `x/staking`, `x/distribution` and `x/governance` with overrides and extensions required for normal operation when participating in interchain security. + +The modules are plug-and-play and only require small wiring changes to be enabled. + +For a full integration check the `consumer-democracy` [example app](https://github.com/cosmos/interchain-security/blob/main/app/consumer-democracy/app.go). + +## Staking + +The democracy staking module allows the cosmos-sdk `x/staking` module to be used alongside the interchain security `consumer` module. + +The module uses overrides that allow the full `x/staking` functionality with one notable difference - the staking module will no longer be used to provide the consensus validator set. + +### Implications for consumer chains + +The `x/ccv/democracy/staking` allows consumer chains to separate governance from block production. + +:::info +The validator set coming from the provider chain does not need to participate in governance - they only provide infrastructure (create blocks and maintain consensus). +::: + +#### Governators (aka. Governors) + +Validators registered with the `x/staking` module become "Governators". + +Unlike Validators, Governators are not required to run any chain infastructure since they are not signing any blocks. + +However, Governators retain a subset of the validator properties: + +- new Governators can be created (via `MsgCreateValidator`) +- Governators can accept delegations +- Governators can vote on governance proposals (with their self stake and delegations) +- Governators earn token rewards + +With these changes, Governators can become community advocates that can specialize in chain governance and they get rewarded for their participation the same way the validators do. + +Additionally, Governators can choose to provide additional infrastructure such as RPC/API access points, archive nodes, indexers and similar software. + +#### Tokenomics + +The consumer chain's token will remain a governance and reward token. The token's parameters (inflation, max supply, burn rate) are not affected. + +:::info +Staking rewards are distributed to all Governators and their delegators after distributing the rewards to the provider chain's validator set. +::: + +### Integration + +The `x/ccv/democracy/staking` module provides these `x/staking` overrides: + +```golang + +// InitGenesis delegates the InitGenesis call to the underlying x/staking module, +// however, it returns no validator updates as validators are tracked via the +// consumer chain's x/cvv/consumer module and so this module is not responsible for returning the initial validator set. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { + var genesisState types.GenesisState + + cdc.MustUnmarshalJSON(data, &genesisState) + _ = am.keeper.InitGenesis(ctx, &genesisState) // run staking InitGenesis + + return []abci.ValidatorUpdate{} // do not return validator updates +} + +// EndBlock delegates the EndBlock call to the underlying x/staking module. +// However, no validator updates are returned as validators are tracked via the +// consumer chain's x/cvv/consumer module. +func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + _ = am.keeper.BlockValidatorUpdates(ctx) // perform staking BlockValidatorUpdates + return []abci.ValidatorUpdate{} // do not return validator updates +} +``` + +To integrate the `democracy/staking` follow this guide: + +#### 1. confirm that no modules are returning validator updates + +:::tip +Only the `x/ccv/consumer` module should be returning validator updates. +::: + +If some of your modules are returning validator updates please disable them while maintaining your business logic: + +```diff +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { + var genesisState types.GenesisState + + cdc.MustUnmarshalJSON(data, &genesisState) +- return am.keeper.InitGenesis(ctx, &genesisState) ++ _ = am.keeper.InitGenesis(ctx, &genesisState) // run InitGenesis but drop the result ++ return []abci.ValidatorUpdate{} // return empty validator updates +} + + +func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { +- return am.keeper.BlockValidatorUpdates(ctx) ++ _ = am.keeper.BlockValidatorUpdates(ctx) // perform staking BlockValidatorUpdates ++ return []abci.ValidatorUpdate{} // return empty validator updates +} +``` + +#### 2. wire the module in app.go + +You **do not need to remove** the cosmos-sdk `StakingKeeper` from your wiring. + +```diff +import ( + ... ++ ccvstaking "github.com/cosmos/interchain-security/v4/x/ccv/democracy/staking" +) + +var ( + // replace the staking.AppModuleBasic + ModuleBasics = module.NewBasicManager( + auth.AppModuleBasic{}, + genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator), + bank.AppModuleBasic{}, + capability.AppModuleBasic{}, +- sdkstaking.AppModuleBasic{}, ++ ccvstaking.AppModuleBasic{}, // replace sdkstaking + ... + ) +) + + +func NewApp(...) { + ... + + // use sdk StakingKeepeer + app.StakingKeeper = stakingkeeper.NewKeeper( + appCodec, + keys[stakingtypes.StoreKey], + app.AccountKeeper, + app.BankKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.MintKeeper = mintkeeper.NewKeeper( + appCodec, + keys[minttypes.StoreKey], + app.StakingKeeper, + app.AccountKeeper, + app.BankKeeper, + authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + // no changes required for the distribution keeper + app.DistrKeeper = distrkeeper.NewKeeper( + appCodec, + keys[distrtypes.StoreKey], + app.AccountKeeper, + app.BankKeeper, + app.StakingKeeper, // keep StakingKeeper! + authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + ++ // pre-initialize ConsumerKeeper to satsfy ibckeeper.NewKeeper ++ app.ConsumerKeeper = consumerkeeper.NewNonZeroKeeper( ++ appCodec, ++ keys[consumertypes.StoreKey], ++ app.GetSubspace(consumertypes.ModuleName), ++ ) ++ ++ app.IBCKeeper = ibckeeper.NewKeeper( ++ appCodec, ++ keys[ibchost.StoreKey], ++ app.GetSubspace(ibchost.ModuleName), ++ &app.ConsumerKeeper, ++ app.UpgradeKeeper, ++ scopedIBCKeeper, ++ ) ++ ++ // Create CCV consumer and modules ++ app.ConsumerKeeper = consumerkeeper.NewKeeper( ++ appCodec, ++ keys[consumertypes.StoreKey], ++ app.GetSubspace(consumertypes.ModuleName), ++ scopedIBCConsumerKeeper, ++ app.IBCKeeper.ChannelKeeper, ++ &app.IBCKeeper.PortKeeper, ++ app.IBCKeeper.ConnectionKeeper, ++ app.IBCKeeper.ClientKeeper, ++ app.SlashingKeeper, ++ app.BankKeeper, ++ app.AccountKeeper, ++ &app.TransferKeeper, ++ app.IBCKeeper, ++ authtypes.FeeCollectorName, ++ ) ++ ++ // Setting the standalone staking keeper is only needed for standalone to consumer changeover chains ++ // New chains using the democracy/staking do not need to set this ++ app.ConsumerKeeper.SetStandaloneStakingKeeper(app.StakingKeeper) + + + + // change the slashing keeper dependency + app.SlashingKeeper = slashingkeeper.NewKeeper( + appCodec, + legacyAmino, + keys[slashingtypes.StoreKey], +- app.StakingKeeper, ++ &app.ConsumerKeeper, // ConsumerKeeper implements StakingKeeper interface + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + // register slashing module StakingHooks to the consumer keeper ++ app.ConsumerKeeper = *app.ConsumerKeeper.SetHooks(app.SlashingKeeper.Hooks()) ++ consumerModule := consumer.NewAppModule(app.ConsumerKeeper, app.GetSubspace(consumertypes.ModuleName)) + + // register the module with module manager + // replace the x/staking module + app.MM = module.NewManager( + ... +- sdkstaking.NewAppModule(appCodec, &app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), ++ ccvstaking.NewAppModule(appCodec, *app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), + ... + ) +} +``` + +## Governance + +The `x/ccv/democracy/governance` module extends the `x/governance` module with the functionality to filter proposals. + +:::tip +Consumer chains can limit in the types of governance proposals that can be executed on chain to avoid inadvertant changes to interchain security protocol that could affect security properties. +::: + +The module uses `AnteHandler` to limit the types of proposals that can be executed. + +### Integration + +Add new `AnteHandler` to your `app`. + +```go + +// app/ante/forbidden_proposals.go +package ante + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + ibctransfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + + "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + "github.com/cosmos/cosmos-sdk/x/params/types/proposal" +) + +type ForbiddenProposalsDecorator struct { + isLegacyProposalWhitelisted func(govv1beta1.Content) bool + isModuleWhiteList func(string) bool +} + +func NewForbiddenProposalsDecorator( + whiteListFn func(govv1beta1.Content) bool, + isModuleWhiteList func(string) bool, +) ForbiddenProposalsDecorator { + return ForbiddenProposalsDecorator{ + isLegacyProposalWhitelisted: whiteListFn, + isModuleWhiteList: isModuleWhiteList, + } +} + +func (decorator ForbiddenProposalsDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { + currHeight := ctx.BlockHeight() + + for _, msg := range tx.GetMsgs() { + // if the message is MsgSubmitProposal, check if proposal is whitelisted + submitProposalMgs, ok := msg.(*govv1.MsgSubmitProposal) + if !ok { + continue + } + + messages := submitProposalMgs.GetMessages() + for _, message := range messages { + if sdkMsg, isLegacyProposal := message.GetCachedValue().(*govv1.MsgExecLegacyContent); isLegacyProposal { + // legacy gov proposal content + content, err := govv1.LegacyContentFromMessage(sdkMsg) + if err != nil { + return ctx, fmt.Errorf("tx contains invalid LegacyContent") + } + if !decorator.isLegacyProposalWhitelisted(content) { + return ctx, fmt.Errorf("tx contains unsupported proposal message types at height %d", currHeight) + } + continue + } + // not legacy gov proposal content and not whitelisted + if !decorator.isModuleWhiteList(message.TypeUrl) { + return ctx, fmt.Errorf("tx contains unsupported proposal message types at height %d", currHeight) + } + } + } + + return next(ctx, tx, simulate) +} + +func IsProposalWhitelisted(content v1beta1.Content) bool { + switch c := content.(type) { + case *proposal.ParameterChangeProposal: + return isLegacyParamChangeWhitelisted(c.Changes) + + default: + return false + } +} + +func isLegacyParamChangeWhitelisted(paramChanges []proposal.ParamChange) bool { + for _, paramChange := range paramChanges { + _, found := LegacyWhitelistedParams[legacyParamChangeKey{Subspace: paramChange.Subspace, Key: paramChange.Key}] + if !found { + return false + } + } + return true +} + +type legacyParamChangeKey struct { + Subspace, Key string +} + +// Legacy params can be whitelisted +var LegacyWhitelistedParams = map[legacyParamChangeKey]struct{}{ + {Subspace: ibctransfertypes.ModuleName, Key: "SendEnabled"}: {}, + {Subspace: ibctransfertypes.ModuleName, Key: "ReceiveEnabled"}: {}, +} + +// New proposal types can be whitelisted +var WhiteListModule = map[string]struct{}{ + "/cosmos.gov.v1.MsgUpdateParams": {}, + "/cosmos.bank.v1beta1.MsgUpdateParams": {}, + "/cosmos.staking.v1beta1.MsgUpdateParams": {}, + "/cosmos.distribution.v1beta1.MsgUpdateParams": {}, + "/cosmos.mint.v1beta1.MsgUpdateParams": {}, +} + +func IsModuleWhiteList(typeUrl string) bool { + _, found := WhiteListModule[typeUrl] + return found +} +``` + +Add the `AnteHandler` to the list of supported antehandlers: + +```diff +// app/ante_handler.go +package app + +import ( + ... + ++ democracyante "github.com/cosmos/interchain-security/v4/app/consumer-democracy/ante" ++ consumerante "github.com/cosmos/interchain-security/v4/app/consumer/ante" ++ icsconsumerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" +) + +type HandlerOptions struct { + ante.HandlerOptions + + IBCKeeper *ibckeeper.Keeper ++ ConsumerKeeper ibcconsumerkeeper.Keeper +} + +func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { + .... + + anteDecorators := []sdk.AnteDecorator{ + ... ++ consumerante.NewMsgFilterDecorator(options.ConsumerKeeper), ++ consumerante.NewDisabledModulesDecorator("/cosmos.evidence", "/cosmos.slashing"), ++ democracyante.NewForbiddenProposalsDecorator(IsProposalWhitelisted, IsModuleWhiteList), + ... + } + + return sdk.ChainAnteDecorators(anteDecorators...), nil +} +``` + +Wire the module in `app.go`. + +```diff +// app/app.go +package app +import ( + ... + sdkgov "github.com/cosmos/cosmos-sdk/x/gov" + govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + ++ ccvgov "github.com/cosmos/interchain-security/v4/x/ccv/democracy/governance" +) + +var ( + + // use sdk governance module + ModuleBasics = module.NewBasicManager( + ... + sdkgov.NewAppModuleBasic( + []govclient.ProposalHandler{ + paramsclient.ProposalHandler, + upgradeclient.LegacyProposalHandler, + upgradeclient.LegacyCancelProposalHandler, + }, + ), + ) +) + +func NewApp(...) { + // retain sdk gov router and keeper registrations + sdkgovRouter := govv1beta1.NewRouter() + sdkgovRouter. + AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler). + AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)). + AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(&app.UpgradeKeeper)) + govConfig := govtypes.DefaultConfig() + + app.GovKeeper = *govkeeper.NewKeeper( + appCodec, + keys[govtypes.StoreKey], + app.AccountKeeper, + app.BankKeeper, + app.StakingKeeper, + app.MsgServiceRouter(), + govConfig, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + app.GovKeeper.SetLegacyRouter(sdkgovRouter) + + + // register the module with module manager + // replace the x/gov module + app.MM = module.NewManager( +- sdkgov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper, IsProposalWhitelisted, app.GetSubspace(govtypes.ModuleName), IsModuleWhiteList), ++ ccvgov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper, IsProposalWhitelisted, app.GetSubspace(govtypes.ModuleName), IsModuleWhiteList), + ... + ) +} +``` + +## Distribution + +:::tip +The `democracy/distribution` module allows the consumer chain to send rewards to the provider chain while retaining the `x/distribution` module for internal reward distribution to Governators and stakers. +::: + +### How it works + +First, a % of rewards to be distributed to the provider chain's validator set is calculated and sent to the provider chain. Only opted-in validators from the provider chain will receive the consumer rewards. + +Second, the remaining rewards get distributed to the consumer chain's Governators and their delegators. + +:::info +The % that is sent to the provider chain corresponds to `1 - ConsumerRedistributionFraction`. + +e.g. `ConsumerRedistributionFraction = "0.75"` + +means that the consumer chain retains 75% of the rewards, while 25% gets sent to the provider chain to be distributed as rewards to provider chain validators. +::: + +### Integration + +Change the wiring in `app.go` + +```diff +import ( + ... + distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + sdkdistr "github.com/cosmos/cosmos-sdk/x/distribution" + ++ ccvdistr "github.com/cosmos/interchain-security/v4/x/ccv/democracy/distribution" +) + +var ( + // replace sdk distribution AppModuleBasic + ModuleBasics = module.NewBasicManager( + auth.AppModuleBasic{}, + genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator), + bank.AppModuleBasic{}, + capability.AppModuleBasic{}, + ccvstaking.AppModuleBasic{}, // make sure you first swap the staking keeper + mint.AppModuleBasic{}, +- sdkdistr.AppModuleBasic{}, ++ ccvdistr.AppModuleBasic{}, + ) +) + +func NewApp(...) { + .... + + app.DistrKeeper = distrkeeper.NewKeeper( + appCodec, + keys[distrtypes.StoreKey], + app.AccountKeeper, + app.BankKeeper, + app.StakingKeeper, // connect to sdk StakingKeeper + consumertypes.ConsumerRedistributeName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + // register with the module manager + app.MM = module.NewManager( + ... +- sdkdistr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, *app.StakingKeeper, authtypes.FeeCollectorName, app.GetSubspace(distrtypes.ModuleName)), + ++ ccvdistr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, *app.StakingKeeper, authtypes.FeeCollectorName, app.GetSubspace(distrtypes.ModuleName)), + ccvstaking.NewAppModule(appCodec, *app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)), + ... + ) +} +``` diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index e9c2b1e75c..b3a22cc03d 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -174,7 +174,7 @@ const config = { prism: { theme: lightCodeTheme, darkTheme: darkCodeTheme, - additionalLanguages: ["protobuf", "go-module"], // https://prismjs.com/#supported-languages + additionalLanguages: ["protobuf", "go-module", "diff", "go"], // https://prismjs.com/#supported-languages }, // algolia: { // appId: "QLS2QSP47E", From bd65ba51fee0e7c59cc87e8dcb7c22c812bbf7c1 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 2 Jul 2024 09:35:44 +0200 Subject: [PATCH 20/35] chore!: upgrade PSS to SDK v0.50.x (ICS v4.3.x features only) (#1996) * build(deps): bump slackapi/slack-github-action from 1.25.0 to 1.26.0 (#1803) Bumps [slackapi/slack-github-action](https://github.com/slackapi/slack-github-action) from 1.25.0 to 1.26.0. - [Release notes](https://github.com/slackapi/slack-github-action/releases) - [Commits](https://github.com/slackapi/slack-github-action/compare/v1.25.0...v1.26.0) --- updated-dependencies: - dependency-name: slackapi/slack-github-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: add v4.1.x to docs and cleanup bots (#1812) * add v4.1.x to releases and features * cleanup mergify and dependabot * build(deps): bump github.com/cosmos/cosmos-proto from 1.0.0-beta.4 to 1.0.0-beta.5 (#1802) build(deps): bump github.com/cosmos/cosmos-proto Bumps [github.com/cosmos/cosmos-proto](https://github.com/cosmos/cosmos-proto) from 1.0.0-beta.4 to 1.0.0-beta.5. - [Release notes](https://github.com/cosmos/cosmos-proto/releases) - [Commits](https://github.com/cosmos/cosmos-proto/compare/v1.0.0-beta.4...v1.0.0-beta.5) --- updated-dependencies: - dependency-name: github.com/cosmos/cosmos-proto dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * docs: add docs versioning and legacy page (pre v4.0.0) (#1833) * Updated build to allow for versioned docs * wip: add steps to build legacy docs * docs: add build legacy website * docs: add v4; rename to legacy * docs: add docs versioning for docusaurus v3.x * docs: add docs version sync and deploy scripts * update makefile * docs: rm deprecated build script * docs: fix banner in v4.1.0 * docs: update build script & config * update .gitignore * docs: update build script & config * docs: update Readme * build: update docs build script * build: update docs README.md * address review comments * address review comments -- update readme --------- Co-authored-by: Milan Mulji <98309852+mmulji-ic@users.noreply.github.com> * build(deps): bump JamesIves/github-pages-deploy-action from 4.5.0 to 4.6.0 (#1804) build(deps): bump JamesIves/github-pages-deploy-action Bumps [JamesIves/github-pages-deploy-action](https://github.com/jamesives/github-pages-deploy-action) from 4.5.0 to 4.6.0. - [Release notes](https://github.com/jamesives/github-pages-deploy-action/releases) - [Commits](https://github.com/jamesives/github-pages-deploy-action/compare/v4.5.0...v4.6.0) --- updated-dependencies: - dependency-name: JamesIves/github-pages-deploy-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: add release/v5.x bots targets (#1829) * chore: fix spelling errors (#1835) chore: spelling errors fixes Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com> * build(deps): bump github.com/hashicorp/go-getter from 1.7.1 to 1.7.4 (#1826) Bumps [github.com/hashicorp/go-getter](https://github.com/hashicorp/go-getter) from 1.7.1 to 1.7.4. - [Release notes](https://github.com/hashicorp/go-getter/releases) - [Changelog](https://github.com/hashicorp/go-getter/blob/main/.goreleaser.yml) - [Commits](https://github.com/hashicorp/go-getter/compare/v1.7.1...v1.7.4) --- updated-dependencies: - dependency-name: github.com/hashicorp/go-getter dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * docs: update docs deployment (#1841) * build(deps): bump amannn/action-semantic-pull-request from 5.4.0 to 5.5.2 (#1831) build(deps): bump amannn/action-semantic-pull-request Bumps [amannn/action-semantic-pull-request](https://github.com/amannn/action-semantic-pull-request) from 5.4.0 to 5.5.2. - [Release notes](https://github.com/amannn/action-semantic-pull-request/releases) - [Changelog](https://github.com/amannn/action-semantic-pull-request/blob/main/CHANGELOG.md) - [Commits](https://github.com/amannn/action-semantic-pull-request/compare/v5.4.0...v5.5.2) --- updated-dependencies: - dependency-name: amannn/action-semantic-pull-request dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump bufbuild/buf-setup-action from 1.30.1 to 1.31.0 (#1832) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.30.1 to 1.31.0. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.30.1...v1.31.0) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat!: Introduce Partial Set Security (#1809) * cleanup ./changelog entries * docs: changelog and release notes for v4.0.0 (#1564) * add v4.0.0 section to changelog * add release notes * fix!: Validation of SlashAcks fails due to marshaling to Bech32 (backport #1570) (#1577) fix!: Validation of SlashAcks fails due to marshaling to Bech32 (#1570) * add different Bech32Prefix for consumer and provider * separate app encoding and params * remove ConsumerValPubKey from ValidatorConfig * update addresses in tests * make SlashAcks consistent across chains * add comments for clarity * Regenerate traces * Fix argument order * set bech32prefix for provider to cosmos * add changelog entries * add consumer-double-downtime e2e test * update nightly-e2e workflow * fix typo * add consumer-double-downtime to testConfigs * remove changes on provider * skip invalid SlashAcks * seal the config * clear the outstanding downtime flag for new vals * add info on upgrading to v4.0.0 * fix upgrade handler * fix changeover e2e test * Update tests/e2e/config.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update tests/e2e/config.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * add AccountPrefix to ChainConfig * fix docstrings * update AccountAddressPrefix in app.go * fix consumer-misb e2e test --------- Co-authored-by: Philip Offtermatt Co-authored-by: Simon Noetzlin Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> (cherry picked from commit 86046926502f7b0ba795bebcdd1fdc97ac776573) Co-authored-by: Marius Poke * docs: update changelog for v4.0.0 (#1578) update changelog * docs: prepare for v4.0.0 (#1581) * unclog build * update release notes * update release date * feat!: enable Opt In and Top N chains through gov proposals (#1615) * init commit * added test * fixed tests * added changelog entry and comment * Update x/ccv/provider/keeper/proposal_test.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update .changelog/unreleased/features/1587-enable-opt-in-chains-through-gov-proposals.md Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update proto/interchain_security/ccv/provider/v1/provider.proto Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update proto/interchain_security/ccv/provider/v1/provider.proto Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update proto/interchain_security/ccv/provider/v1/provider.proto Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update proto/interchain_security/ccv/provider/v1/provider.proto Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update x/ccv/provider/keeper/keeper.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * changed to tabular test --------- Co-authored-by: insumity Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * feat!: introduce MsgOptIn and MsgOptOut (#1620) * init commit * cleaning up * changed cons to val address * Revert "changed cons to val address" This reverts commit a32e8829fee3cbbe50e363a0aa91ad62117a8a1d. * Update x/ccv/provider/keeper/keeper.go Co-authored-by: Simon Noetzlin * took into account comments * added key assignment * add contraint such that opt out only works if the chain is running --------- Co-authored-by: insumity Co-authored-by: Simon Noetzlin * test: MBT: Add partial set security to model (feature branch version) (#1627) * Port changes from branch to main * Add model analysis changes to Makefile * test: Ports key assignment to the driver on the PSS feature branch (#1628) * Port key assignment to MBT driver * Add comment and make var names clearer * feat!: automatically opt in validators that vote Yes on consumer addition proposals (#1629) * init commit * changed providerKeeper.GetProposedConsumerChain to return a bool * add logging mesages * one more log message * fix comment * added one more test case of NO vote and made tabular test * test: Add driver for PSS (#1636) * Port key assignment to MBT driver * Add PSS trace generation * Add PSS trace gen to longer trace gen * Start handling top N parameter for new consumers * Finish merge * Add handling for optin/optout steps * Remove expected error from OptIn, which should not error * set top N parameter during path setup * Add comment to setup.go * feat!: add PSS reward distribution spike (#1632) * PSS reward distribution * "add optin mapping to test" * Update app/provider/app.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * docs * add TODO * fix Dos vector in IBCMiddlewarea * add reformat * fix DOS issue and make integration tests pass * doc * add integration test * doc * Compute total vp per consumer * add comments * remove opt-in comments and add TODOs * format * Update x/ccv/provider/keeper/distribution.go Co-authored-by: insumity * add UT + doc * Update tests/integration/distribution.go Co-authored-by: insumity * Update tests/integration/distribution.go Co-authored-by: insumity * nits * Update x/ccv/provider/ibc_middleware.go Co-authored-by: Marius Poke * add panics in IBC Middleware ICS4wrapper funcs * address comments --------- Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> Co-authored-by: insumity Co-authored-by: Marius Poke * feat! use protos to serialize opted-in validators (#1659) move OptedInValidators to proto Co-authored-by: insumity * feat!: PSS enable per-consumer chain commission (#1657) * add draft commission * implement consumer commission draft * formatting * add msg handling * improve UT * nits * Update x/ccv/provider/keeper/keeper.go Co-authored-by: insumity * Update proto/interchain_security/ccv/provider/v1/tx.proto Co-authored-by: Marius Poke * optimize keys * Update x/ccv/provider/keeper/keeper.go Co-authored-by: insumity * address comments * address comments * remove unnecessary check * Revert "remove unnecessary check" This reverts commit 2951e9bace04f6436d6ad1e4a11efcedd0be8cb1. * fix minor bug in StopConsumerChain --------- Co-authored-by: insumity Co-authored-by: Marius Poke * test: update integration test suite for PSS (#1687) * draft multi consumer transfer setup and test * format multi consumer distribution test * update test for democ consumer chains * nits * nit * docs: changelog and release notes for v4.0.0 (#1564) * add v4.0.0 section to changelog * add release notes * fix!: Validation of SlashAcks fails due to marshaling to Bech32 (backport #1570) (#1577) fix!: Validation of SlashAcks fails due to marshaling to Bech32 (#1570) * add different Bech32Prefix for consumer and provider * separate app encoding and params * remove ConsumerValPubKey from ValidatorConfig * update addresses in tests * make SlashAcks consistent across chains * add comments for clarity * Regenerate traces * Fix argument order * set bech32prefix for provider to cosmos * add changelog entries * add consumer-double-downtime e2e test * update nightly-e2e workflow * fix typo * add consumer-double-downtime to testConfigs * remove changes on provider * skip invalid SlashAcks * seal the config * clear the outstanding downtime flag for new vals * add info on upgrading to v4.0.0 * fix upgrade handler * fix changeover e2e test * Update tests/e2e/config.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update tests/e2e/config.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * add AccountPrefix to ChainConfig * fix docstrings * update AccountAddressPrefix in app.go * fix consumer-misb e2e test --------- Co-authored-by: Philip Offtermatt Co-authored-by: Simon Noetzlin Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> (cherry picked from commit 86046926502f7b0ba795bebcdd1fdc97ac776573) Co-authored-by: Marius Poke * docs: update changelog for v4.0.0 (#1578) update changelog * feat!: enable Opt In and Top N chains through gov proposals (#1615) * init commit * added test * fixed tests * added changelog entry and comment * Update x/ccv/provider/keeper/proposal_test.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update .changelog/unreleased/features/1587-enable-opt-in-chains-through-gov-proposals.md Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update proto/interchain_security/ccv/provider/v1/provider.proto Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update proto/interchain_security/ccv/provider/v1/provider.proto Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update proto/interchain_security/ccv/provider/v1/provider.proto Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update proto/interchain_security/ccv/provider/v1/provider.proto Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update x/ccv/provider/keeper/keeper.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * changed to tabular test --------- Co-authored-by: insumity Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * feat!: introduce MsgOptIn and MsgOptOut (#1620) * init commit * cleaning up * changed cons to val address * Revert "changed cons to val address" This reverts commit a32e8829fee3cbbe50e363a0aa91ad62117a8a1d. * Update x/ccv/provider/keeper/keeper.go Co-authored-by: Simon Noetzlin * took into account comments * added key assignment * add contraint such that opt out only works if the chain is running --------- Co-authored-by: insumity Co-authored-by: Simon Noetzlin * test: MBT: Add partial set security to model (feature branch version) (#1627) * Port changes from branch to main * Add model analysis changes to Makefile * feat!: add PSS reward distribution spike (#1632) * PSS reward distribution * "add optin mapping to test" * Update app/provider/app.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * docs * add TODO * fix Dos vector in IBCMiddlewarea * add reformat * fix DOS issue and make integration tests pass * doc * add integration test * doc * Compute total vp per consumer * add comments * remove opt-in comments and add TODOs * format * Update x/ccv/provider/keeper/distribution.go Co-authored-by: insumity * add UT + doc * Update tests/integration/distribution.go Co-authored-by: insumity * Update tests/integration/distribution.go Co-authored-by: insumity * nits * Update x/ccv/provider/ibc_middleware.go Co-authored-by: Marius Poke * add panics in IBC Middleware ICS4wrapper funcs * address comments --------- Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> Co-authored-by: insumity Co-authored-by: Marius Poke * feat!: PSS enable per-consumer chain commission (#1657) * add draft commission * implement consumer commission draft * formatting * add msg handling * improve UT * nits * Update x/ccv/provider/keeper/keeper.go Co-authored-by: insumity * Update proto/interchain_security/ccv/provider/v1/tx.proto Co-authored-by: Marius Poke * optimize keys * Update x/ccv/provider/keeper/keeper.go Co-authored-by: insumity * address comments * address comments * remove unnecessary check * Revert "remove unnecessary check" This reverts commit 2951e9bace04f6436d6ad1e4a11efcedd0be8cb1. * fix minor bug in StopConsumerChain --------- Co-authored-by: insumity Co-authored-by: Marius Poke * fix nits in MBT model after merging #1676 from main * Fix merging ccv model * Remove conflict markers * Remove more conflict markers * EndProviderEpoch takes ConsumerAdditionMsg * Fix using consumer addition msgs instead of chain names in boundeddrift.qnt * lint * chore: rebase PSS branch with main (#1689) * Update tests/mbt/driver/mbt_test.go * nits * revert unwanted line deletion from linter --------- Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * feat!: complete the PSS reward distribution (#1709) * update compute consumer total power for reward distribution * update distribution logic to work with epochcs * Adapt reward distribution mem test to epochs * doc * nits * other nits * nits * Update tests/integration/distribution.go * feat!: Add slashing logic for PSS (#1710) * add check for consumer validators in downtime logic * fix UT * try to fix weird errors in gh worfklow * fix silly merge bug * nits * ci: do not scan the tests for security issues (#1717) init commit * feat!: compute partial sets (#1702) * init commit * nit change * cleaning up * clean up * fix distribution test * Update x/ccv/provider/keeper/hooks.go Co-authored-by: Simon Noetzlin * took into Simon's comments * took into rest of the comments * nit change * return an error if validator cannot opt out from a Top N chain * removed automatic opt-in for validators that vote Yes on proposals * tiny fix for E2E tests * nit change to remove unecessary else * fixed topN == 0 issue --------- Co-authored-by: Simon Noetzlin * feat!: update PSS cli (#1708) finalize PSS CLI cmds * Rename and add comission rate command to commands * feat!: only perform consumer additions for non-empty chains (#1730) * init commit * Update x/ccv/provider/keeper/proposal.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> --------- Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * feat: Add queries for PSS and consumer commission rate (#1733) * init commit * nit change * cleaning up * clean up * fix distribution test * Update x/ccv/provider/keeper/hooks.go Co-authored-by: Simon Noetzlin * took into Simon's comments * took into rest of the comments * nit change * return an error if validator cannot opt out from a Top N chain * removed automatic opt-in for validators that vote Yes on proposals * tiny fix for E2E tests * nit change to remove unecessary else * update consumer chains query to return topN * update query consu chains proto * add consumer chains per validator query * Add PSS command to provider's cli * nits * add consumer commission rate query * nits * big renaming * fix doc * nits * nits * docs * Update proto/interchain_security/ccv/provider/v1/query.proto Co-authored-by: insumity * nit * add OptedIn in QueryConsumerChainsValidatorHasToValidate * remove OptIn field in consumer chains query response * include validators that opt-in during the next epochs * update has-to-validate condition * fix tinny bug in the tests after merging feat/partial-security * update doc * update cli description * Update x/ccv/provider/keeper/grpc_query.go Co-authored-by: insumity * changes --------- Co-authored-by: insumity * fix!: Fix opt-in assignment (#1732) * Make the same validator assigning the same key a noop instead of an error * Adjust test * Update tests * Fix newline warning * Regenerate traces * Add key assignment change to changelog * Add info log for same key same validator assignments * Add changelog entry to api-breaking * Update x/ccv/provider/handler_test.go Co-authored-by: insumity * Add more comments to test and return right validator --------- Co-authored-by: insumity * fix silly bug in PSS opted-in val query * fix logging in ibc_module.go * test: add partial-set-security E2E tests (#1737) * init commit * fix traces * Add PSS to default tests * Update tests/e2e/steps_partial_set_security.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update tests/e2e/steps_partial_set_security.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> --------- Co-authored-by: Philip Offtermatt Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Nit changes based on Simons comments. To be pushed directly because E2E PR 1737 were the comments were written was accidentally merged. * fix!: return a SlashAck even if the validator is not a consumer validator (#1763) * init commit * fix test * test: Expand PSS e2e test to include slashing (#1752) * Expand test to include slashing * Add back existing steps * Add downtime to top N test * Fix nits * fix!: update unbonding pausing for PSS (#1728) * draft PSS unbonding fix * fix hook logic to retrieve validator address from ubd op * add unbonding pausing unit-test * remove panic in hook * Get back 3.2.0 and 3.3.0 changelog from main * Port epilogue from main * Fix proto conflict * generate proto files * Port RELEASE_NOTES * Fix merge for tests * Merge declaration and assignment * Clean up model files * Add pss tests to MBT readme * Restore MsgSubmitConsumerDoubleVoting handler * Remove local driver files * Remove Quint guidelines * Add optin/optout to MBT readme * Fix types in model * Fix model * Add migration * Ensure SlashAcks are sent even when the valset does not change * adding changelog entry * Empty DowntimeSlachAcks on EndBlock * Remove logs * Change condition for sending slash acks * Revert model changes * Start fixing PSS issues in model * Add expected errors to opt out action * Revert PSS quint model changes * Add parameter to ComputeNextEpochConsumerValSet * Set top N param in setup * Fix: do not try key assignment if there is no nonjailed validator * Do not assign keys for jailed validators * Only jail validators with non-zero-power * Add unit test * Add unit test for unset case * Panic on not being able to unmarshal * Move packet handling into ack.Success block * Format * Remove unnecessary comment * Add parens for clarity * Format and fix typo * Move OptIn/OptOut events to provider events * Remove unused function * Improve comments for keys * Improve comments for key getter functions * Remove order change for existing keys * Re-add nolint instruction * nit comment fix * Move ConsumerAllocationTests to correct folder * nit comment fix * fix!: handle consumer commission marshalling errors gracefully (#1836) * handle consumer commission setter/getter gracefully to avoid BeginBlock panic + add msg in codec * fix consumer commission query rest path * fix: update queries REST path for PSS (#1839) update queries rest path * Clarify that GetProposedConsumerChain is test-only * fix: Fix has-to-validate query (#1823) * Fix has-to-validate query * Flip comparison sign for checking minPower * Regenerate traces * Remove unnecessary print * Address comments * fix!: fix slashing in PSS (#1838) * drop slash packet for opted-out validators before updating slash meter * fix integration test * fix ut * update UT * Update x/ccv/provider/types/msg.go Co-authored-by: Marius Poke * Remove BlockValidatorUpdate from expected staking keeper * added an error response value to ComputeMinPowerToOptIn * delete additional state when we stop a chain * Assign keys and change voting power only for unjailed nodes with >0 power * fix: Validate consumer commission rate against minimal rate (#1834) * Validate consumer commission rate * Add test for commission rates * Remove static minimum commission rate validation from Set * feat!: introduce power shaping (#1830) * added power shaping * fixes * Add property based test for power cap * fixed tests & added algorithm's idea * nit changes * Update x/ccv/provider/keeper/proposal.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * remove empty-validator-set check * implicit memory aliasing issue fixed * added keeper tests * updated HasToValidate query * Update x/ccv/provider/keeper/keeper.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update x/ccv/provider/keeper/keeper.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * took into account comments * do not use cached ctx * Fix E2E test. A jailed validator does not have to validate. * fix merge issue and format --------- Co-authored-by: Philip Offtermatt Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update v4 to v5 in package version * Bump consensus version * Add migration in correct folder * Update version from v4 to v5 in migration --------- Co-authored-by: mpoke Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: insumity Co-authored-by: insumity Co-authored-by: Simon Noetzlin * chore: add v5.0.x-provider and v5.0.x-provider to mergify and dependabot (#1845) updated bots for v5.0.x-provider release * fix: revert version bump to v5 (#1847) * revert bump version to 5 * register migration * chore: rm v5-provider; add v4.2.0; rm old versions (#1849) * chore: rm v5-provider; add v4.2.0; rm old versions * chore: rm v5-provider; add v4.2.0; rm old versions * chore: Add coderabbit configuration file (#1852) * Add coderabbit configuration file * Add release and feat base branches to coderabbit * Change config to not auto-post review status on unreviewed PRs * refactor: remove redundant code from MakeConsumerGenesis (#1807) * remove redundant code from MakeConsumerGenesis * fix tests * refactor: nit naming changes (#1854) * small naming fix * reverts name to ComputeNextValidators because the semantics of ComputeNextEpochConsumerValSet were different in v4.1 * docs: ADR for Security Aggregation solution (#1866) * ADR CosmoLayer: Initial draft * update adr: slinky api * cleanup * Apply suggestions from code review Co-authored-by: Marius Poke * addressed comments * cleanup of pseudo code, power sources * renaming to security aggregation * mv adr * removed comments * minor change in code example * Apply suggestions from code review Grammar Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: Marius Poke Co-authored-by: Jehan Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * chore: Make coderabbit ignore docs folder (#1864) Make bot ignore docs folder * chore: Fix codespell config (#1869) * Add optin and opt-in to codespell ignored words * Fix typo on multiple * Fix typo on assignment * feat: PSS - Add minimum power in top N & power shaping params to consumer chain list (#1863) * Add minimum power in top N to the list-consumer-chains query * Add test for MinPowerInTop_N * Add changelog entry * Update x/ccv/provider/keeper/keeper_test.go Co-authored-by: insumity * Add other validator shaping params to consumer chain list * Add power shaping params to query test * Adjust changelog for extra fields * Add changelog entry for API breaking --------- Co-authored-by: insumity * chore: fixed all-pairs-valconsensus-address CLI command usage (#1870) * chore: Try to make coderabbit ignore missing/extra newlines in md files (#1877) Update .coderabbit.yml * docs: Add PSS docs (#1859) * Add params to proposals * Start rewriting intro * Finish overview and terminology * Write up generics about PSS and power shaping * Add more info about top N and optin * Nit: apostrophe * Clarify governance proposal process for Opt In chains * Apply suggestions from code review Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Add missing newlines * Update docs/docs/features/partial-set-security.md Co-authored-by: insumity * Update docs/docs/features/power-shaping.md Co-authored-by: insumity * Use Interchain Security instead of ICSv2 * docs: Add PSS docs (Part 2) (#1861) * first version * first commit * one more warning on having all validators opt out * Update docs/docs/validators/partial-set-security-for-validators.md Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update docs/docs/validators/partial-set-security-for-validators.md Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update docs/docs/validators/partial-set-security-for-validators.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update docs/docs/validators/partial-set-security-for-validators.md Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update docs/docs/frequently-asked-questions.md Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update docs/docs/validators/partial-set-security-for-validators.md Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update docs/docs/frequently-asked-questions.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update docs/docs/validators/partial-set-security-for-validators.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * took into account some comments * small comment changes --------- Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Add warning that vals have to manually opt out if going out of top N * Add short PSS FAQ * Add FAQ on how many chains vals can opt in on * Change first to third person * Fix typo * Add missing comma * added a warning * Add more guidelines to 'how to choose the power shaping parameters' * Mention list-consumer-chains query * Add tip about default commission rate --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: insumity * docs: Minor improvements (#1882) * Fix typo in tip * Minor improvements around commission rate * Mention soft opt-out * Link to normal consumer addition prop * Remove confusing line from changeover prop * Remove instructions about not assigning keys * Clarify starting condition for top N chains * Incorporate comments * Update docs/docs/validators/joining-testnet.md Co-authored-by: insumity * Reformulate opting out --------- Co-authored-by: insumity * build(deps): bump google.golang.org/protobuf from 1.33.0 to 1.34.1 (#1862) Bumps google.golang.org/protobuf from 1.33.0 to 1.34.1. --- updated-dependencies: - dependency-name: google.golang.org/protobuf dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: add a query to retrieve validator set that was last sent to the consumer chain (#1867) * init commit * took into account comments * add docs * Update docs/docs/validators/partial-set-security-for-validators.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix!: drop chain proposals with empty validator set at spawn time (#1888) * init commit * Update x/ccv/provider/keeper/proposal.go Co-authored-by: MSalopek * added one more test case --------- Co-authored-by: MSalopek * test: Remove v5.0.0 (pre-release) be tested within e2e compatibility (#1894) * Remove v5.0.0 (pre-release) from last version to be tested within e2e comopatibility tests * Apply suggestions from code review Co-authored-by: Marius Poke --------- Co-authored-by: Marius Poke * test: add E2E test for power-shaping features (#1853) * added E2E tests * Update tests/e2e/steps_partial_set_security.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * added to nightly tests --------- Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * build(deps): bump comet to v0.37.6 (#1876) * bump comet to v0.37.6 * add changelog entry * fix exp deps and pin it to go.mod * bump comet to 0.37.5 and sdk to 0.47.11 to match * bump comet back to 0.37.6 * add changelog entry for SDK --------- Co-authored-by: MSalopek * docs: add v4.2.0; bump v5.0.0 (#1900) * docs: add v4.2.0; bump v5.0.0 * docs: add v4.2.0; bump v5.0.0 * docs: fix broken docs deploy (v4.2.0) (#1903) * docs: add v4.2.0; bump v5.0.0 * docs: add v4.2.0; bump v5.0.0 * sync * sync stuff * fix * try docs tag * add version alias * chore: fix spelling errors (#1904) chore: spelling errors fixes Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com> * build(deps): bump JamesIves/github-pages-deploy-action from 4.6.0 to 4.6.1 (#1905) build(deps): bump JamesIves/github-pages-deploy-action Bumps [JamesIves/github-pages-deploy-action](https://github.com/jamesives/github-pages-deploy-action) from 4.6.0 to 4.6.1. - [Release notes](https://github.com/jamesives/github-pages-deploy-action/releases) - [Commits](https://github.com/jamesives/github-pages-deploy-action/compare/v4.6.0...v4.6.1) --- updated-dependencies: - dependency-name: JamesIves/github-pages-deploy-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump bufbuild/buf-setup-action from 1.31.0 to 1.32.0 (#1906) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.31.0 to 1.32.0. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.31.0...v1.32.0) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump google.golang.org/grpc from 1.63.2 to 1.64.0 (#1908) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.63.2 to 1.64.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.63.2...v1.64.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * docs: document democracy modules in more detail (#1915) * docs: document democracy modules in more detail * docs: add diff to config * Update docs/docs/features/democracy-modules.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update docs/docs/features/democracy-modules.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update docs/docs/features/democracy-modules.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * cleanup after applying bot comments --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * docs: bring v4.2.0 changelog to main (#1909) bring v4.2.0 changelog to main * build(deps): bump github.com/cosmos/ibc-go/v7 from 7.4.0 to 7.5.0 (#1907) * build(deps): bump github.com/cosmos/ibc-go/v7 from 7.4.0 to 7.5.0 Bumps [github.com/cosmos/ibc-go/v7](https://github.com/cosmos/ibc-go) from 7.4.0 to 7.5.0. - [Release notes](https://github.com/cosmos/ibc-go/releases) - [Changelog](https://github.com/cosmos/ibc-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/cosmos/ibc-go/compare/v7.4.0...v7.5.0) --- updated-dependencies: - dependency-name: github.com/cosmos/ibc-go/v7 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * add changelong entry --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mpoke * chore: fix spelling errors (#1922) chore: spelling errors fixes Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com> * fix(client): write unbonding period advisory to stderr instead of stdout (#1921) * fix(client): write unbonding period advisory to stderr instead of stdout * Add changelog for unbonding period advisory --------- Co-authored-by: Philip Offtermatt * docs: update ADR metadata (#1910) * update ADR metadata * fix broken link * fix: migration and error code duplication + e2e tests (#1930) * e2e tests pss * go version 1.22 * fix error code issue * fix e2e tests * fix RegisterMigration * test: e2e fix PSS tests (#1931) * e2e fix PSS tests * Fix message signing for MsgOptIn and MsgOptOut * chore!: fix PSS mem-tests (SDK v50 upgrade) (#1933) * fix mem-tests * nits * nits * other nits * chore!: Add last PSS changes (#1941) * build(deps): bump github.com/cosmos/ibc-go/v7 from 7.5.0 to 7.5.1 (#1924) * build(deps): bump github.com/cosmos/ibc-go/v7 from 7.5.0 to 7.5.1 Bumps [github.com/cosmos/ibc-go/v7](https://github.com/cosmos/ibc-go) from 7.5.0 to 7.5.1. - [Release notes](https://github.com/cosmos/ibc-go/releases) - [Changelog](https://github.com/cosmos/ibc-go/blob/v7.5.1/CHANGELOG.md) - [Commits](https://github.com/cosmos/ibc-go/compare/v7.5.0...v7.5.1) --- updated-dependencies: - dependency-name: github.com/cosmos/ibc-go/v7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * update changelog entry --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mpoke * build(deps): bump bufbuild/buf-setup-action from 1.32.0 to 1.32.1 (#1923) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.32.0 to 1.32.1. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.32.0...v1.32.1) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix mem-tests * nits * nits * other nits * build(deps): bump bufbuild/buf-setup-action from 1.32.1 to 1.32.2 (#1934) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.32.1 to 1.32.2. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.32.1...v1.32.2) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github.com/spf13/viper from 1.18.2 to 1.19.0 (#1936) Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.18.2 to 1.19.0. - [Release notes](https://github.com/spf13/viper/releases) - [Commits](https://github.com/spf13/viper/compare/v1.18.2...v1.19.0) --- updated-dependencies: - dependency-name: github.com/spf13/viper dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump docker/login-action from 3.1.0 to 3.2.0 (#1935) Bumps [docker/login-action](https://github.com/docker/login-action) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/e92390c5fb421da1463c202d546fed0ec5c39f20...0d4c9c5ea7693da7b068278f7b52bda2a190a446) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * docs: Add draft ADR for validators outside of the active set (#1879) * Add draft ADR for active set validators * Remove unused changelog entry * Add initial date and remove square brackets * Suggest alternative approach: unbonded validators can validate * Expand unbonded validators section a bit * Incorporate comments * Update docs/docs/adrs/adr-017-allowing-inactive-validators.md Co-authored-by: Marius Poke * Update docs/docs/adrs/adr-017-allowing-inactive-validators.md Co-authored-by: Marius Poke * Update docs/docs/adrs/adr-017-allowing-inactive-validators.md Co-authored-by: Marius Poke * Clarify consensus validators vs staking validators * Update ADR to roll context doc into it * Fix image links * Add negative consequence * Add sentence about module wiring * Address review comments * Add source code for diagrams and make text more technical * Update docs/docs/adrs/adr-017-allowing-inactive-validators.md Co-authored-by: Marius Poke * Update docs/docs/adrs/adr-017-allowing-inactive-validators.md Co-authored-by: Marius Poke * Update docs/docs/adrs/adr-017-allowing-inactive-validators.md Co-authored-by: Jehan * Write changes to state * Update intro, links, mitigations --------- Co-authored-by: Marius Poke Co-authored-by: Jehan * chore: fix struct name in comment (#1938) Signed-off-by: xiaoxiangirl * feat!: allow consumer chains to change their PSS parameters (#1932) * added modification proposal * small fixes * Update x/ccv/provider/client/proposal_handler.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * removed trailing comma * Update x/ccv/provider/types/proposal.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update x/ccv/provider/types/proposal.go Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * took into account comment --------- Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix!: apply audit suggestions (#1925) * init commit * added CHANGELOG entries * added nit simplification change * addressed comment by Hypha * took into account err returned by ComputeMinPowerToOptIn * fixed test failing * build(deps): bump github.com/cosmos/ibc-go/v7 from 7.5.0 to 7.5.1 (#1924) * build(deps): bump github.com/cosmos/ibc-go/v7 from 7.5.0 to 7.5.1 Bumps [github.com/cosmos/ibc-go/v7](https://github.com/cosmos/ibc-go) from 7.5.0 to 7.5.1. - [Release notes](https://github.com/cosmos/ibc-go/releases) - [Changelog](https://github.com/cosmos/ibc-go/blob/v7.5.1/CHANGELOG.md) - [Commits](https://github.com/cosmos/ibc-go/compare/v7.5.0...v7.5.1) --- updated-dependencies: - dependency-name: github.com/cosmos/ibc-go/v7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * update changelog entry --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mpoke * build(deps): bump bufbuild/buf-setup-action from 1.32.0 to 1.32.1 (#1923) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.32.0 to 1.32.1. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.32.0...v1.32.1) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump bufbuild/buf-setup-action from 1.32.1 to 1.32.2 (#1934) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.32.1 to 1.32.2. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.32.1...v1.32.2) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github.com/spf13/viper from 1.18.2 to 1.19.0 (#1936) Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.18.2 to 1.19.0. - [Release notes](https://github.com/spf13/viper/releases) - [Commits](https://github.com/spf13/viper/compare/v1.18.2...v1.19.0) --- updated-dependencies: - dependency-name: github.com/spf13/viper dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump docker/login-action from 3.1.0 to 3.2.0 (#1935) Bumps [docker/login-action](https://github.com/docker/login-action) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/e92390c5fb421da1463c202d546fed0ec5c39f20...0d4c9c5ea7693da7b068278f7b52bda2a190a446) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * took into account comments --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mpoke * nits * update gosec alerts --------- Signed-off-by: dependabot[bot] Signed-off-by: xiaoxiangirl Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mpoke Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> Co-authored-by: Jehan Co-authored-by: xiaoxiangirl Co-authored-by: insumity Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * chore!: backport #1946 (GetAllConsumerChains fix) to `feat/pss-upgrade-v50` branch (#1950) fix!: Replace GetAllConsumerChains with lightweight version (#1946) * add GetAllConsumerChainIDs * replace GetAllConsumerChains with GetAllRegisteredConsumerChainIDs * add changelog entry * move HasToValidate to grpc_query.go as it's used only there * apply review suggestions Co-authored-by: Marius Poke * fix: backport #1949 + fix handler entry (#1960) * feat!: added E2E test and docs for ConsumerModificationProposal (#1949) * added E2E test for the ConsumerModificationProposal * added docs * add to nightly tests * fix markdown links * Update docs/docs/features/proposals.md Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> --------- Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * fix e2e test 'ConsumerModificationProposal' * app: added missing ConsumerModificationProposalHandle * Apply suggestions from code review Co-authored-by: Simon Noetzlin --------- Co-authored-by: insumity Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> Co-authored-by: Simon Noetzlin * chore: backport regression mem tests for Hub halt (#1945) (#1965) * test: Add integration test reproducing the LastValidators exceeding MaxValidators bug (#1945) * Add test reproducing the LastValidators exceeding MaxValidators * formatting * Update tests/integration/unbonding.go Co-authored-by: insumity * Update tests/integration/unbonding.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * document --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: insumity Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * update mocks --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: insumity Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * test: backport #1942 (#1963) * test: Add an e2e test that reproduces the chain halt (#1942) * Start writing e2e test with unjailing * Add e2e steps for too many validators bug * Fix test config and setup * Change test to use top N chain * Add comment for panic * Start cleaning up active/inactive vals e2e test * Revert change to StartChains * Revert changes to partial-set-security tests * Rename test case * Rename CLI flag for test case * Address comments * Add active set changes test to nightly runs * Fix merge in main.go * adapt e2e to v0.50 --------- Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * chore: use `IterateLastValidatorPowers` instead of `GetLastValidators` (backport #1953) (#1966) * test: Add integration test reproducing the LastValidators exceeding MaxValidators bug (#1945) * Add test reproducing the LastValidators exceeding MaxValidators * formatting * Update tests/integration/unbonding.go Co-authored-by: insumity * Update tests/integration/unbonding.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * document --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: insumity Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * refactor: use IterateLastValidatorPowers instead of GetLastValidators (#1953) * Add skeleton for GetLastValidators wrapper * Fix unit tests * Correct comment * Log error messages if validators are not found * Change AnyTimes to more specific Times(1) * Instantiate slices with their max length and truncate * Remove GetLastValidators from expectation * Remove GetLastValidators call in consumer * Move GetLastBondedValidators to validator_set_updates * Add comment on iteration loop --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: insumity Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * feat!: store the minimal power to be in the top N on EndBlock (#1977) feat!: store the minimal power to be in the top N on EndBlock, instead of computing on-the-fly (#1952) * Store the minimal power among the top N in EndBlock * Finish merge * Fix unit tests * Fix store method for the min power * Fix migration * Revert migration changes * Change comment to proper name for key * Add staking keeper to migration * Revert "Add staking keeper to migration" This reverts commit 575cfd3ccec7732e0d1488d80bda7f6172110cf7. * Rename migration * Update x/ccv/provider/keeper/grpc_query.go * Clean up minimal power in top N on StopConsumerChain * Set min power in consumer modification proposal * Address comments * Use GetLastBondedValidators instead of GetLastValidators * Add migration * Add comment for migration * Improve comment in migration * Handle case where topN is not found * Add test for updating minimum power in top N * Merged tests * Rename updatedMinPower->newUpdatedMinPower * Address comments Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * chore: align to LSM hook signature to SDK v0.50.0 (#1984) fix LSM hook * fix!: update PSS reward distribution to work with SDK v0.50.0 changes (#1982) * fix commented distribution test * doc * Update tests/integration/distribution.go Co-authored-by: insumity * Update tests/integration/distribution.go Co-authored-by: insumity * Update tests/integration/distribution.go Co-authored-by: insumity * add godoc * fix renaming issue * address comments * Update tests/integration/distribution.go Co-authored-by: insumity * make naming more consistent with godoc * Update tests/integration/distribution.go Co-authored-by: insumity --------- Co-authored-by: insumity * chore!: only distribute rewards to validators that have been validating a consumer chain for some backport #1929 (#1983) * fix commented distribution test * feat!: only distribute rewards to validators that have been validating a consumer chain for some time (#1929) * init commit * added a warning * took into account comments * init commit * added a warning * took into account comments * added a comment * Update .changelog/unreleased/improvements/provider/1929-distribute-rewards-to-long-term-validating-validators.md Co-authored-by: Marius Poke * Update .changelog/unreleased/state-breaking/provider/1929-distribute-rewards-to-long-term-validating-validators.md Co-authored-by: Marius Poke * took into account comments * doc * update consensus version to 7 * Update x/ccv/provider/migrations/v6/migration_test.go Co-authored-by: insumity * nit --------- Co-authored-by: insumity * Update proto/interchain_security/ccv/provider/v1/tx.proto Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * address coments * --amend * nits --------- Signed-off-by: dependabot[bot] Signed-off-by: xiaoxiangirl Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Marius Poke Co-authored-by: MSalopek Co-authored-by: Milan Mulji <98309852+mmulji-ic@users.noreply.github.com> Co-authored-by: Cosmos SDK <113218068+github-prbot@users.noreply.github.com> Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com> Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: insumity Co-authored-by: insumity Co-authored-by: bernd-m <43466467+bermuell@users.noreply.github.com> Co-authored-by: Jehan Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Sergey <83376337+freak12techno@users.noreply.github.com> Co-authored-by: Chris Ricketts <6156768+chris-ricketts@users.noreply.github.com> Co-authored-by: Philip Offtermatt Co-authored-by: xiaoxiangirl --- .../unreleased/bug-fixes/1921-write-stderr.md | 2 + .../provider/1925-apply-audit-suggestions.md | 3 + .../provider/1946-get-consumer-chains.md | 3 + .../unreleased/dependencies/1924-bump-ibc.md | 3 + ...ards-to-long-term-validating-validators.md | 3 + .../provider/1925-apply-audit-suggestions.md | 3 + ...ards-to-long-term-validating-validators.md | 3 + ...1732-assigning-already-assigned-key-fix.md | 2 + ...um-power-in-topN-to-consumer-chain-list.md | 2 + .../v4.2.0/dependencies/1876-bump-comet.md | 3 + .../v4.2.0/dependencies/1876-bump-sdk.md | 3 + ...ble-opt-in-chains-through-gov-proposals.md | 2 + .../v4.2.0/features/provider/1809-pss.md | 3 + .../provider/1830-introduce-power-shaping.md | 2 + ...um-power-in-topN-to-consumer-chain-list.md | 2 + ...query-for-latest-consumer-validator-set.md | 2 + ...ble-opt-in-chains-through-gov-proposals.md | 2 + ...1732-assigning-already-assigned-key-fix.md | 2 + .../state-breaking/provider/1809-pss.md | 2 + .../provider/1830-introduce-power-shaping.md | 2 + .changelog/v4.2.0/summary.md | 1 + .coderabbit.yml | 41 + .github/.codespellignore | 2 + .github/dependabot.yml | 39 +- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/deploy-docs.yml | 6 +- .github/workflows/docker-publish.yml | 2 +- .github/workflows/golangci-lint.yml | 2 +- .github/workflows/lint-pr.yml | 2 +- .github/workflows/nightly-e2e.yml | 178 +- .github/workflows/proto-registry.yml | 2 +- .github/workflows/proto.yml | 2 +- .github/workflows/test.yml | 12 +- .gitignore | 4 + .mergify.yml | 54 +- CHANGELOG.md | 49 + Dockerfile | 2 +- Dockerfile.gaia | 8 +- FEATURES.md | 31 +- Makefile | 10 +- RELEASES.md | 14 +- app/provider/app.go | 12 +- docs/README.md | 54 +- docs/build.sh | 10 - docs/build_local.sh | 5 + ...cryptographic-equivocation-verification.md | 2 +- docs/docs/adrs/adr-014-epochs.md | 2 +- .../docs/adrs/adr-015-partial-set-security.md | 2 +- docs/docs/adrs/adr-016-securityaggregation.md | 203 + .../adr-017-allowing-inactive-validators.md | 122 + docs/docs/adrs/intro.md | 6 +- .../consumer-development/app-integration.md | 3 +- .../changeover-procedure.md | 3 +- docs/docs/consumer-development/onboarding.md | 32 +- docs/docs/features/democracy-modules.md | 2 +- docs/docs/features/key-assignment.md | 5 + docs/docs/features/partial-set-security.md | 33 + docs/docs/features/power-shaping.md | 66 + docs/docs/features/proposals.md | 52 +- docs/docs/features/slashing.md | 3 + docs/docs/frequently-asked-questions.md | 70 +- docs/docs/introduction/overview.md | 13 +- docs/docs/introduction/terminology.md | 6 +- docs/docs/validators/joining-testnet.md | 6 +- docs/docs/validators/overview.md | 8 +- .../partial-set-security-for-validators.md | 175 + docs/docs/validators/withdraw_rewards.md | 11 +- docs/docusaurus.config.js | 22 +- docs/figures/inactivevals_after.excalidraw | 847 +++ docs/figures/inactivevals_after.png | Bin 0 -> 78614 bytes docs/figures/inactivevals_before.excalidraw | 659 ++ docs/figures/inactivevals_before.png | Bin 0 -> 65423 bytes docs/sync_versions.sh | 30 + docs/versions.json | 4 + go.mod | 22 +- go.sum | 48 +- .../ccv/provider/v1/provider.proto | 73 +- .../ccv/provider/v1/query.proto | 106 +- .../ccv/provider/v1/tx.proto | 133 +- scripts/protocgen.sh | 0 tests/e2e/actions.go | 205 +- tests/e2e/builder.go | 1 - tests/e2e/config.go | 19 + tests/e2e/main.go | 54 +- tests/e2e/state.go | 82 +- tests/e2e/steps_active_set_changes.go | 143 + tests/e2e/steps_compatibility.go | 13 +- tests/e2e/steps_consumer_misbehaviour.go | 3 +- tests/e2e/steps_partial_set_security.go | 2443 +++++++ tests/e2e/steps_sovereign_changeover.go | 1 + tests/e2e/steps_start_chains.go | 17 +- tests/e2e/test_driver.go | 6 + tests/e2e/testlib/types.go | 10 + .../e2e/tracehandler_testdata/changeover.json | 20 +- .../consumer-double-sign.json | 43 +- .../consumer-misbehaviour.json | 16 +- .../e2e/tracehandler_testdata/democracy.json | 58 +- .../democracyRewardsSteps.json | 58 +- .../e2e/tracehandler_testdata/happyPath.json | 87 +- .../multipleConsumers.json | 157 +- .../e2e/tracehandler_testdata/shorthappy.json | 70 +- .../tracehandler_testdata/slashThrottle.json | 58 +- tests/e2e/v4/state.go | 4 + tests/integration/distribution.go | 730 +- tests/integration/key_assignment.go | 57 +- tests/integration/provider_gov_hooks.go | 3 +- tests/integration/setup.go | 67 +- tests/integration/slashing.go | 9 + tests/integration/unbonding.go | 62 +- tests/mbt/driver/core.go | 34 +- tests/mbt/driver/mbt_test.go | 72 +- tests/mbt/driver/setup.go | 7 +- tests/mbt/model/README.md | 20 +- tests/mbt/model/ccv.qnt | 10 +- tests/mbt/model/ccv_model.qnt | 16 +- tests/mbt/model/ccv_pss.qnt | 157 + tests/mbt/model/ccv_pss_model.qnt | 113 + tests/mbt/model/ccv_pss_test.qnt | 61 + tests/mbt/model/ccv_utils.qnt | 5 + testutil/ibc_testing/generic_setup.go | 56 +- testutil/integration/debug_test.go | 24 + testutil/integration/interfaces.go | 28 +- testutil/keeper/expectations.go | 38 +- testutil/keeper/mocks.go | 88 +- testutil/keeper/unit_test_helpers.go | 13 + x/ccv/consumer/keeper/changeover_test.go | 16 +- x/ccv/consumer/keeper/keeper.go | 8 +- x/ccv/consumer/keeper/keeper_test.go | 11 +- x/ccv/consumer/keeper/soft_opt_out.go | 4 +- x/ccv/provider/client/cli/query.go | 161 +- x/ccv/provider/client/cli/tx.go | 137 + .../client/legacy_proposal_handler.go | 81 +- x/ccv/provider/client/legacy_proposals.go | 38 +- x/ccv/provider/handler.go | 9 + x/ccv/provider/handler_test.go | 33 +- x/ccv/provider/ibc_middleware.go | 242 + x/ccv/provider/ibc_middleware_test.go | 77 + .../provider/keeper/consumer_equivocation.go | 16 +- x/ccv/provider/keeper/distribution.go | 306 +- x/ccv/provider/keeper/distribution_test.go | 299 + x/ccv/provider/keeper/genesis.go | 36 +- x/ccv/provider/keeper/grpc_query.go | 237 +- x/ccv/provider/keeper/grpc_query_test.go | 247 +- x/ccv/provider/keeper/hooks.go | 69 +- x/ccv/provider/keeper/hooks_test.go | 4 +- x/ccv/provider/keeper/keeper.go | 459 +- x/ccv/provider/keeper/keeper_test.go | 259 +- x/ccv/provider/keeper/key_assignment.go | 70 +- x/ccv/provider/keeper/key_assignment_test.go | 10 +- x/ccv/provider/keeper/legacy_proposal.go | 59 + x/ccv/provider/keeper/legacy_proposal_test.go | 66 +- x/ccv/provider/keeper/msg_server.go | 160 +- x/ccv/provider/keeper/params.go | 7 + x/ccv/provider/keeper/params_test.go | 1 + x/ccv/provider/keeper/partial_set_security.go | 320 + .../keeper/partial_set_security_test.go | 684 ++ x/ccv/provider/keeper/proposal.go | 125 +- x/ccv/provider/keeper/proposal_test.go | 261 +- x/ccv/provider/keeper/relay.go | 65 +- x/ccv/provider/keeper/relay_test.go | 304 +- x/ccv/provider/keeper/validator_set_update.go | 166 +- .../keeper/validator_set_update_test.go | 216 +- x/ccv/provider/migrations/migrator.go | 21 +- x/ccv/provider/migrations/v3/migrations.go | 8 +- x/ccv/provider/migrations/v5/migrations.go | 23 +- .../provider/migrations/v5/migrations_test.go | 57 +- .../provider/migrations/v6/migration_test.go | 27 + x/ccv/provider/migrations/v6/migrations.go | 47 + .../migrations/{v5 => v7}/legacy_params.go | 9 +- x/ccv/provider/migrations/v7/migrations.go | 21 + .../provider/migrations/v7/migrations_test.go | 56 + x/ccv/provider/module.go | 12 +- x/ccv/provider/proposal_handler.go | 2 + x/ccv/provider/proposal_handler_test.go | 9 +- x/ccv/provider/types/codec.go | 16 + x/ccv/provider/types/errors.go | 49 +- x/ccv/provider/types/events.go | 5 + x/ccv/provider/types/genesis_test.go | 26 +- x/ccv/provider/types/keys.go | 98 +- x/ccv/provider/types/keys_test.go | 5 + x/ccv/provider/types/legacy_proposal.go | 85 +- x/ccv/provider/types/legacy_proposal_test.go | 264 +- x/ccv/provider/types/msg.go | 165 + x/ccv/provider/types/params.go | 55 +- x/ccv/provider/types/params_test.go | 28 +- x/ccv/provider/types/provider.pb.go | 1296 +++- x/ccv/provider/types/query.pb.go | 5996 +++++++++++------ x/ccv/provider/types/query.pb.gw.go | 426 ++ x/ccv/provider/types/tx.pb.go | 3407 ++++++++-- x/ccv/types/expected_keepers.go | 10 +- x/ccv/types/utils.go | 48 +- 191 files changed, 22437 insertions(+), 3697 deletions(-) create mode 100644 .changelog/unreleased/bug-fixes/1921-write-stderr.md create mode 100644 .changelog/unreleased/bug-fixes/provider/1925-apply-audit-suggestions.md create mode 100644 .changelog/unreleased/bug-fixes/provider/1946-get-consumer-chains.md create mode 100644 .changelog/unreleased/dependencies/1924-bump-ibc.md create mode 100644 .changelog/unreleased/improvements/provider/1929-distribute-rewards-to-long-term-validating-validators.md create mode 100644 .changelog/unreleased/state-breaking/provider/1925-apply-audit-suggestions.md create mode 100644 .changelog/unreleased/state-breaking/provider/1929-distribute-rewards-to-long-term-validating-validators.md create mode 100644 .changelog/v4.2.0/api-breaking/provider/1732-assigning-already-assigned-key-fix.md create mode 100644 .changelog/v4.2.0/api-breaking/provider/1863-add-minimum-power-in-topN-to-consumer-chain-list.md create mode 100644 .changelog/v4.2.0/dependencies/1876-bump-comet.md create mode 100644 .changelog/v4.2.0/dependencies/1876-bump-sdk.md create mode 100644 .changelog/v4.2.0/features/provider/1587-enable-opt-in-chains-through-gov-proposals.md create mode 100644 .changelog/v4.2.0/features/provider/1809-pss.md create mode 100644 .changelog/v4.2.0/features/provider/1830-introduce-power-shaping.md create mode 100644 .changelog/v4.2.0/features/provider/1863-add-minimum-power-in-topN-to-consumer-chain-list.md create mode 100644 .changelog/v4.2.0/features/provider/1867-add-query-for-latest-consumer-validator-set.md create mode 100644 .changelog/v4.2.0/state-breaking/provider/1587-enable-opt-in-chains-through-gov-proposals.md create mode 100644 .changelog/v4.2.0/state-breaking/provider/1732-assigning-already-assigned-key-fix.md create mode 100644 .changelog/v4.2.0/state-breaking/provider/1809-pss.md create mode 100644 .changelog/v4.2.0/state-breaking/provider/1830-introduce-power-shaping.md create mode 100644 .changelog/v4.2.0/summary.md create mode 100644 .coderabbit.yml delete mode 100755 docs/build.sh create mode 100755 docs/build_local.sh create mode 100644 docs/docs/adrs/adr-016-securityaggregation.md create mode 100644 docs/docs/adrs/adr-017-allowing-inactive-validators.md create mode 100644 docs/docs/features/partial-set-security.md create mode 100644 docs/docs/features/power-shaping.md create mode 100644 docs/docs/validators/partial-set-security-for-validators.md create mode 100644 docs/figures/inactivevals_after.excalidraw create mode 100644 docs/figures/inactivevals_after.png create mode 100644 docs/figures/inactivevals_before.excalidraw create mode 100644 docs/figures/inactivevals_before.png create mode 100755 docs/sync_versions.sh create mode 100644 docs/versions.json mode change 100644 => 100755 scripts/protocgen.sh create mode 100644 tests/e2e/steps_active_set_changes.go create mode 100644 tests/e2e/steps_partial_set_security.go create mode 100644 tests/mbt/model/ccv_pss.qnt create mode 100644 tests/mbt/model/ccv_pss_model.qnt create mode 100644 tests/mbt/model/ccv_pss_test.qnt create mode 100644 x/ccv/provider/ibc_middleware.go create mode 100644 x/ccv/provider/ibc_middleware_test.go create mode 100644 x/ccv/provider/keeper/distribution_test.go create mode 100644 x/ccv/provider/keeper/partial_set_security.go create mode 100644 x/ccv/provider/keeper/partial_set_security_test.go create mode 100644 x/ccv/provider/migrations/v6/migration_test.go create mode 100644 x/ccv/provider/migrations/v6/migrations.go rename x/ccv/provider/migrations/{v5 => v7}/legacy_params.go (92%) create mode 100644 x/ccv/provider/migrations/v7/migrations.go create mode 100644 x/ccv/provider/migrations/v7/migrations_test.go diff --git a/.changelog/unreleased/bug-fixes/1921-write-stderr.md b/.changelog/unreleased/bug-fixes/1921-write-stderr.md new file mode 100644 index 0000000000..665ef78024 --- /dev/null +++ b/.changelog/unreleased/bug-fixes/1921-write-stderr.md @@ -0,0 +1,2 @@ +- Write unbonding period advisory to stderr instead of stdout + ([\#1921](https://github.com/cosmos/interchain-security/pull/1921)) \ No newline at end of file diff --git a/.changelog/unreleased/bug-fixes/provider/1925-apply-audit-suggestions.md b/.changelog/unreleased/bug-fixes/provider/1925-apply-audit-suggestions.md new file mode 100644 index 0000000000..3d12033a4e --- /dev/null +++ b/.changelog/unreleased/bug-fixes/provider/1925-apply-audit-suggestions.md @@ -0,0 +1,3 @@ +- Apply audit suggestions that include a bug fix in the way we compute the + maximum capped power. ([\#1925](https://github.com/cosmos/interchain- + security/pull/1925)) diff --git a/.changelog/unreleased/bug-fixes/provider/1946-get-consumer-chains.md b/.changelog/unreleased/bug-fixes/provider/1946-get-consumer-chains.md new file mode 100644 index 0000000000..eae373c390 --- /dev/null +++ b/.changelog/unreleased/bug-fixes/provider/1946-get-consumer-chains.md @@ -0,0 +1,3 @@ +- Replace `GetAllConsumerChains` with lightweight version + (`GetAllRegisteredConsumerChainIDs`) that doesn't call into the staking module + ([\#1946](https://github.com/cosmos/interchain-security/pull/1946)) \ No newline at end of file diff --git a/.changelog/unreleased/dependencies/1924-bump-ibc.md b/.changelog/unreleased/dependencies/1924-bump-ibc.md new file mode 100644 index 0000000000..8980dd3b9a --- /dev/null +++ b/.changelog/unreleased/dependencies/1924-bump-ibc.md @@ -0,0 +1,3 @@ +- Bump [ibc-go](https://github.com/cosmos/ibc-go) to + [v7.5.1](https://github.com/cosmos/ibc-go/releases/tag/v7.5.1). + ([\#1924](https://github.com/cosmos/interchain-security/pull/1924)) \ No newline at end of file diff --git a/.changelog/unreleased/improvements/provider/1929-distribute-rewards-to-long-term-validating-validators.md b/.changelog/unreleased/improvements/provider/1929-distribute-rewards-to-long-term-validating-validators.md new file mode 100644 index 0000000000..b4ff9d6341 --- /dev/null +++ b/.changelog/unreleased/improvements/provider/1929-distribute-rewards-to-long-term-validating-validators.md @@ -0,0 +1,3 @@ +- Only start distributing rewards to validators after they have been validating + for a fixed number of blocks. Introduces the `NumberOfEpochsToStartReceivingRewards` param. + ([\#1929](https://github.com/cosmos/interchain-security/pull/1929)) diff --git a/.changelog/unreleased/state-breaking/provider/1925-apply-audit-suggestions.md b/.changelog/unreleased/state-breaking/provider/1925-apply-audit-suggestions.md new file mode 100644 index 0000000000..3d12033a4e --- /dev/null +++ b/.changelog/unreleased/state-breaking/provider/1925-apply-audit-suggestions.md @@ -0,0 +1,3 @@ +- Apply audit suggestions that include a bug fix in the way we compute the + maximum capped power. ([\#1925](https://github.com/cosmos/interchain- + security/pull/1925)) diff --git a/.changelog/unreleased/state-breaking/provider/1929-distribute-rewards-to-long-term-validating-validators.md b/.changelog/unreleased/state-breaking/provider/1929-distribute-rewards-to-long-term-validating-validators.md new file mode 100644 index 0000000000..b4ff9d6341 --- /dev/null +++ b/.changelog/unreleased/state-breaking/provider/1929-distribute-rewards-to-long-term-validating-validators.md @@ -0,0 +1,3 @@ +- Only start distributing rewards to validators after they have been validating + for a fixed number of blocks. Introduces the `NumberOfEpochsToStartReceivingRewards` param. + ([\#1929](https://github.com/cosmos/interchain-security/pull/1929)) diff --git a/.changelog/v4.2.0/api-breaking/provider/1732-assigning-already-assigned-key-fix.md b/.changelog/v4.2.0/api-breaking/provider/1732-assigning-already-assigned-key-fix.md new file mode 100644 index 0000000000..667a481d3f --- /dev/null +++ b/.changelog/v4.2.0/api-breaking/provider/1732-assigning-already-assigned-key-fix.md @@ -0,0 +1,2 @@ +- Assigning a key that is already assigned by the same validator will now be a no-op instead of throwing an error. + ([\#1732](https://github.com/cosmos/interchain-security/pull/1732)) \ No newline at end of file diff --git a/.changelog/v4.2.0/api-breaking/provider/1863-add-minimum-power-in-topN-to-consumer-chain-list.md b/.changelog/v4.2.0/api-breaking/provider/1863-add-minimum-power-in-topN-to-consumer-chain-list.md new file mode 100644 index 0000000000..482702f26b --- /dev/null +++ b/.changelog/v4.2.0/api-breaking/provider/1863-add-minimum-power-in-topN-to-consumer-chain-list.md @@ -0,0 +1,2 @@ +- Changes the `list-consumer-chains` query to include a `min_power_in_top_N` field, as well as fields for all power shaping parameters of the consumer. + ([\#1863](https://github.com/cosmos/interchain-security/pull/1863)) \ No newline at end of file diff --git a/.changelog/v4.2.0/dependencies/1876-bump-comet.md b/.changelog/v4.2.0/dependencies/1876-bump-comet.md new file mode 100644 index 0000000000..aed8c4f155 --- /dev/null +++ b/.changelog/v4.2.0/dependencies/1876-bump-comet.md @@ -0,0 +1,3 @@ +- Bump [CometBFT](https://github.com/cometbft/cometbft) to + [v0.37.6](https://github.com/cometbft/cometbft/releases/tag/v0.37.6). + ([\#1876](https://github.com/cosmos/interchain-security/pull/1876)) \ No newline at end of file diff --git a/.changelog/v4.2.0/dependencies/1876-bump-sdk.md b/.changelog/v4.2.0/dependencies/1876-bump-sdk.md new file mode 100644 index 0000000000..8f18db0eca --- /dev/null +++ b/.changelog/v4.2.0/dependencies/1876-bump-sdk.md @@ -0,0 +1,3 @@ +- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to + [v0.47.11](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.11). + ([\#1876](https://github.com/cosmos/interchain-security/pull/1876)) \ No newline at end of file diff --git a/.changelog/v4.2.0/features/provider/1587-enable-opt-in-chains-through-gov-proposals.md b/.changelog/v4.2.0/features/provider/1587-enable-opt-in-chains-through-gov-proposals.md new file mode 100644 index 0000000000..57f16adc9b --- /dev/null +++ b/.changelog/v4.2.0/features/provider/1587-enable-opt-in-chains-through-gov-proposals.md @@ -0,0 +1,2 @@ +- Enable Opt In and Top N chains through gov proposals. + ([\#1587](https://github.com/cosmos/interchain-security/pull/1587)) \ No newline at end of file diff --git a/.changelog/v4.2.0/features/provider/1809-pss.md b/.changelog/v4.2.0/features/provider/1809-pss.md new file mode 100644 index 0000000000..f7a235c5be --- /dev/null +++ b/.changelog/v4.2.0/features/provider/1809-pss.md @@ -0,0 +1,3 @@ +- Adding the Partial Set Security (PSS) feature cf. [ADR 015](https://cosmos.github.io/interchain-security/adrs/adr-015-partial-set-security). + PSS enables consumer chains to join ICS as _Top N_ or _Opt In_ chains and enables validators to opt to validate the consumer chains they want. + ([\#1809](https://github.com/cosmos/interchain-security/pull/1809)) \ No newline at end of file diff --git a/.changelog/v4.2.0/features/provider/1830-introduce-power-shaping.md b/.changelog/v4.2.0/features/provider/1830-introduce-power-shaping.md new file mode 100644 index 0000000000..87cd4590b4 --- /dev/null +++ b/.changelog/v4.2.0/features/provider/1830-introduce-power-shaping.md @@ -0,0 +1,2 @@ +- Introduce power-shaping features for consumer chains. The features: (i) allow us to cap the total number of validators that can validate the consumer chain, (ii) set a cap on the maximum voting power (percentage-wise) a validator can have on a consumer chain, and (iii) introduce allowlist and denylists to restrict which validators are allowed or not to validate a consumer chain. + ([\#1830](https://github.com/cosmos/interchain-security/pull/1830)) \ No newline at end of file diff --git a/.changelog/v4.2.0/features/provider/1863-add-minimum-power-in-topN-to-consumer-chain-list.md b/.changelog/v4.2.0/features/provider/1863-add-minimum-power-in-topN-to-consumer-chain-list.md new file mode 100644 index 0000000000..482702f26b --- /dev/null +++ b/.changelog/v4.2.0/features/provider/1863-add-minimum-power-in-topN-to-consumer-chain-list.md @@ -0,0 +1,2 @@ +- Changes the `list-consumer-chains` query to include a `min_power_in_top_N` field, as well as fields for all power shaping parameters of the consumer. + ([\#1863](https://github.com/cosmos/interchain-security/pull/1863)) \ No newline at end of file diff --git a/.changelog/v4.2.0/features/provider/1867-add-query-for-latest-consumer-validator-set.md b/.changelog/v4.2.0/features/provider/1867-add-query-for-latest-consumer-validator-set.md new file mode 100644 index 0000000000..dc33ef69d0 --- /dev/null +++ b/.changelog/v4.2.0/features/provider/1867-add-query-for-latest-consumer-validator-set.md @@ -0,0 +1,2 @@ +- Introduces the `consumer-validators` query to retrieve the latest set consumer-validator set for a consumer chain. + ([\#1863](https://github.com/cosmos/interchain-security/pull/1867)) diff --git a/.changelog/v4.2.0/state-breaking/provider/1587-enable-opt-in-chains-through-gov-proposals.md b/.changelog/v4.2.0/state-breaking/provider/1587-enable-opt-in-chains-through-gov-proposals.md new file mode 100644 index 0000000000..57f16adc9b --- /dev/null +++ b/.changelog/v4.2.0/state-breaking/provider/1587-enable-opt-in-chains-through-gov-proposals.md @@ -0,0 +1,2 @@ +- Enable Opt In and Top N chains through gov proposals. + ([\#1587](https://github.com/cosmos/interchain-security/pull/1587)) \ No newline at end of file diff --git a/.changelog/v4.2.0/state-breaking/provider/1732-assigning-already-assigned-key-fix.md b/.changelog/v4.2.0/state-breaking/provider/1732-assigning-already-assigned-key-fix.md new file mode 100644 index 0000000000..667a481d3f --- /dev/null +++ b/.changelog/v4.2.0/state-breaking/provider/1732-assigning-already-assigned-key-fix.md @@ -0,0 +1,2 @@ +- Assigning a key that is already assigned by the same validator will now be a no-op instead of throwing an error. + ([\#1732](https://github.com/cosmos/interchain-security/pull/1732)) \ No newline at end of file diff --git a/.changelog/v4.2.0/state-breaking/provider/1809-pss.md b/.changelog/v4.2.0/state-breaking/provider/1809-pss.md new file mode 100644 index 0000000000..c0af9ae11e --- /dev/null +++ b/.changelog/v4.2.0/state-breaking/provider/1809-pss.md @@ -0,0 +1,2 @@ +- Adding the Partial Set Security feature cf. [ADR 015](https://cosmos.github.io/interchain-security/adrs/adr-015-partial-set-security). + ([\#1809](https://github.com/cosmos/interchain-security/pull/1809)) \ No newline at end of file diff --git a/.changelog/v4.2.0/state-breaking/provider/1830-introduce-power-shaping.md b/.changelog/v4.2.0/state-breaking/provider/1830-introduce-power-shaping.md new file mode 100644 index 0000000000..87cd4590b4 --- /dev/null +++ b/.changelog/v4.2.0/state-breaking/provider/1830-introduce-power-shaping.md @@ -0,0 +1,2 @@ +- Introduce power-shaping features for consumer chains. The features: (i) allow us to cap the total number of validators that can validate the consumer chain, (ii) set a cap on the maximum voting power (percentage-wise) a validator can have on a consumer chain, and (iii) introduce allowlist and denylists to restrict which validators are allowed or not to validate a consumer chain. + ([\#1830](https://github.com/cosmos/interchain-security/pull/1830)) \ No newline at end of file diff --git a/.changelog/v4.2.0/summary.md b/.changelog/v4.2.0/summary.md new file mode 100644 index 0000000000..d9bdda58b3 --- /dev/null +++ b/.changelog/v4.2.0/summary.md @@ -0,0 +1 @@ +May 17, 2024 diff --git a/.coderabbit.yml b/.coderabbit.yml new file mode 100644 index 0000000000..e89dfcdfcd --- /dev/null +++ b/.coderabbit.yml @@ -0,0 +1,41 @@ +language: "en" +early_access: false +reviews: + request_changes_workflow: false + high_level_summary: true + poem: false + review_status: false + collapse_walkthrough: true + path_filters: + - "!api/" + - "!docs/" + path_instructions: + - path: "**/*.go" + instructions: "Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations." + - path: "tests/e2e/*" + instructions: | + "Assess the e2e test code assessing sufficient code coverage for the changes associated in the pull request" + - path: "tests/integration/*" + instructions: | + "Assess the e2e test code assessing sufficient code coverage for the changes associated in the pull request" + - path: "**/*_test.go" + instructions: | + "Assess the unit test code assessing sufficient code coverage for the changes associated in the pull request" + - path: "**/*.md" + instructions: | + "Assess the documentation for misspellings, grammatical errors, missing documentation and correctness. Please DO NOT report any missing or superfluous newlines, in particular at the end or beginning of files." + - path: ".changelog/*" + instructions: | + "Assess the changes in the changelog for correctness and completeness, particularly flagging missing changes" + auto_review: + enabled: true + ignore_title_keywords: + - "WIP" + - "DO NOT MERGE" + drafts: false + base_branches: + - "main" + - "feat/*" + - "release/*" +chat: + auto_reply: true diff --git a/.github/.codespellignore b/.github/.codespellignore index 3fc9037efb..0c7e0a95c1 100644 --- a/.github/.codespellignore +++ b/.github/.codespellignore @@ -1,3 +1,5 @@ clienta connectiona sover +optin +opt-in diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e588557500..0a55a2d111 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -22,7 +22,7 @@ updates: directory: "/" schedule: interval: daily - target-branch: "release/v2.0.x" + target-branch: "release/v4.1.x" # Only allow automated security-related dependency updates on release branches. open-pull-requests-limit: 0 labels: @@ -32,27 +32,7 @@ updates: directory: "/" schedule: interval: daily - target-branch: "release/v2.4.x-lsm" - # Only allow automated security-related dependency updates on release branches. - open-pull-requests-limit: 0 - labels: - - dependencies - - - package-ecosystem: gomod - directory: "/" - schedule: - interval: daily - target-branch: "release/v3.1.x" - # Only allow automated security-related dependency updates on release branches. - open-pull-requests-limit: 0 - labels: - - dependencies - - - package-ecosystem: gomod - directory: "/" - schedule: - interval: daily - target-branch: "release/v3.2.x" + target-branch: "release/v4.1.x-lsm" # Only allow automated security-related dependency updates on release branches. open-pull-requests-limit: 0 labels: @@ -62,7 +42,7 @@ updates: directory: "/" schedule: interval: daily - target-branch: "release/v3.3.x" + target-branch: "release/v4.2.x" # Only allow automated security-related dependency updates on release branches. open-pull-requests-limit: 0 labels: @@ -72,7 +52,7 @@ updates: directory: "/" schedule: interval: daily - target-branch: "release/v4.0.x" + target-branch: "release/v4.2.x-lsm" # Only allow automated security-related dependency updates on release branches. open-pull-requests-limit: 0 labels: @@ -82,18 +62,9 @@ updates: directory: "/" schedule: interval: daily - target-branch: "release/v4.1.x" + target-branch: "release/v5.x" # Only allow automated security-related dependency updates on release branches. open-pull-requests-limit: 0 labels: - dependencies - - package-ecosystem: gomod - directory: "/" - schedule: - interval: daily - target-branch: "release/v4.1.x-lsm" - # Only allow automated security-related dependency updates on release branches. - open-pull-requests-limit: 0 - labels: - - dependencies \ No newline at end of file diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 2150c8ac86..7a18604ac7 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -37,7 +37,7 @@ jobs: uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" check-latest: true # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 8e36cd6cda..db8ecca694 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -37,10 +37,12 @@ jobs: - name: Build 🔧 run: | npm install -g npm@10.2.4 - make build-docs + cd docs + ./sync_versions.sh + ./build_deploy.sh - name: Deploy 🚀 - uses: JamesIves/github-pages-deploy-action@v4.5.0 + uses: JamesIves/github-pages-deploy-action@v4.6.1 with: branch: gh-pages folder: ~/output diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 895ad0e4e3..bb9c86a3f9 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -57,7 +57,7 @@ jobs: # https://github.com/docker/login-action - name: Log into registry ${{ env.REGISTRY }} if: github.event_name != 'pull_request' - uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 + uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index a879de2114..02db4be638 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.22' - uses: technote-space/get-diff-action@v6.1.2 id: git_diff with: diff --git a/.github/workflows/lint-pr.yml b/.github/workflows/lint-pr.yml index 18027164fc..7c573d1647 100644 --- a/.github/workflows/lint-pr.yml +++ b/.github/workflows/lint-pr.yml @@ -17,7 +17,7 @@ jobs: statuses: write # for amannn/action-semantic-pull-request to mark status of analyzed PR runs-on: ubuntu-latest steps: - - uses: amannn/action-semantic-pull-request@v5.4.0 + - uses: amannn/action-semantic-pull-request@v5.5.2 id: lint_pr_title env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/nightly-e2e.yml b/.github/workflows/nightly-e2e.yml index ca560550ca..b279c59714 100644 --- a/.github/workflows/nightly-e2e.yml +++ b/.github/workflows/nightly-e2e.yml @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" - uses: actions/checkout@v4 with: fetch-depth: 0 # get all history for all branches and tags @@ -31,7 +31,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "1.21" # The Go version to download (if necessary) and use. + go-version: "1.22" # The Go version to download (if necessary) and use. - name: E2E compatibility test # Run compatibility tests for different consumer (-cv) and provider (-pv) versions. # Combination of all provider versions with consumer versions are tested. @@ -43,14 +43,14 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" - uses: actions/checkout@v4 - name: Checkout LFS objects run: git lfs checkout - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "1.21" # The Go version to download (if necessary) and use. + go-version: "1.22" # The Go version to download (if necessary) and use. - name: E2E happy-path test run: go run ./tests/e2e/... --tc happy-path changeover-test: @@ -59,14 +59,14 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" - uses: actions/checkout@v4 - name: Checkout LFS objects run: git lfs checkout - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "1.21" # The Go version to download (if necessary) and use. + go-version: "1.22" # The Go version to download (if necessary) and use. - name: E2E changeover test run: go run ./tests/e2e/... --tc changeover democracy-reward-test: @@ -75,14 +75,14 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" - uses: actions/checkout@v4 - name: Checkout LFS objects run: git lfs checkout - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "1.21" # The Go version to download (if necessary) and use. + go-version: "1.22" # The Go version to download (if necessary) and use. - name: E2E democracy-reward tests run: go run ./tests/e2e/... --tc democracy-reward democracy-test: @@ -91,14 +91,14 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" - uses: actions/checkout@v4 - name: Checkout LFS objects run: git lfs checkout - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "1.21" # The Go version to download (if necessary) and use. + go-version: "1.22" # The Go version to download (if necessary) and use. - name: E2E democracy tests run: go run ./tests/e2e/... --tc democracy slash-throttle-test: @@ -107,14 +107,14 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" - uses: actions/checkout@v4 - name: Checkout LFS objects run: git lfs checkout - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "1.21" # The Go version to download (if necessary) and use. + go-version: "1.22" # The Go version to download (if necessary) and use. - name: E2E slash-throttle tests run: go run ./tests/e2e/... --tc slash-throttle multiconsumer-test: @@ -123,14 +123,14 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" - uses: actions/checkout@v4 - name: Checkout LFS objects run: git lfs checkout - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "1.21" # The Go version to download (if necessary) and use. + go-version: "1.22" # The Go version to download (if necessary) and use. - name: E2E multi-consumer tests run: go run ./tests/e2e/... --tc multiconsumer consumer-misbehaviour-test: @@ -139,14 +139,14 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" - uses: actions/checkout@v4 - name: Checkout LFS objects run: git lfs checkout - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "1.21" # The Go version to download (if necessary) and use. + go-version: "1.22" # The Go version to download (if necessary) and use. - name: E2E consumer-misbehaviour tests run: go run ./tests/e2e/... --tc consumer-misbehaviour consumer-double-sign-test: @@ -155,14 +155,14 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" - uses: actions/checkout@v4 - name: Checkout LFS objects run: git lfs checkout - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "1.21" # The Go version to download (if necessary) and use. + go-version: "1.22" # The Go version to download (if necessary) and use. - name: E2E consumer-double-sign tests run: go run ./tests/e2e/... --tc consumer-double-sign consumer-double-downtime-test: @@ -171,16 +171,144 @@ jobs: steps: - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" - uses: actions/checkout@v4 - name: Checkout LFS objects run: git lfs checkout - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "1.21" # The Go version to download (if necessary) and use. + go-version: "1.22" # The Go version to download (if necessary) and use. - name: E2E consumer-double-downtime tests run: go run ./tests/e2e/... --tc consumer-double-downtime + partial-set-security-opt-in-test: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/setup-go@v5 + with: + go-version: "1.22" + - uses: actions/checkout@v4 + - name: Checkout LFS objects + run: git lfs checkout + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: "1.22" # The Go version to download (if necessary) and use. + - name: E2E partial set security opt-in chain + run: go run ./tests/e2e/... --tc partial-set-security-opt-in + partial-set-security-top-n-test: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/setup-go@v5 + with: + go-version: "1.22" + - uses: actions/checkout@v4 + - name: Checkout LFS objects + run: git lfs checkout + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: "1.22" # The Go version to download (if necessary) and use. + - name: E2E partial set security Top N chain + run: go run ./tests/e2e/... --tc partial-set-security-top-n + partial-set-security-validator-set-cap-test: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/setup-go@v5 + with: + go-version: "1.22" + - uses: actions/checkout@v4 + - name: Checkout LFS objects + run: git lfs checkout + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: "1.22" # The Go version to download (if necessary) and use. + - name: E2E partial set security validator-set cap + run: go run ./tests/e2e/... --tc partial-set-security-validator-set-cap + partial-set-security-validators-power-cap-test: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/setup-go@v5 + with: + go-version: "1.22" + - uses: actions/checkout@v4 + - name: Checkout LFS objects + run: git lfs checkout + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: "1.22" # The Go version to download (if necessary) and use. + - name: E2E partial set security validators-power cap + run: go run ./tests/e2e/... --tc partial-set-security-validators-power-cap + partial-set-security-validators-allowlisted-test: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/setup-go@v5 + with: + go-version: "1.22" + - uses: actions/checkout@v4 + - name: Checkout LFS objects + run: git lfs checkout + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: "1.22" # The Go version to download (if necessary) and use. + - name: E2E partial set security allowlist + run: go run ./tests/e2e/... --tc partial-set-security-validators-allowlisted + partial-set-security-validators-denylisted-test: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/setup-go@v5 + with: + go-version: "1.22" + - uses: actions/checkout@v4 + - name: Checkout LFS objects + run: git lfs checkout + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: "1.22" # The Go version to download (if necessary) and use. + - name: E2E partial set security denylist + run: go run ./tests/e2e/... --tc partial-set-security-validators-denylisted + partial-set-security-modification-proposal: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/setup-go@v5 + with: + go-version: "1.22" + - uses: actions/checkout@v4 + - name: Checkout LFS objects + run: git lfs checkout + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: "1.22" # The Go version to download (if necessary) and use. + - name: E2E partial set security modification proposal + run: go run ./tests/e2e/... --tc partial-set-security-modification-proposal + active-set-changes-test: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/setup-go@v5 + with: + go-version: "1.22" + - uses: actions/checkout@v4 + - name: Checkout LFS objects + run: git lfs checkout + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: "1.22" # The Go version to download (if necessary) and use. + - name: E2E active set changes + run: go run ./tests/e2e/... --tc active-set-changes nightly-test-fail: needs: @@ -193,11 +321,19 @@ jobs: - consumer-misbehaviour-test - consumer-double-sign-test - consumer-double-downtime-test + - partial-set-security-opt-in-test + - partial-set-security-top-n-test + - partial-set-security-validator-set-cap-test + - partial-set-security-validators-power-cap-test + - partial-set-security-validators-allowlisted-test + - partial-set-security-validators-denylisted-test + - partial-set-security-modification-proposal + - active-set-changes-test if: ${{ failure() }} runs-on: ubuntu-latest steps: - name: Notify Slack on failure - uses: slackapi/slack-github-action@v1.25.0 + uses: slackapi/slack-github-action@v1.26.0 env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK diff --git a/.github/workflows/proto-registry.yml b/.github/workflows/proto-registry.yml index 2f1385be33..0dd39a112c 100644 --- a/.github/workflows/proto-registry.yml +++ b/.github/workflows/proto-registry.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: bufbuild/buf-setup-action@v1.30.1 + - uses: bufbuild/buf-setup-action@v1.32.2 - uses: bufbuild/buf-push-action@v1 with: input: "proto" diff --git a/.github/workflows/proto.yml b/.github/workflows/proto.yml index 3c9d1b05b0..68f31f2b67 100644 --- a/.github/workflows/proto.yml +++ b/.github/workflows/proto.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: bufbuild/buf-setup-action@v1.30.1 + - uses: bufbuild/buf-setup-action@v1.32.2 - uses: bufbuild/buf-breaking-action@v1 with: input: "proto" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 479be3c317..147ab7f60e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" check-latest: true cache: true cache-dependency-path: go.sum @@ -65,7 +65,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" check-latest: true cache: true cache-dependency-path: go.sum @@ -96,7 +96,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" check-latest: true cache: true cache-dependency-path: go.sum @@ -177,7 +177,7 @@ jobs: run: git lfs checkout - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" check-latest: true cache: true cache-dependency-path: go.sum @@ -208,7 +208,7 @@ jobs: run: git lfs checkout - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" check-latest: true cache: true cache-dependency-path: go.sum @@ -239,7 +239,7 @@ jobs: run: git lfs checkout - uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" check-latest: true cache: true cache-dependency-path: go.sum diff --git a/.gitignore b/.gitignore index e83a69a504..96e3251977 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,7 @@ vendor/ build/ .vscode .idea + +# docusaurus versioned docs created during build +docs/versioned_docs +docs/versioned_sidebars diff --git a/.mergify.yml b/.mergify.yml index 1c0a6bb81a..d373fe3fb9 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -10,67 +10,43 @@ queue_rules: - "#approved-reviews-by>1" pull_request_rules: - - name: Backport patches to the release/v2.0.x branch - conditions: - - base=main - - label=A:backport/v2.0.x - actions: - backport: - branches: - - release/v2.0.x - - name: Backport patches to the release/v2.4.x-lsm branch - conditions: - - base=main - - label=A:backport/v2.4.x-lsm - actions: - backport: - branches: - - release/v2.4.x-lsm - - name: Backport patches to the release/v3.1.x branch - conditions: - - base=main - - label=A:backport/v3.1.x - actions: - backport: - branches: - - release/v3.1.x - - name: Backport patches to the release/v3.2.x branch + - name: Backport patches to the release/v4.1.x branch conditions: - base=main - - label=A:backport/v3.2.x + - label=A:backport/v4.1.x actions: backport: branches: - - release/v3.2.x - - name: Backport patches to the release/v3.3.x branch + - release/v4.1.x + - name: Backport patches to the release/v4.1.x-lsm branch conditions: - base=main - - label=A:backport/v3.3.x + - label=A:backport/v4.1.x-lsm actions: backport: branches: - - release/v3.3.x - - name: Backport patches to the release/v4.0.x branch + - release/v4.1.x-lsm + - name: Backport patches to the release/v4.2.x branch conditions: - base=main - - label=A:backport/v4.0.x + - label=A:backport/v4.2.x actions: backport: branches: - - release/v4.0.x - - name: Backport patches to the release/v4.1.x branch + - release/v4.2.x + - name: Backport patches to the release/v4.2.x-lsm branch conditions: - base=main - - label=A:backport/v4.1.x + - label=A:backport/v4.2.x-lsm actions: backport: branches: - - release/v4.1.x - - name: Backport patches to the release/v4.1.x-lsm branch + - release/v4.2.x-lsm + - name: Backport patches to the release/v5.x branch conditions: - base=main - - label=A:backport/v4.1.x-lsm + - label=A:backport/v5.x actions: backport: branches: - - release/v4.1.x-lsm \ No newline at end of file + - release/v5.x diff --git a/CHANGELOG.md b/CHANGELOG.md index 893f65a76b..666321b346 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## v5.0.0 +❗ *The provider module should not be used with this version.* + *May 9, 2024* ### DEPENDENCIES @@ -38,6 +40,53 @@ ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) - Revert `PutUnbondingOnHold` behavior to ICS@v1 ([\#1819](https://github.com/cosmos/interchain-security/pull/1819)) +## v4.2.0 + +May 17, 2024 + +### API BREAKING + +- [Provider](x/ccv/provider) + - Assigning a key that is already assigned by the same validator will now be a no-op instead of throwing an error. + ([\#1732](https://github.com/cosmos/interchain-security/pull/1732)) + - Changes the `list-consumer-chains` query to include a `min_power_in_top_N` field, as well as fields for all power shaping parameters of the consumer. + ([\#1863](https://github.com/cosmos/interchain-security/pull/1863)) + +### DEPENDENCIES + +- Bump [CometBFT](https://github.com/cometbft/cometbft) to + [v0.37.6](https://github.com/cometbft/cometbft/releases/tag/v0.37.6). + ([\#1876](https://github.com/cosmos/interchain-security/pull/1876)) +- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to + [v0.47.11](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.11). + ([\#1876](https://github.com/cosmos/interchain-security/pull/1876)) + +### FEATURES + +- [Provider](x/ccv/provider) + - Enable Opt In and Top N chains through gov proposals. + ([\#1587](https://github.com/cosmos/interchain-security/pull/1587)) + - Adding the Partial Set Security (PSS) feature cf. [ADR 015](https://cosmos.github.io/interchain-security/adrs/adr-015-partial-set-security). + PSS enables consumer chains to join ICS as _Top N_ or _Opt In_ chains and enables validators to opt to validate the consumer chains they want. + ([\#1809](https://github.com/cosmos/interchain-security/pull/1809)) + - Introduce power-shaping features for consumer chains. The features: (i) allow us to cap the total number of validators that can validate the consumer chain, (ii) set a cap on the maximum voting power (percentage-wise) a validator can have on a consumer chain, and (iii) introduce allowlist and denylists to restrict which validators are allowed or not to validate a consumer chain. + ([\#1830](https://github.com/cosmos/interchain-security/pull/1830)) + - Changes the `list-consumer-chains` query to include a `min_power_in_top_N` field, as well as fields for all power shaping parameters of the consumer. + ([\#1863](https://github.com/cosmos/interchain-security/pull/1863)) + - Introduces the `consumer-validators` query to retrieve the latest set consumer-validator set for a consumer chain. + ([\#1863](https://github.com/cosmos/interchain-security/pull/1867)) + +### STATE BREAKING + +- [Provider](x/ccv/provider) + - Enable Opt In and Top N chains through gov proposals. + ([\#1587](https://github.com/cosmos/interchain-security/pull/1587)) + - Assigning a key that is already assigned by the same validator will now be a no-op instead of throwing an error. + ([\#1732](https://github.com/cosmos/interchain-security/pull/1732)) + - Adding the Partial Set Security feature cf. [ADR 015](https://cosmos.github.io/interchain-security/adrs/adr-015-partial-set-security). + ([\#1809](https://github.com/cosmos/interchain-security/pull/1809)) + - Introduce power-shaping features for consumer chains. The features: (i) allow us to cap the total number of validators that can validate the consumer chain, (ii) set a cap on the maximum voting power (percentage-wise) a validator can have on a consumer chain, and (iii) introduce allowlist and denylists to restrict which validators are allowed or not to validate a consumer chain. + ([\#1830](https://github.com/cosmos/interchain-security/pull/1830)) ## v4.1.1 diff --git a/Dockerfile b/Dockerfile index c32b2b5787..36eaf5188b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 -FROM golang:1.21-alpine AS is-builder +FROM golang:1.22-alpine AS is-builder ENV PACKAGES curl make git libc-dev bash gcc linux-headers RUN apk add --no-cache $PACKAGES diff --git a/Dockerfile.gaia b/Dockerfile.gaia index de3f1b2ff7..3ecf9e4e72 100644 --- a/Dockerfile.gaia +++ b/Dockerfile.gaia @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 # build latest tagged gaia -FROM golang:1.21-alpine AS gaia-builder +FROM golang:1.22-alpine AS gaia-builder # WORKDIR is set to /go by default ARG USE_GAIA_TAG ENV GAIA_TAG=${USE_GAIA_TAG} @@ -30,7 +30,7 @@ RUN if [ -n "${GAIA_TAG}" ]; \ # if GAIA_TAG is not set, build the latest tagged version else \ git checkout $(git tag | sort -Vr | head -n1); \ - fi + fi # Also replace sdk version in the go.mod if specified RUN if [ -d "/interchain-security/cosmos-sdk" ]; then \ @@ -40,10 +40,10 @@ RUN if [ -d "/interchain-security/cosmos-sdk" ]; then \ RUN go mod tidy # Print the version of the sdk used in the build -RUN go list -m github.com/cosmos/cosmos-sdk +RUN go list -m github.com/cosmos/cosmos-sdk RUN make build -FROM golang:1.21-alpine AS is-builder +FROM golang:1.22-alpine AS is-builder ENV PACKAGES curl make git libc-dev bash gcc linux-headers RUN apk add --no-cache $PACKAGES diff --git a/FEATURES.md b/FEATURES.md index c5d87df857..f9a54e0589 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -2,18 +2,19 @@ The following table indicates the major ICS features available in the [currently active releases](./RELEASES.md#version-matrix): -| Feature | `v3.2.0` | `v3.3.0` | `v3.3.3-lsm` | `v4.0.0` | -|---------|---------:|---------:|-------------:|---------:| -| [Channel initialization: new chains](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#channel-initialization-new-chains) | ✅ | ✅ | ✅ | ✅ | -| [Validator set update](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#validator-set-update) | ✅ | ✅ | ✅ | ✅ | -| [Completion of unbonding operations](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#completion-of-unbonding-operations) | ✅ | ✅ | ✅ | ✅ | -| [Consumer initiated slashing](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#consumer-initiated-slashing) | ✅ | ✅ | ✅ | ✅ | -| [Reward distribution](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#reward-distribution) | ✅ | ✅ | ✅ | ✅ | -| [Consumer chain removal](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#consumer-chain-removal) | ✅ | ✅ | ✅ | ✅ | -| [Key assignment](https://github.com/cosmos/interchain-security/issues/26) | ✅ | ✅ | ✅ | ✅ | -| [Jail throttling](https://github.com/cosmos/interchain-security/issues/404) | ✅ | ✅ | ✅ | ✅ | -| [Soft opt-out](https://github.com/cosmos/interchain-security/issues/851) | ✅ | ✅ | ✅ | ✅ | -| [Channel initialization: existing chains](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#channel-initialization-existing-chains) (aka [Standalone to consumer changeover](https://github.com/cosmos/interchain-security/issues/756)) | ✅ | ✅ | ✅ | ✅ | -| [Cryptographic verification of equivocation](https://github.com/cosmos/interchain-security/issues/732) | ❌ | ✅ | ✅ | ✅ | -| [Jail throttling with retries](https://github.com/cosmos/interchain-security/issues/713) - consumer-side changes | ✅ | ✅ | ✅ | ✅ | -| [Jail throttling with retries](https://github.com/cosmos/interchain-security/issues/713) - [provider-side changes](https://github.com/cosmos/interchain-security/issues/1102) | ❌ | ❌ | ❌ | ✅ | +| Feature | `v3.2.0` | `v3.3.0` | `v3.3.3-lsm` | `v4.0.0` | `v4.1.1` | `v4.1.1-lsm` | +|---------|---------:|---------:|-------------:|---------:|---------:|-------------:| +| [Channel initialization: new chains](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#channel-initialization-new-chains) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Validator set update](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#validator-set-update) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Completion of unbonding operations](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#completion-of-unbonding-operations) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Consumer initiated slashing](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#consumer-initiated-slashing) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Reward distribution](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#reward-distribution) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Consumer chain removal](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#consumer-chain-removal) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Key assignment](https://github.com/cosmos/interchain-security/issues/26) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Jail throttling](https://github.com/cosmos/interchain-security/issues/404) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Soft opt-out](https://github.com/cosmos/interchain-security/issues/851) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Channel initialization: existing chains](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#channel-initialization-existing-chains) (aka [Standalone to consumer changeover](https://github.com/cosmos/interchain-security/issues/756)) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Cryptographic verification of equivocation](https://github.com/cosmos/interchain-security/issues/732) | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Jail throttling with retries](https://github.com/cosmos/interchain-security/issues/713) - consumer-side changes | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Jail throttling with retries](https://github.com/cosmos/interchain-security/issues/713) - [provider-side changes](https://github.com/cosmos/interchain-security/issues/1102) | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | +| [ICS epochs](https://cosmos.github.io/interchain-security/adrs/adr-014-epochs) | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | diff --git a/Makefile b/Makefile index 715eb1acc8..e68df6fd63 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,8 @@ BRANCH := $(shell git rev-parse --abbrev-ref HEAD) COMMIT := $(shell git log -1 --format='%H') # Fetch tags and get the latest ICS version by filtering tags by vX.Y.Z and vX.Y.Z-lsm # using lazy set to only execute commands when variable is used -LATEST_RELEASE ?= $(shell git fetch; git tag -l --sort -v:refname 'v*.?' 'v*.?'-lsm 'v*.??' 'v*.??'-lsm | head -n 1) +# Note: v.5.0.0 is currently excluded from the list as it's a pre-release and will be added back once it's out of pre-release status +LATEST_RELEASE ?= $(shell git fetch; git tag -l --sort -v:refname 'v*.?' 'v*.?'-lsm 'v*.??' 'v*.??'-lsm --no-contains v5.0.0 | head -n 1) # don't override user values ifeq (,$(VERSION)) @@ -246,10 +247,11 @@ proto-update-deps: ### Documentation ### ############################################################################### -build-docs: - @cd docs && ./build.sh +build-docs-deploy: + @cd docs && ./sync_versions.sh && ./build_deploy.sh -.PHONY: build-docs +build-docs-local: + @cd docs && ./build_local.sh ############################################################################### ### Test Traces ### diff --git a/RELEASES.md b/RELEASES.md index 41a2df9cfc..b1d3eefa22 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -63,6 +63,7 @@ All missing minor release versions have been discontinued. | `v3.3.x` | July 10, 2024 | | `v3.3.x-lsm` | July 10, 2024 | | `v4.0.x` | January 24, 2025 | +| `v4.1.x` | January 24, 2025 | **Note**: As of [Gaia v15.1.0](https://github.com/cosmos/gaia/releases/tag/v15.1.0), the Cosmos Hub uses a fork of Cosmos SDK ([v0.47.10-ics-lsm](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.10-ics-lsm)) @@ -81,6 +82,8 @@ Versions of Golang, IBC, Cosmos SDK and CometBFT used by ICS in the currently ac | [v3.3.0](https://github.com/cosmos/interchain-security/releases/tag/v3.3.0) | 1.20 | v7.3.0 | v0.47.5 | v0.37.2 | | [v3.3.3-lsm](https://github.com/cosmos/interchain-security/releases/tag/v3.3.3-lsm) | 1.20 | v7.3.1 | v0.47.10-ics-lsm | v0.37.4 | Provider only (Cosmos Hub specific) | | [v4.0.0](https://github.com/cosmos/interchain-security/releases/tag/v4.0.0) | 1.21 | v7.3.1 | v0.47.7 | v0.37.4 | Provider on >= v4.0.0 backwards compatible with consumers >= v3.2.0 | +| [v4.1.1](https://github.com/cosmos/interchain-security/releases/tag/v4.1.1) | 1.21 | v7.4.0 | v0.47.10 | v0.37.4 | +| [v4.1.1-lsm](https://github.com/cosmos/interchain-security/releases/tag/v4.1.1-lsm) | 1.21 | v7.4.0 | v0.47.12-ics-lsm | v0.37.4 | Provider only (Cosmos Hub specific) | **Note:** For a list of major ICS features available in the currently active releases, see [FEATURES.md](./FEATURES.md). @@ -90,11 +93,12 @@ A MAJOR version of ICS will always be backwards compatible with the previous MAJ The following table indicates the compatibility of currently active releases: -| Consumer | Provider | `v3.2.0` | `v3.3.0` | `v3.3.3-lsm` | `v4.0.0` | -|----------|----------|----------|----------|--------------|----------| -| `v3.2.0` || ✅ | ✅ (1) | ✅ | ✅ | -| `v3.3.0` || ✅ (1) | ✅ | ✅ | ✅ | -| `v4.0.0` || ✅ (1)| ✅ (1)| ✅ (1) | ✅ | +| Consumer | Provider | `v3.2.0` | `v3.3.0` | `v3.3.3-lsm` | `v4.0.0` | `v4.1.1-lsm` | +|----------|----------|----------|----------|--------------|----------|--------------| +| `v3.2.0` || ✅ | ✅ (1) | ✅ | ✅ | ✅ | +| `v3.3.0` || ✅ (1) | ✅ | ✅ | ✅ | ✅ | +| `v4.0.0` || ✅ (1)| ✅ (1)| ✅ (1) | ✅ | ✅ | +| `v4.1.1` || ✅ (1)| ✅ (1)| ✅ (1) | ✅ | ✅ | #### Notes diff --git a/app/provider/app.go b/app/provider/app.go index 32bb17050a..4c998bdc13 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -145,6 +145,7 @@ var ( paramsclient.ProposalHandler, ibcproviderclient.ConsumerAdditionProposalHandler, ibcproviderclient.ConsumerRemovalProposalHandler, + ibcproviderclient.ConsumerModificationProposalHandler, ibcproviderclient.ChangeRewardDenomsProposalHandler, }, ), @@ -519,12 +520,14 @@ func New( authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) - transferModule := transfer.NewAppModule(app.TransferKeeper) - ibcmodule := transfer.NewIBCModule(app.TransferKeeper) + // Add an IBC middleware callback to track the consumer rewards + var transferStack porttypes.IBCModule + transferStack = transfer.NewIBCModule(app.TransferKeeper) + transferStack = ibcprovider.NewIBCMiddleware(transferStack, app.ProviderKeeper) // create static IBC router, add transfer route, then set and seal it ibcRouter := porttypes.NewRouter() - ibcRouter.AddRoute(ibctransfertypes.ModuleName, ibcmodule) + ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack) ibcRouter.AddRoute(providertypes.ModuleName, providerModule) app.IBCKeeper.SetRouter(ibcRouter) @@ -556,7 +559,7 @@ func New( ibc.NewAppModule(app.IBCKeeper), ibctm.NewAppModule(), params.NewAppModule(app.ParamsKeeper), - transferModule, + transfer.NewAppModule(app.TransferKeeper), providerModule, ) @@ -570,6 +573,7 @@ func New( paramsclient.ProposalHandler, ibcproviderclient.ConsumerAdditionProposalHandler, ibcproviderclient.ConsumerRemovalProposalHandler, + ibcproviderclient.ConsumerModificationProposalHandler, ibcproviderclient.ChangeRewardDenomsProposalHandler, }, ), diff --git a/docs/README.md b/docs/README.md index aaba2fa1e1..4c4146ca4b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,17 +1,17 @@ # Website -This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. +This website is built using [Docusaurus 3](https://docusaurus.io/), a modern static website generator. ### Installation ``` -$ yarn +$ npm install ``` ### Local Development ``` -$ yarn start +$ npm run start ``` This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. @@ -19,23 +19,55 @@ This command starts a local development server and opens up a browser window. Mo ### Build ``` -$ yarn build +$ npm run build ``` This command generates static content into the `build` directory and can be served using any static contents hosting service. -### Deployment -Using SSH: +# Adding versions +To add/remove versions from the page you can modify `versions.json`. + +At the time of writing it looked like this: +```json +[ + "v4.0.0", + "v4.1.0", + "v5.0.0-rc0" +] ``` -$ USE_SSH=true yarn deploy -``` -Not using SSH: +You can remove any version that you no longer need and the build process will remove it from the final page. + + +# Accessing versioned docs locally +```shell +# from interchain-security/docs run: +./sync_versions.sh ``` -$ GIT_USER= yarn deploy + +The script above will create `versioned_docs` and `versioned_sidebars` directories inside `interchain-security/docs`. + +To view the docs run: + +```shell +npm run start ``` -If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. +Remember to check back out to your working branch. Running `./sync_versions.sh` will leave you in a detached head state. +(simply run `git checkout ) + +## Note: +The script will exit if you have uncommitted changes. +The script switches branches while building the versioned docs - **please note that this could overwrite your local changes**. + + +# Legacy documentation + +`legacy-docs-page` [branch](https://github.com/cosmos/interchain-security/tree/legacy-docs-page) contains documentation for versions `<= v4.0.0`. These versions were built using docusaurus `v2.4.0` which is not compatible with docusaurus `v3.x` used at the time of writing. It was not feasible to port the legacy docs from `v2.4.0` because `v3.x` is not compatible with it and it required changing all release branches and cutting patch releases. + +The `./docs/legacy` directory on `legacy-docs-page` was created manually, by modifying `docusaurus.config.js` and `versions.json` on `https://github.com/cosmos/interchain-security/releases/v3.3.1-lsm` and generating the static pages manually using `npm run build`. + +The `./docs/legacy` directory gets included into the rest of the documentation using a simple `cp` command during the deploy process using the [build_deploy.sh](./build_deploy.sh) script. It is **not** included during local builds. diff --git a/docs/build.sh b/docs/build.sh deleted file mode 100755 index b39a0539a6..0000000000 --- a/docs/build.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# This builds docs using docusaurus. -COMMIT=$(git rev-parse HEAD) -echo "building docusaurus main docs" -(git clean -fdx && git reset --hard && git checkout $COMMIT) -npm ci && npm run build -mv build ~/output -echo "done building docusaurus main docs" -# echo $DOCS_DOMAIN > ~/output/CNAME diff --git a/docs/build_local.sh b/docs/build_local.sh new file mode 100755 index 0000000000..b93f147b0a --- /dev/null +++ b/docs/build_local.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +echo "building docusaurus from local branch" +npm ci && npm run build +echo "done building docusaurus from local docs" diff --git a/docs/docs/adrs/adr-005-cryptographic-equivocation-verification.md b/docs/docs/adrs/adr-005-cryptographic-equivocation-verification.md index 4438b83239..1e1a3f08cf 100644 --- a/docs/docs/adrs/adr-005-cryptographic-equivocation-verification.md +++ b/docs/docs/adrs/adr-005-cryptographic-equivocation-verification.md @@ -31,7 +31,7 @@ multiple nodes, called primary and witness nodes. Light clients download new headers committed on chain from a primary. Headers can be verified in two ways: sequentially, where the block height of headers is serial, or using skipping. This second verification method allows light clients to download headers -with nonconsecutive block height, where some intermediate headers are skipped (see [Tendermint Light Client, Figure 1 and Figure 3](https://arxiv.org/pdf/2010.07031.pdf)). +with nonconsecutive block height, where some intermediate headers are skipped (see [Tendermint Light Client, Figure 1 and Figure 3](https://arxiv.org/pdf/2010.07031)). Additionally, light clients are cross-checking new headers obtained from a primary with witnesses to ensure all nodes share the same state. A light client attack occurs when a Byzantine validator sends invalid headers to a light client. diff --git a/docs/docs/adrs/adr-014-epochs.md b/docs/docs/adrs/adr-014-epochs.md index fc669e9b36..7637078cf0 100644 --- a/docs/docs/adrs/adr-014-epochs.md +++ b/docs/docs/adrs/adr-014-epochs.md @@ -10,7 +10,7 @@ title: Epochs ## Status -Proposed +Accepted ## Context diff --git a/docs/docs/adrs/adr-015-partial-set-security.md b/docs/docs/adrs/adr-015-partial-set-security.md index e89c46b5cf..0c3a331dfb 100644 --- a/docs/docs/adrs/adr-015-partial-set-security.md +++ b/docs/docs/adrs/adr-015-partial-set-security.md @@ -10,7 +10,7 @@ title: Partial Set Security ## Status -Proposed +Accepted ## Context diff --git a/docs/docs/adrs/adr-016-securityaggregation.md b/docs/docs/adrs/adr-016-securityaggregation.md new file mode 100644 index 0000000000..0709f4a582 --- /dev/null +++ b/docs/docs/adrs/adr-016-securityaggregation.md @@ -0,0 +1,203 @@ +--- +sidebar_position: 17 +title: Security aggregation +--- +# ADR 016: Security aggregation + +## Changelog + +- 2024-04-24: Initial draft of ADR + +## Status + +Proposed + +## Context + +Security Aggregation enables staking of tokens from external sources such as Ethereum or Bitcoin to Cosmos blockchains. By integrating Security Aggregation, a Cosmos blockchain can be secured by both native tokens and external tokens (e.g. ETH, BTC). + +Security Aggregation consists of the following parts: + +- A mechanism for delegating external tokens to Cosmos validators, such as Babylon or EigenLayer AVS contract. +- An oracle that tracks how much external stake has been delegated to each Cosmos validator and provides price feeds for external tokens. +- Power mixing: a mechanism to combine external and native stake to derive the power of each validator. +- A reward distribution protocol that enables sending back rewards to the external source. + +External staking information is received from an oracle together with price information of related stakes. +The CosmosLayer derives validator powers based on external and native staking information and initiates rewarding of external depositors. + +This ADR describes the _Cosmos modules_ of the solution. + +## Alternative Approaches + +### Rewards +As an alternative to sending rewards back to the external chains, stakers could be rewarded on the Cosmos chain. +This would require a mapping of external addresses to addresses on Cosmos chain for each staker on external source. +In addition detailed external staking information such as staking addresses, amount of stakes per staker and validator, etc. have to be provided by the oracle. + +## Decision + +### Rewards will be sent back to external chains instead of paying rewards for external stakers on Cosmos chain +Rewards will be sent back to external chains instead of paying rewards for external stakers on Cosmos chain +- due to amount of additional staking information to be sent and tracked by the oracle +- due to the additional complexity of managing external and Cosmos addresses + +## Detailed Design + +The `Power Mixing` feature and `Reward Distribution` protocol are an integral part of the Security Aggregation solution. +The `Power Mixing` module provides the capability of deriving validator power based on stake originated from external sources such as Ethereum/Bitcoin and the native staking module. +The `Reward Distribution` manages the process of sending rewards to external stakers. + +### Power Mixing + +Power Mixing provides the final validator powers based on staking information of the native chain and the external stakes. The information about external staking and related price feeds are received from an oracle. +Once the final validator powers are determined the result is submitted to the underlying CometBFT consensus layer by [updating](https://docs.cometbft.com/v0.38/spec/abci/abci++_app_requirements#updating-the-validator-set) the validator set. + +Requirements: + +- validator updates are performed on each EndBlock +- a validator's power is determined based on its native on-chain stakes and external stakes +- price information of staked tokens is used to determine a validator’s power, e.g. price ratio (price of native on-chain token / price of external stake) +- price information of native/external tokens are received from an oracle +- staking information from external sources received from the oracle +- native staking information are received from the `Cosmos SDK Staking Module` +- set of validator stakes from oracle always have the current price, full set of validators, and current stakes + +The `Power Mixing` implementation +- queries current validators and their powers from [x/staking](https://github.com/cosmos/cosmos-sdk/blob/a6f3fbfbeb7ea94bda6369a7163a523e118a123c/x/staking/types/staking.pb.go#L415) +and from oracle (see below). +- calculates power updates by mixing power values of external and internal sources +Following pseudocode snippet shows a possible implementation of how power mixing +feature works. +```golang +// PowerSource is an abstract entity providing validator powers which +// are used by the mixer. This can be an oracle, staking module or an +// IBC connected bridge. +type PowerSource interface { + GetValidatorUpdates() []abci.ValidatorUpdate +} + +// MixPowers calculates power updates by mixing validator powers from different sources +func (k *Keeper) MixPowers(source ...PowerSource) []abci.ValidatorUpdate { + var valUpdate []abci.ValidatorUpdate + for _, ps := range source { + // mix powers from two sets of validator updates an return set of validator updates + // with aggregated powers + valUpdate = mixPower(valUpdate, ps.GetValidatorUpdates()) + } + return valUpdate +} + +func (k *keeper) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + // GetPowerSources (including local staking module) + registeredPowerSource := GetPowerSources() + return k.MixPowers(registeredPowerSource...) +} +``` + +#### Integration with `ICS provider` +The provider module updates the validator set on CometBFT instead of the SDK staking module (x/staking). The provider implementation will intervene in this behavior and ensure that the validator updates are taken from the `Power Mixing` feature. + +External power sources are managed by the provider module. Only registered power sources can provide input to the `Power Mixing` feature. +Power sources will be assigned a unique identifier which will be used by the oracle, provider module and the power mixing and rewarding feature. + +Updates with the next validator set are sent to consumer chains on each epoch (see `EndBlockVSU()`). +When collecting the validator updates for each consumer chain (see [`QueueVSCPackets()`](https://pkg.go.dev/github.com/cosmos/interchain-security/v4/x/ccv/provider/keeper#Keeper.QueueVSCPackets)), the validator powers of the bonded validators will be updated with the validator powers from the external sources using the `Power Mixing` module. +These updates are sent as part of the VSC packets to all registered consumer chains. + +#### Integration with `ICS consumer` +Consumer chains receive validator updates as part of VSC packets from the provider. +These packets contain validator powers which were already mixed with external staked powers. + + +### Queries + +```protobuf +// GetValidatorUpdates returns the power mixed validator results from the provided sources +service Query { + rpc GetValidatorUpdates(PowerMixedValUpdateRequest) PowerMixedValUpdateResponse {}; +} + +// PowerMixedValUpdateRequest contains the list of power sources on which the +// power mixing should be based on +message PowerMixedValUpdateRequest { + repeated PowerSource sources; +} + +// PowerMixedValUpdateResponse returns the validator set with the updated powers +// from the power mixing feature +message PowerMixedValUpdateResponse { + repeated abci.ValidatorUpdate val_set +} +``` + + +The following queries will be provided by the oracle + +```protobuf +service Query { + rpc GetExtValidators(GetExtValidatorRequest) returns (ExtValidatorsResponse) { + option (google.api.http).get = "oracle/v1/get_validators"; + }; +} + +message GetExtValidatorRequest {} + +// ExtValidatorsResponse is the response from GetExtValidators queries +message ExtValidatorsResponse { + repeated ExtValPower powers; +} + +// ExtValPower represents a validator with its staking and token information, +// where: +// `power_source_identifier` is the identifier of the registered power source +// `validator_address` is the address of the validator +// `stakes` is the total amount of stakes for a validator +// `denom` is the source token of the stake e.g. ETH,BTC +// `price_ratio` is the ratio of price of the external token to the price of the 'local' token +message ExtValPower { + string power_source_identifier; + string validator_address; + uint64 stakes; + string denom; + float price_ratio; +} + +// GetPrice returns a price feed for a given token +service Query { + rpc GetPrice(GetPriceRequest) returns (GetPriceResponse) { + option (google.api.http).get = "/oracle/v1/get_price"; + }; +} +``` + +For security reasons the amount of external stakes needs to be limited. Limitation of external staking could be driven by governance and is not subject of this version of the ADR. + +### Reward Handler + +For native staked tokens the `Distribution Module` of the Cosmos SDK is taking care of sending the rewards to stakers. +For stakes originated from external chains (Ethereum/Bitcoin) the `Reward Handler` module sends rewards to EigenLayer/Babylon. +The transfer of rewards is done using a bridge between the Cosmos chain and the external provider chain. + +Note: currently there's no support paying rewards on EigenLayer (see [here](https://www.coindesk.com/tech/2024/04/10/eigenlayer-cryptos-biggest-project-launch-this-year-is-still-missing-crucial-functionality/)) + +## Consequences + +### Positive + +* Allow external depositors to stake their tokens to secure a Cosmos chain + +### Negative +* Dependency to external sources e.g (price feeds) for validator power calculation +* Security impact + +### Neutral +* Additional complexity for staking + +## Questions: +- Slashing: subject of this ADR? (Defined but [not activated](https://www.coindesk.com/tech/2024/04/10/eigenlayer-cryptos-biggest-project-launch-this-year-is-still-missing-crucial-functionality/) currently on EigenLayer). + +## References + +- [EigenLayer](https://docs.eigenlayer.xyz/) +- [Babylon](https://babylonchain.io/) diff --git a/docs/docs/adrs/adr-017-allowing-inactive-validators.md b/docs/docs/adrs/adr-017-allowing-inactive-validators.md new file mode 100644 index 0000000000..9a3715f135 --- /dev/null +++ b/docs/docs/adrs/adr-017-allowing-inactive-validators.md @@ -0,0 +1,122 @@ +--- +sidebar_position: 18 +title: ICS with Inactive Provider Validators +--- +# ADR 017: ICS with Inactive Provider Validators + +## Changelog +* 15th May 2024: Initial draft + + +## Status + +Proposed + +## Context + +Currently, only validators in the active set on the provider can validate on consumer chains, which limits the number of validators that can participate in Interchain Security (ICS). +Validators outside of the active set might be willing +to validate on consumer chains, but we might not want to make the provider validator set larger, e.g. to not put more strain on the consensus engine. +This runs the risk of leaving consumer chains with too few validators. + +The purpose of this ADR is to allow validators that are *not* part of the consensus process on the provider chain (because they are inactive) +to validate on consumer chains. + +In the context of this ADR, "consensus validator set" is the set of validators participating in the consensus protocol, and "staking validator set" is the set of validators viewed as active by the staking module. + +Currently, the staking module, provider module, and CometBFT interact in this way: + +![inactivevals_before.png](../../figures/inactivevals_before.png) + +The staking module keeps a list of validators. The `MaxValidators` validators with the largest amount of stake are "active" validators. `MaxValidators` is a parameter of the staking module. The staking module sends these validators to CometBFT to inform which validators make up the next consensus validators, that is, the set of validators participating in the consensus process. Separately, the provider module reads the list of bonded validators and sends this to the consumer chain, after shaping it according to which validators are opted in and the parameters set by the consumer chain for allowlist, denylist, etc. + +## Decision + +The proposed solution to allow validators that are not participating in the consensus process on the provider (inactive validators) is to change 3 main things: + +a) increase the `MaxValidators` parameter of the staking module + +b) do *not* take the updates for CometBFT directly from the bonded validators in the staking module, by wrapping the staking modules `EndBlocker` with a dummy EndBlocker that doesn't return any validator updates. Instead, we adjust the provider module to return validator updates on its EndBlocker. These validator updates are obtained by *filtering* the bonded validators to send only the first `MaxProviderConsensusValidators` (sorted by largest amount of stake first) many validators to CometBFT + +c) use the enlarged list of bonded validators from the staking module as basis for the validator set that the provider module sends to consumer chains (again after applying power shaping and filtering out validatiors that are not opted in). + +In consequence, the provider chain can keep a reasonably-sized consensus validator set, while giving consumer chains a much larger pool of potential validators. + +![inactivevals_after.png](../../figures/inactivevals_after.png) + + +Some additional considerations: + +* Migration: In the migration, the last consensus validator set will be set to the last active validator set from the view of the staking module. Existing consumer chains are migrated to have a validator set size cap (otherwise, they could end up with a huge validator set including all the staking-but-not-consensus-active validators from the provider chain) +* Slashing: Validators that are not part of the active set on the provider chain can still be jailed for downtime on a consumer chain (via an Interchain Security SlashPacket sent to the provider, who will then jail the validator), but they *are not* slashed for downtime on the provider chain. +This is achieved without any additional changes to the slashing module, because the slashing module checks for downtime by looking at the consensus participants reported by CometBFT, and thus with the proposed solution, validators that are not part of the consensus validators on the provider chain are not considered for downtime slashing (see https://github.com/cosmos/cosmos-sdk/blob/v0.47.11/x/slashing/abci.go#L22). +* Rewards: Validators that are not part of the active set on the provider chain can still receive rewards on the consumer chain, but they *do not* receive rewards from the provider chain. This change is +achieved without further changes to staking or reward distributions, because similar to downtime, rewards are based on the consensus validator set (see https://github.com/cosmos/cosmos-sdk/blob/v0.47.11/x/distribution/abci.go#L28) + + +### Changes to the state + +The following changes to the state are required: + +* Introduce the `MaxProviderConsensusValidators` parameter to the provider module, which is the number of validators that the provider module will send to consumer chains. +* Store the provider consensus validator set in the provider module state under the `LastProviderConsensusValsPrefix` key. This is the last set of validators that the provider sent to the consensus engine. This is needed to compute the ValUpdates to send to the consensus engine (by diffing the current set with this last sent set). +* Increase the `MaxValidators` parameter of the staking module to the desired size of the potential validator +set of consumer chains. + +## Risk Mitigations + +To mitigate risks from validators with little stake, we introduce a minimum stake requirement for validators to be able to validate on consumer chains, which can be set by each consumer chain independently, with a default value set by the provider chain. + +Additionally, we indepdently allow individual consumer chains to disable this feature, which will disallow validators from outside the provider active set from validating on the consumer chain and revert them to the previous behaviour of only considering validators of the provider that are part of the active consensus validator set. + +Additional risk mitigations are to increase the active set size slowly, and to monitor the effects on the network closely. For the first iteration, we propose to increase the active set size to 200 validators (while keeping the consensus validators to 180), thus letting the 20 validators with the most stake outside of the active set validate on consumer chains. + +## Consequences + +### Positive + +* Validators outside of the active set can validate on consumer chains without having an impact on the consensus engine of the provider chain +* Consumer chains can have a much larger validator set than the provider chain if they prefer this e.g. for decentralization reasons +* Consumer chain teams can, with much less cost than today, start up their own consumer chain node to keep the chain running (in a centralized manner) even if no hub validators have opted in to validate on the chain. This is useful to stop the chain from ending up with an empty validator set and becoming recoverable only with a hardfork + +### Negative + +Allowing validators from the inactive set brings with it some additional risks. +In general, consumer chains will now face some of the problems also faced by standalone chains. It’s reasonable to assume that the validator set on the hub has a minimum amount of operational quality due to being battle tested and decentralized, and consumer chains with validators from outside the hub active set cannot rely on this as much anymore. + + +#### Sybil attacks + +With the restricted size of the active set today, it’s clear that the set is at least minimally competitive and it is not trivial to spin up multiple nodes as a validator. + +When we make the “potential validator set” much larger, we should assume that it becomes much less competitive to be part of that set, and thus trivial for single entities to control many of those validators. + +#### Reputational damage is not a deterrent + +For validators in the active set, we typically assume that if they would misbehave, they pay a large reputational cost. This represents delegators deciding to switch validators (potentially even on chains other than the one the misbehaviour happened on), and loss of credibility in the ecosystem. With the much larger active set, it seems prudent to assume that reputational damage is not a deterrent for many validators. They might only have minimal amounts of delegated stake and control most of it themselves, so they might not be deterred from performing actions that would usually bring reputational damage. + +#### Additional negative consequences +* The provider keeper will need to implement the staking keeper interface, and modules need to be wired up to either the staking or provider keeper, depending on whether they need the consensus or staking validator set +* This will impact how future modules are integrated, since we will need to consider whether those modules should consider the consensus validators or the bonded validators (which other modules might assume to be the same) + +### Neutral + +* There might be validators that are bonded, but not validating on any chain at all. This is not a problem, but it might be a bit confusing. + +## Alternative considerations + +### Modifying the staking module + +We could instead adapt the *staking module* with a similar change. +This might be better if it turns out that the staking module active set is used in many other places. + +### Allowing unbonding validators to validate + +Instead of increasing the active set size, we could allow validators that are unbonded (but still exist on the provider) to validate consumer chains. +For this, we would need to: +* Modify the VSC updates to consider the set of all validators, even unbonded ones, instead of just active ones +* Adjust our downtime jailing/equivocation slashing logic to work correctly with unbonded validators. This is very hard, because redelegations are not usually tracked for unbonded validators. + +## References + +* [Security Aggregation](./adr-016-securityaggregation.md) has similar concerns where the staking validator set will differ from the consensus validator set diff --git a/docs/docs/adrs/intro.md b/docs/docs/adrs/intro.md index 0ba2b5096e..fc7d06a152 100644 --- a/docs/docs/adrs/intro.md +++ b/docs/docs/adrs/intro.md @@ -40,12 +40,14 @@ To suggest an ADR, please make use of the [ADR template](./adr-template.md) prov - [ADR 009: Soft Opt-Out](./adr-009-soft-opt-out.md) - [ADR 010: Standalone to Consumer Changeover](./adr-010-standalone-changeover.md) - [ADR 013: Slashing on the provider for consumer equivocation](./adr-013-equivocation-slashing.md) +- [ADR 014: Epochs](./adr-014-epochs.md) +- [ADR 015: Partial Set Security](./adr-015-partial-set-security.md) ### Proposed - [ADR 011: Improving testing and increasing confidence](./adr-011-improving-test-confidence.md) -- [ADR 014: Epochs](./adr-014-epochs.md) -- [ADR 015: Partial Set Security](./adr-015-partial-set-security.md) +- [ADR 016: Security aggregation](./adr-016-securityaggregation.md) +- [ADR 017: ICS with Inactive Provider Validators](./adr-017-allowing-inactive-validators.md) ### Rejected diff --git a/docs/docs/consumer-development/app-integration.md b/docs/docs/consumer-development/app-integration.md index 81d9141242..73c034d073 100644 --- a/docs/docs/consumer-development/app-integration.md +++ b/docs/docs/consumer-development/app-integration.md @@ -28,5 +28,6 @@ This allows the consumer chain to leverage those modules while also using the `x With these modules enabled, the consumer chain can mint its own governance tokens, which can then be delegated to prominent community members which are referred to as "representatives" (as opposed to "validators" in standalone chains). The token may have different use cases besides just voting on governance proposals. ## Standalone chain to consumer chain changeover -This feature is being actively worked on. Information will be provided at a later time. + +See the [standalone chain to consumer chain changeover guide](./changeover-procedure.md) for more information on how to transition your standalone chain to a consumer chain. diff --git a/docs/docs/consumer-development/changeover-procedure.md b/docs/docs/consumer-development/changeover-procedure.md index 0a3954283a..332bade599 100644 --- a/docs/docs/consumer-development/changeover-procedure.md +++ b/docs/docs/consumer-development/changeover-procedure.md @@ -150,7 +150,7 @@ Additionally, reach out to the community via the [forum](https://forum.cosmos.ne - [ ] determine consumer chain parameters to be put in the proposal - [ ] take note to include a link to your onboarding repository -Example of a consumer chain addition proposal. +Example of a consumer chain addition proposal (compare with the [ConsumerAdditionProposal](./onboarding.md#3-submit-a-governance-proposal) in the ICS Provider Proposals section for chains that *launch* as consumers): ```js // ConsumerAdditionProposal is a governance proposal on the provider chain to spawn a new consumer chain or add a standalone chain. @@ -167,7 +167,6 @@ Example of a consumer chain addition proposal. // Must be unique from all other consumer chain ids of the executing provider chain. "chain_id": "standalone-1", // Initial height of new consumer chain. - // For a completely new chain, this will be {0,1}. "initial_height" : { // must correspond to current revision number of standalone chain // e.g. standalone-1 => "revision_number": 1 diff --git a/docs/docs/consumer-development/onboarding.md b/docs/docs/consumer-development/onboarding.md index f4f022c946..9f438dd8d4 100644 --- a/docs/docs/consumer-development/onboarding.md +++ b/docs/docs/consumer-development/onboarding.md @@ -41,12 +41,15 @@ Additionally, reach out to the community via the [forum](https://forum.cosmos.ne - [ ] determine consumer chain parameters to be put in the proposal - [ ] take note to include a link to your onboarding repository - [ ] describe the purpose and benefits of running your chain +- [ ] determine whether your chain should be an Opt-In chain or a Top N chain (see [Partial Set Security](../features/partial-set-security.md)) +- [ ] if desired, decide on power-shaping parameters (see [Power Shaping](../features/power-shaping.md)) Example of a consumer chain addition proposal. ```js // ConsumerAdditionProposal is a governance proposal on the provider chain to spawn a new consumer chain. -// If it passes, then all validators on the provider chain are expected to validate the consumer chain at spawn time. +// If it passes, if the top_N parameter is not equal to 0, the top N% of validators by voting power on the provider chain are expected to validate the consumer chain at spawn time. +// Otherwise, only validators that opted in during the proposal period are expected to validate the consumer chain at spawn time. // It is recommended that spawn time occurs after the proposal end time. { // Title of the proposal @@ -69,7 +72,7 @@ Example of a consumer chain addition proposal. // Hash of the consumer chain binary that should be run by validators on chain initialization. // It is used for off-chain confirmation of binary validity by validators and other parties. "binary_hash": "376cdbd3a222a3d5c730c9637454cd4dd925e2f9e2e0d0f3702fc922928583f1", - // Time on the provider chain at which the consumer chain genesis is finalized and all validators + // Time on the provider chain at which the consumer chain genesis is finalized and validators // will be responsible for starting their consumer chain validator node. "spawn_time": "2023-02-28T20:40:00.000000Z", // Unbonding period for the consumer chain. @@ -97,13 +100,34 @@ Example of a consumer chain addition proposal. // Note that transfer_channel_id is the ID of the channel end on the consumer chain. // it is most relevant for chains performing a standalone to consumer changeover // in order to maintain the existing ibc transfer channel - "distribution_transmission_channel": "channel-123" + "distribution_transmission_channel": "channel-123", + // Corresponds to the percentage of validators that have to validate the chain under the Top N case. + // For example, 53 corresponds to a Top 53% chain, meaning that the top 53% provider validators by voting power + // have to validate the proposed consumer chain. top_N can either be 0 or any value in [50, 100]. + // A chain can join with top_N == 0 as an Opt In chain, or with top_N ∈ [50, 100] as a Top N chain. + "top_N": 95, + // Corresponds to the maximum power (percentage-wise) a validator can have on the consumer chain. For instance, if + // `validators_power_cap` is set to 32, it means that no validator can have more than 32% of the voting power on the + // consumer chain. Note that this might not be feasible. For example, think of a consumer chain with only + // 5 validators and with `validators_power_cap` set to 10%. In such a scenario, at least one validator would need + // to have more than 20% of the total voting power. Therefore, `validators_power_cap` operates on a best-effort basis. + "validators_power_cap": 0, + // Corresponds to the maximum number of validators that can validate a consumer chain. + // Only applicable to Opt In chains. Setting `validator_set_cap` on a Top N chain is a no-op. + "validator_set_cap": 0, + // Corresponds to a list of provider consensus addresses of validators that are the ONLY ones that can validate + // the consumer chain. + "allowlist": [], + // Corresponds to a list of provider consensus addresses of validators that CANNOT validate the consumer chain. + "denylist": [] } ``` ## 4. Launch -The consumer chain starts after at least 66.67% of all provider's voting power comes online. The consumer chain is considered interchain secured once the appropriate CCV channels are established and the first validator set update is propagated from the provider to the consumer +The consumer chain starts after at least 66.67% of its voting power comes online. +Note that this means 66.67% of the voting power in the *consumer* validator set, which will be comprised of all validators that either opted in to the chain or are part of the top N% of the provider chain (and are thus automatically opted in). +The consumer chain is considered interchain secured once the appropriate CCV channels are established and the first validator set update is propagated from the provider to the consumer - [ ] provide a repo with onboarding instructions for validators (it should already be listed in the proposal) - [ ] genesis.json with ccv data populated (MUST contain the initial validator set) diff --git a/docs/docs/features/democracy-modules.md b/docs/docs/features/democracy-modules.md index a138bb0413..5add40c67e 100644 --- a/docs/docs/features/democracy-modules.md +++ b/docs/docs/features/democracy-modules.md @@ -229,7 +229,7 @@ func NewApp(...) { The `x/ccv/democracy/governance` module extends the `x/governance` module with the functionality to filter proposals. :::tip -Consumer chains can limit in the types of governance proposals that can be executed on chain to avoid inadvertant changes to interchain security protocol that could affect security properties. +Consumer chains can limit in the types of governance proposals that can be executed on chain to avoid inadvertent changes to interchain security protocol that could affect security properties. ::: The module uses `AnteHandler` to limit the types of proposals that can be executed. diff --git a/docs/docs/features/key-assignment.md b/docs/docs/features/key-assignment.md index 1906eb8b78..85dcb8e074 100644 --- a/docs/docs/features/key-assignment.md +++ b/docs/docs/features/key-assignment.md @@ -81,6 +81,11 @@ To change your key, simply repeat all of the steps listed above. Take note that To remove a key, simply switch it back to the consensus key you have assigned on the provider chain by following steps in the `Adding a key` section and using your provider consensus key. +:::warning +Validators are strongly recommended to assign a separate key for each consumer chain +and **not** reuse the provider key across consumer chains for security reasons. +::: + ## Querying proposed consumer chains To query the consumer addition proposals that are in the voting period, you can use the following command on the provider: diff --git a/docs/docs/features/partial-set-security.md b/docs/docs/features/partial-set-security.md new file mode 100644 index 0000000000..6405fe092b --- /dev/null +++ b/docs/docs/features/partial-set-security.md @@ -0,0 +1,33 @@ +--- +sidebar_position: 5 +--- + +# Partial Set Security + +Partial Set Security (PSS) allows consumer chains to leverage only a subset of validators from the provider chain, which offers more flexibility than the traditional Replicated Security model. By introducing the top_N parameter, each consumer chain can choose the extent of security needed: + + * Top N: Requires the top N% validators from the provider chain to secure the consumer chain. This guarantees that the validators with the most power on the provider will validate the consumer chain, while others can voluntarily opt in. + + * Opt-In: If the `top_N` parameter is set to zero, no validator is mandated to secure the consumer chain. Instead, any validator from the provider chain can opt in using a dedicated transaction. + +An advantage of a Top N chain is that the consumer chain is guaranteed to receive at least a certain fraction of the market cap of the provider chain in security. In turn, this chain needs to be approved by governance, since validators will be forced to run the chain. Thus, Top N chains should typically expect to need to provide a strong case for why they should be added to the provider chain, and they should make sure they offer enough rewards to incentivize validators and delegators to vote for their proposal. + +Opt-In chains, on the other hand, are more flexible. While for technical reasons, they are also currently added via governance proposals, since validators are never forced to validate these chains and simply opt in if they want to, they should typically expect to get their proposals approved much more easily compared to Top N chains, since validators that do not want to validate the chain can simply choose not to opt in. +However, opt in chains do not get a fixed amount of security as a relation of the market cap of the provider as top N chains do, so opt in chains might want to keep an eye on how many validators have opted in to validate their chain and adjust their reward emissions accordingly to incentivize validators. + +:::tip +Partial Set Security is handled only by the provider chain - the consumer chains are simply sent validator sets, and they are not aware that this represents only a subset of the provider chain's validator set. +::: + +:::caution +Both Opt In and Top N chains currently require a governance proposal to be added to the provider chain. + +For Top N chains, this is also the long term vision for how they are launched. + +For Opt In chains, this is a temporary measure to prevent issues around chain ID squatting, i.e. someone could spuriously register many desirable chain IDs of upcoming consumer chain and simply deny legitimate consumer chains from using them. Eventually, the plan is to allow launching Opt In chains permissionlessly without going through governance, with quality control being handled by the market of validators deciding which chains they would like to validate on. +::: + +:::tip +A running Top N consumer chain might want to become an Opt-In chain or vice versa. This can be achieved by issuing +a [`ConsumerModificationProposal`](./proposals.md#consumermodificationproposal). +::: \ No newline at end of file diff --git a/docs/docs/features/power-shaping.md b/docs/docs/features/power-shaping.md new file mode 100644 index 0000000000..2f51aef8f0 --- /dev/null +++ b/docs/docs/features/power-shaping.md @@ -0,0 +1,66 @@ +# Power Shaping + +To give consumer chains more flexibility in choosing their validator set, Interchain Security offers +several "power shaping" mechanisms for consumer chains. + +These are: +1) **Capping the size of the validator set**: The consumer chain can specify a maximum number of validators it +wants to have in its validator set. This can be used to limit the number of validators in the set, which can +be useful for chains that want to have a smaller validator set for faster blocks or lower overhead. If more validators +than the maximum size have opted in on a consumer chain, only the validators with the highest power, up to the specified +maximum, will validate the consumer chain. +:::info +This is only applicable to Opt In chains (chains with Top N = 0). +::: +1) **Capping the fraction of power any single validator can have**: The consumer chain can specify a maximum fraction +of the total voting power that any single validator in its validator set should have. +This is a security measure with the intention of making it harder for a single large validator to take over a consumer chain. This mitigates the risk of an Opt In chain with only a few validators being dominated by a validator with a large amount of stake opting in. +For example, setting this fraction to e.g. 33% would mean that no single validator can have more than 33% of the total voting power, +and thus there is no single validator who would stop the chain by going offline. +:::info +This is a soft cap, and the actual power of a validator can exceed this fraction if the validator set is small (e.g. there are only 3 validators and the cap is 20%). +::: +:::info +Rewards are distributed proportionally to validators with respect to their capped voting power on the consumer, +not their total voting power on the provider. +::: +1) **Allowlist and denylist**: The consumer chain can specify a list of validators that are allowed or disallowed from participating in the validator set. If an allowlist is set, all validators not on the allowlist cannot validate the consumer chain. If a validator is on both lists, the denylist takes precedence, that is, they cannot validate the consumer chain. If neither list is set, all validators are able to validate the consumer chain. + +:::warning +Note that if denylisting is used in a Top N consumer chain, then the chain might not be secured by N% of the total provider's +power. For example, consider that the top validator `V` on the provider chain has 10% of the voting power, and we have a Top 50% consumer chain, +then if `V` is denylisted, the consumer chain would only be secured by at least 40% of the provider's power. +::: + +All these mechanisms are set by the consumer chain in the `ConsumerAdditionProposal`. They operate *solely on the provider chain*, meaning the consumer chain simply receives the validator set after these rules have been applied and does not have any knowledge about whether they are applied. + +Each of these mechanisms is *set during the consumer addition proposal* (see [Onboarding](../consumer-development/onboarding.md#3-submit-a-governance-proposal)), and is currently *immutable* after the chain has been added. + +The values can be seen by querying the list of consumer chains: +```bash +interchain-security-pd query provider list-consumer-chains +``` + +## Guidelines for setting power shaping parameters + +When setting power shaping parameters, please consider the following guidelines: +* Do not cap the validator set size too low: Notice that this number is the **maximum* number of validators that will ever validate the consumer chain. If this number is too low, the chain will be very limited in the +amount of stake that secures it. The validator set size cap should only be used if there are strong reasons to prefer fewer validators. Consider that setting the cap will mean that +even if the whole validator set of the provider wants to validate on the chain, some validators will simply not be able to. +* Capping the fraction of power any single validator can have is a decent security measure, but it's good to be aware of the interactions with the size of the validator set. +For example, if there are only 3 validators, and the cap is 20%, this will not be possible (since even splitting the power fairly would mean that each validator has 33% of the power, so is above the cap). +However, the cap can be a good measure to prevent a single large validator from essentially taking over the chain. +In general, values under 33% make sense (since a validator that has 33% of the chains power would halt the chain if they go offline). +Notice that the smaller this value is, the more the original voting power gets distorted, which could discourage large validators from deciding to opt in to the chain. +* If the allowlist is *empty*, all validators can validate the chain. If it is *non empty*, then *only* validators on the allowlist can validate the chain. +Thus, an allowlist containing too few validators is a security risk. In particular, consider that if the validators on the allowlist lose a lot of stake or stop being validators, +an allowlist that is too short can very quickly become outdated and leave too few validators, or validators with too little stake, to secure the chain in a decentralized way. +* If the denylist is too full, this can likewise be problematic. If too many large validators are denylisted, the chain might not be secured by a large enough fraction of the provider's power, in particular when +the power distribution on the provider shifts and the denylisted validators gain more power. + +In general, when setting these parameters, consider that the voting power distribution in the future might be very different from the one right now, +and that the chain should be secure even if the power distribution changes significantly. + +:::tip +The power shaping parameters of a running consumer chain can be changed through a [`ConsumerModificationProposal`](./proposals.md#consumermodificationproposal). +::: \ No newline at end of file diff --git a/docs/docs/features/proposals.md b/docs/docs/features/proposals.md index f2d2e3d4b2..5f5457fc0a 100644 --- a/docs/docs/features/proposals.md +++ b/docs/docs/features/proposals.md @@ -5,7 +5,7 @@ sidebar_position: 3 # ICS Provider Proposals -Interchain security module introduces 3 new proposal types to the provider. +Interchain security module introduces new proposal types to the provider. The proposals are used to propose upcoming interchain security events through governance. @@ -42,10 +42,13 @@ Minimal example: "blocks_per_distribution_transmission": 1000, "historical_entries": 10000, "genesis_hash": "d86d756e10118e66e6805e9cc476949da2e750098fcc7634fd0cc77f57a0b2b0", - "binary_hash": "376cdbd3a222a3d5c730c9637454cd4dd925e2f9e2e0d0f3702fc922928583f1" - // relevant for chains performing a standalone to consumer changeover - // in order to maintain the existing ibc transfer channel - "distribution_transmission_channel": "channel-123" + "binary_hash": "376cdbd3a222a3d5c730c9637454cd4dd925e2f9e2e0d0f3702fc922928583f1", + "distribution_transmission_channel": "channel-123", + "top_N": 95, + "validators_power_cap": 0, + "validator_set_cap": 0, + "allowlist": [], + "denylist": [] } ``` More examples can be found in the interchain security testnet repository [here](https://github.com/cosmos/testnets/blob/master/interchain-security/stopped/baryon-1/proposal-baryon-1.json) and [here](https://github.com/cosmos/testnets/blob/master/interchain-security/stopped/noble-1/start-proposal-noble-1.json). @@ -74,6 +77,45 @@ Minimal example: } ``` +:::warning +Before the introduction of Partial Set Security, consumer chains typically included a "soft opt-out mechanism" +which allows the bottom N% of the provider's validators to not validate the consumer chain, without being jailed for downtime on the provider. +After the introduction of Partial Set Security, the use of the soft opt-out mechanism is discouraged, and consumer chains are +encouraged to use the topN parameter to not force validators with little stake to validate the chain. +::: + + +## `ConsumerModificationProposal` +Proposal type used to change the power shaping parameters of a running consumer chain, as well as to change a Top N running +consumer chain to an Opt-In chain and vice versa. + +When a `ConsumerModificationProposal` passes for a running consumer chain, the consumer chain would change all its +parameters to the ones passed in the `ConsumerModificationProposal`. + +Assume, a `chain-1` is a Top N chain. If the following `ConsumerModificationProposal` passes, then `chain-1` would become +an Opt-In chain with a 40% validators power cap, a maximum number of 30 validators, and one denylisted validator. +```js +{ + "title": "Modify consumer chain", + "description": ".md description of your chain and all other relevant information", + "chain_id": "chain-1", + "top_N": 0, + "validators_power_cap": 40, + "validator_set_cap": 30, + "allowlist": [], + "denylist": ["cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq"] +} +``` + +:::warning +If `top_N`, `validators_power_cap`, or some other argument is not included in the proposal, then it is considered +that the default value is set for this argument. For example, if a Top 50% chain wants to only modify `validators_power_cap` +from 35 to 40, then the `ConsumerModificationProposal` would still need to include that `top_N` is 50. Otherwise +`top_N` would be set to its default value of 0, and the chain would become an Opt-In chain. + +To be **safe**, always include `top_N` and all the power shaping parameters in your `ConsumerModificationProposal`. +::: + ## ChangeRewardDenomProposal Proposal type used to mutate the set of denoms accepted by the provider as rewards. diff --git a/docs/docs/features/slashing.md b/docs/docs/features/slashing.md index 6db4c3ee0e..718c3cbad0 100644 --- a/docs/docs/features/slashing.md +++ b/docs/docs/features/slashing.md @@ -21,6 +21,9 @@ Instead of slashing, the provider will only jail offending validator for the dur [Slash throttling](../adrs/adr-002-throttle.md) (sometimes called jail throttling) mechanism ensures that only a fraction of the validator set can be jailed at any one time to prevent malicious consumer chains from harming the provider. ::: +Note that validators are only jailed for downtime on consumer chains that they opted-in to validate on, +or in the case of Top N chains, where they are automatically opted in by being in the Top N% of the validator set on the provider. + ## Equivocation Infractions Equivocation infractions are reported by external agents (e.g., relayers) that can submit to the provider evidence of light client or double signing attacks observed on a consumer chain. diff --git a/docs/docs/frequently-asked-questions.md b/docs/docs/frequently-asked-questions.md index ce76e4e24d..c78dc89f0f 100644 --- a/docs/docs/frequently-asked-questions.md +++ b/docs/docs/frequently-asked-questions.md @@ -4,13 +4,9 @@ title: "Frequently Asked Questions" slug: /faq --- -## What is the meaning of Validator Set Replication? - -VSR simply means that the same validator set is used to secure both the provider and consumer chains. VSR is ensured through ICS protocol which keeps consumers up to date with the validator set of the provider. - ## What is a consumer chain? -Consumer chain is blockchain operated by the same validator operators as the provider chain. The ICS protocol ensures the validator set replication properties (informs consumer chain about the current state of the validator set on the provider) +Consumer chain is a blockchain operated by (a subset of) the validators of the provider chain. The ICS protocol ensures that the consumer chain gets information about which validators should run it (informs consumer chain about the current state of the validator set and the opted in validators for this consumer chain on the provider). Consumer chains are run on infrastructure (virtual or physical machines) distinct from the provider, have their own configurations and operating requirements. @@ -29,7 +25,7 @@ At the very least, the consumer chain could replace the validator set, remove th ## What happens to provider if consumer is down? Consumer chains do not impact the provider chain. -The ICS protocol is concerned only with validator set replication and the only communication that the provider requires from the consumer is information about validator activity (essentially keeping the provider informed about slash events). +The ICS protocol is concerned only with validator set management, and the only communication that the provider requires from the consumer is information about validator activity (essentially keeping the provider informed about slash events). ## Can I run the provider and consumer chains on the same machine? @@ -66,22 +62,15 @@ Validators can also be representatives but representatives are not required to r This feature discerns between validator operators (infrastructure) and governance representatives which further democratizes the ecosystem. This also reduces the pressure on validators to be involved in on-chain governance. -## Can validators opt-out of replicated security? - -At present, the validators cannot opt-out of validating consumer chains. +## Can validators opt out of validating a consumer chain? -There are multiple opt-out mechanisms under active research. +A validator can always opt out from an Opt-In consumer chain. +A validator can only opt out from a Top N chain if the validator does not belong to the top N% validators. -## How does Equivocation Governance Slashing work? +## How does Slashing work? -To avoid potential attacks directed at provider chain validators, a new mechanism was introduced: - -When a validator double-signs on the consumer chain, a special type of slash packet is relayed to the provider chain. The provider will store information about the double signing validator and allow a governance proposal to be submitted. -If the double-signing proposal passes, the offending validator will be slashed on the provider chain and tombstoned. Tombstoning will permanently exclude the validator from the active set of the provider. - -:::caution -An equivocation proposal cannot be submitted for a validator that did not double sign on any of the consumer chains. -::: +Validators that perform an equivocation or a light-client attack on a consumer chain are slashed on the provider chain. +We achieve this by submitting the proof of the equivocation or the light-client attack to the provider chain (see [slashing](features/slashing.md)). ## Can Consumer Chains perform Software Upgrades? @@ -101,9 +90,48 @@ To become a consumer chain use this [checklist](./consumer-development/onboardin Currently supported versions: -- Hermes 1.4.1 -- Support for the CCV module was added to the Go [relayer](https://github.com/cosmos/relayer) in v2.2.0 but v2.4.0 has significant performance fixes which makes it the earliest suggested version to use. +- Hermes 1.8.0 ## How does key delegation work in ICS? You can check the [Key Assignment Guide](./features/key-assignment.md) for specific instructions. + +## How does Partial Set Security work? + +Partial Set Security allows a provider chain to share only a subset of its validator set with a consumer chain. This subset can be determined by the top N% validators by voting power, or by validators opting in to validate the consumer chain. Partial Set Security allows for flexible tradeoffs between security, decentralization, and the budget a consumer chain spends on rewards to validators. + +See the [Partial Set Security](./features/partial-set-security.md) section for more information. + +## How does a validator know which consumers chains it has to validate? + +In order for a validator to keep track of all the chains it has to validate, the validator can use the +[`has-to-validate` query](validators/partial-set-security-for-validators.md#which-chains-does-a-validator-have-to-validate). + +## How many chains can a validator opt in to? + +There is **no** limit in the number of consumers chains a validator can choose to opt in to. + +## Can validators assign a consensus keys while a consumer-addition proposal is in voting period? +Yes, see the [Key Assignment Guide](./features/key-assignment.md) for more information. + +## Can validators assign a consensus key during the voting period for a consumer-addition proposal if they are not in the top N? +Yes. + +## Can validators opt in to an Opt-in or Top N chain after its consumer-addition proposal voting period is over but before the spawn time? +Yes. + +## Can validators opt in to an Opt-in chain after the spawn time if nobody else opted in? +No, the consumer chain will not be added if nobody opted in by the spawn time. At least one validator, regardless of its voting power, must opt in before the spawn time arrives in order for the chain can start. + +## Can all validators opt out of an Opt-in chain? +Yes, the consumer chain will halt with an ERR CONSENSUS FAILURE error after the opt-out message for the last validator is received. + +## Can validators set a commission rate for chains they have not opted in to? +Yes, and this is useful for validators that are not in the top N% of the provider chain, but might move into the top N% in the future. +By setting the commission rate ahead of time, they can make sure that they immediately have a commission rate of their choosing as soon as they are in the top N%. + +## Can a consumer chain modify its power shaping parameters? +Yes, by issuing a [`ConsumerModificationProposal`](./features/proposals.md#consumermodificationproposal). + +## Can a Top N consumer chain become Opt-In or vice versa? +Yes, by issuing a [`ConsumerModificationProposal`](./features/proposals.md#consumermodificationproposal). \ No newline at end of file diff --git a/docs/docs/introduction/overview.md b/docs/docs/introduction/overview.md index aba31751e1..b9f870bfab 100644 --- a/docs/docs/introduction/overview.md +++ b/docs/docs/introduction/overview.md @@ -4,16 +4,19 @@ sidebar_position: 1 # Overview :::info -Replicated security (aka interchain security V1) is an open sourced IBC application which allows cosmos blockchains to lease their proof-of-stake security to one another. +Interchain Security is an open sourced IBC application which allows cosmos blockchains to lease their proof-of-stake security to one another.

-Replicated security allows anyone to launch a "consumer" blockchain using the same validator set as the "provider" blockchain by creating a governance proposal. If the proposal is accepted, provider chain validators start validating the consumer chain as well. Consumer chains will therefore inherit the full security and decentralization of the provider. +Interchain Security allows anyone to launch a "consumer" blockchain using a subset, or even the entire, validator set from the "provider" blockchain by creating a governance proposal. If the proposal is accepted, provider chain validators start validating the consumer chain as well. Consumer chains will therefore inherit security and decentralization from the provider. ::: -## Why Replicated Security? -- Full provider security. At launch, consumer chains are secured by the full validator set and market cap of the provider chain. + + +## Why Interchain Security? + +- The right amount of security for each application. Consumer chains can choose to inherit the whole validator set from the provider, or they can launch as an opt in chain where only a subset of the provider validators validate the consumer chain. This allows for a wide range of security tradeoffs. - Independent block-space. Transactions on consumer chains do not compete with any other applications. This means that there will be no unexpected congestion, and performance will generally be much better than on a shared smart contract platform such as Ethereum. - Projects keep majority of gas fees. Depending on configuration, these fees either go to the project’s community DAO, or can be used in the protocol in other ways. -- No validator search. Consumer chains do not have their own validator sets, and so do not need to find validators one by one. A governance vote will take place for a chain to get adopted by the provider validators which will encourage participation and signal strong buy-in into the project's long-term success. +- No validator search. Consumer chains do not have their own validator sets, and so do not need to find validators one by one. Validators from the provider chain validate on the consumer chain with their stake on the provider chain, earning additional rewards. For the consumer chain, this comes with the benefit of exposing their chain to the wider audience of the provider chain. - Instant sovereignty. Consumers can run arbitrary app logic similar to standalone chains. At any time in the future, a consumer chain can elect to become a completely standalone chain, with its own validator set. ## Core protocol diff --git a/docs/docs/introduction/terminology.md b/docs/docs/introduction/terminology.md index fd06174f92..dd9cd57602 100644 --- a/docs/docs/introduction/terminology.md +++ b/docs/docs/introduction/terminology.md @@ -16,7 +16,11 @@ Interchain Security is the Cosmos-specific category of Shared Security that uses ## Replicated Security -A particular protocol/implementation of Interchain Security that fully replicates the security and decentralization of a validator set across multiple blockchains. Replicated security has also been referred to as "Cross Chain Validation" or "Interchain Security V1", a legacy term for the same protocol. That is, a "provider chain" such as the Cosmos Hub can share its exact validator set with multiple consumer chains by communicating changes in its validator set over IBC. Note this documentation is focused on explaining the concepts from replicated security. +A particular protocol/implementation of Interchain Security that fully replicates the security and decentralization of a validator set across multiple blockchains. Replicated security has also been referred to as "Cross Chain Validation" or "Interchain Security V1", a legacy term for the same protocol. That is, a "provider chain" such as the Cosmos Hub can share its exact validator set with multiple consumer chains by communicating changes in its validator set over IBC. + +## Partial Set Security + +A major iteration of Interchain Security, also known as "Interchain Security V2". Partial Set Security allows a provider chain to share only a subset of its validator set with a consumer chain. This subset can be determined by the top N% validators by voting power, or by validators opting in to validate the consumer chain. Partial Set Security allows for more flexible security tradeoffs than Replicated Security. ## Mesh security diff --git a/docs/docs/validators/joining-testnet.md b/docs/docs/validators/joining-testnet.md index 09737cfb85..e07a28e7c3 100644 --- a/docs/docs/validators/joining-testnet.md +++ b/docs/docs/validators/joining-testnet.md @@ -12,7 +12,7 @@ The experience gained in the testnet will prepare you for validating interchain :::tip Provider and consumer chain represent distinct networks and infrastructures operated by the same validator set. -For general information about running cosmos-sdk based chains check out the [validator basics](https://hub.cosmos.network/validators/validator-setup) and [Running a Node section](https://docs.cosmos.network/main/run-node/run-node) of Cosmos SDK docs +For general information about running cosmos-sdk based chains check out the [validator basics](https://hub.cosmos.network/main/validators/validator-setup) and [Running a Node section](https://docs.cosmos.network/main/run-node/run-node) of Cosmos SDK docs. ::: ## Joining the provider chain @@ -79,7 +79,7 @@ gaiad tx staking create-validator \ ``` :::tip -Check this [guide](https://hub.cosmos.network/validators/validator-setup#edit-validator-description) to edit your validator. +Check this [guide](https://hub.cosmos.network/main/validators/validator-setup#edit-validator-description) to edit your validator. ::: After this step, your validator is created and you can start your node and catch up to the rest of the network. It is recommended that you use `statesync` to catch up to the rest of the network. @@ -133,7 +133,7 @@ Additional scripts to setup your nodes are available [here](https://github.com/c :::tip Once you reach the active set on the provider chain, you will be required to validate all available consumer chains. -You can use the same consensus key on all consumer chains, or opt to use a different key on each consumer chain. +We strongly recommend that you assign a separate key for each consumer chain. Check out this [guide](../features/key-assignment.md) to learn more about key assignment in interchain security. ::: diff --git a/docs/docs/validators/overview.md b/docs/docs/validators/overview.md index 97ef906d0a..ff22edb560 100644 --- a/docs/docs/validators/overview.md +++ b/docs/docs/validators/overview.md @@ -85,7 +85,7 @@ At present, the consumer chain can report evidence about downtime infractions to :::info Causing a downtime infraction on any consumer chain will not incur a slash penalty. Instead, the offending validator will be jailed on the provider chain and consequently on all consumer chains. -To unjail, the validator must wait for the jailing period to elapse on the provider chain and [submit an unjail transaction](https://hub.cosmos.network/validators/validator-setup#unjail-validator) on the provider chain. After unjailing on the provider, the validator will be unjailed on all consumer chains. +To unjail, the validator must wait for the jailing period to elapse on the provider chain and [submit an unjail transaction](https://hub.cosmos.network/main/validators/validator-setup#unjail-validator) on the provider chain. After unjailing on the provider, the validator will be unjailed on all consumer chains. More information is available in [Downtime Slashing documentation](../features/slashing.md#downtime-infractions) ::: @@ -99,7 +99,7 @@ Validators can use different consensus keys on the provider and each of the cons For more information check out the [Key assignment overview and guide](../features/key-assignment.md) ## References: -- [Cosmos Hub Validators FAQ](https://hub.cosmos.network/validators/validator-faq) -- [Cosmos Hub Running a validator](https://hub.cosmos.network/validators/validator-setup) +- [Cosmos Hub Validators FAQ](https://hub.cosmos.network/main/validators/validator-faq) +- [Cosmos Hub Running a validator](https://hub.cosmos.network/main/validators/validator-setup) - [Startup Sequence](https://github.com/cosmos/testnets/blob/master/interchain-security/CONSUMER_LAUNCH_GUIDE.md#chain-launch) -- [Submit Unjailing Transaction](https://hub.cosmos.network/validators/validator-setup#unjail-validator) +- [Submit Unjailing Transaction](https://hub.cosmos.network/main/validators/validator-setup#unjail-validator) diff --git a/docs/docs/validators/partial-set-security-for-validators.md b/docs/docs/validators/partial-set-security-for-validators.md new file mode 100644 index 0000000000..2d6b2dd4a2 --- /dev/null +++ b/docs/docs/validators/partial-set-security-for-validators.md @@ -0,0 +1,175 @@ +--- +sidebar_position: 6 +--- + +# Partial Set Security + +[Partial Set Security](../features/partial-set-security.md) allows consumer chains to join as Opt-In or Top N. +Here, we show how a validator can opt in, opt out, or set a custom commission rate on a consumer chain, as well +as useful queries that a validator can use to figure out which chains it has to validate, etc. + +## Messages +### How to opt in to a consumer chain? + +:::warning +A validator is automatically opted in to a Top N chain if the validator belongs to the top N% of the validators on the provider chain. +::: + +In a Top N chain, a validator that does not belong to the top N% of the validators on the provider can still choose +to opt in to a consumer chain. In other words, validators can opt in, in both Opt-In and Top N chains. + +A validator can opt in to a consumer chain by issuing the following message: +```bash +interchain-security-pd tx provider opt-in +``` + +where +- `consumer-chain-id` is the string identifier of the consumer chain the validator wants to opt in to; +- `consumer-pub-key` corresponds to the public key the validator wants to use on the consumer chain, and it has the +following format `{"@type":"/cosmos.crypto.ed25519.PubKey","key":""}`. + +A validator can opt in to an existing consumer chain that is already running, or to a [proposed](../features/proposals.md) +consumer chain that is still being voted on. A validator can use the following command to retrieve the currently existing +consumer chains: +```bash +interchain-security-pd query provider list-consumer-chains +``` +and this command to see the currently proposed consumer chains: +```bash +interchain-security-pd query provider list-proposed-consumer-chains +``` + + +:::tip +By setting the `consumer-pub-key`, a validator can both opt in to a chain and assign a +public key on a consumer chain. Note that a validator can always [assign](../features/key-assignment.md) +a new consumer key at a later stage. The key-assignment [rules](../features/key-assignment.md#rules) +still apply when setting `consumer-pub-key` when opting in. +::: + +:::info +A validator is only eligible for consumer rewards from a consumer chain if the validator is opted into that chain. +::: + +### How to opt out from a consumer chain? +A validator can opt out from a consumer by issuing the following message: + +```bash +interchain-security-pd tx provider opt-out +``` +where +- `consumer-chain-id` is the string identifier of the consumer chain. + +:::warning +A validator cannot opt out from a Top N chain if it belongs to the top N% validators of the provider. +::: + +:::warning +If a validator moves from the Top N to outside of the top N% of the validators on the provider, it will **not** +be automatically opted-out. The validator has to manually opt out. +::: + +:::warning +A validator can stop its node on a consumer chain **only** after opting out and confirming through the `has-to-validate` +query (see [below](./partial-set-security-for-validators.md#which-chains-does-a-validator-have-to-validate)) that it does +not have to validate the consumer chain any longer. +::: + +:::warning +If all validators opt out from an Opt-In chain, the chain will halt with a consensus failure upon receiving the VSCPacket with an empty validator set. +::: + +### How to set specific per consumer chain commission rate? +A validator can choose to set a different commission rate on each of the consumer chains. +This can be done with the following command: +```bash +interchain-security-pd tx provider set-consumer-commission-rate +``` +where + +- `consumer-chain-id` is the string identifier of the consumer chain; +- `comission-rate` decimal in `[minRate, 1]` where `minRate` corresponds to the minimum commission rate set on the +provider chain (see `min_commission_rate` in `interchain-security-pd query staking params`). + + +If a validator does not set a commission rate on a consumer chain, the commission rate defaults to their commission rate on the provider chain. + +:::tip +Validators can set their commission rate even for consumer chains that they are not currently opted in on, and the commission rate will be applied when they opt in. This is particularly useful for Top N chains, where validators might be opted in automatically, +so validators can set the commission rate in advance. +::: + +:::tip +If a validator opts out and then back in, this will *not* reset their commission rate back to the default. Instead, their +set commission rate still applies. +::: + + +## Queries +Partial Set Security introduces a number of queries to assist validators determine which consumer chains they have to +validate, their commission rate per chain, etc. + +### Which chains does a validator have to validate? +Naturally, a validator is aware of the Opt-In chains it has to validate because in order to validate an Opt-In chain, +a validator has to manually opt in to the chain. This is not the case for Top N chains where a validator might be required +to validate such a chain without explicitly opting in if it belongs to the top N% of the validators on the provider. + +We introduce the following query: +```bash +interchain-security-pd query provider has-to-validate +``` +that can be used by validator with `provider-validator-address` address to retrieve the list of chains that it has to validate. + + +:::tip +As a validator, the list of chains returned by `has-to-validate` is the list of chains you **should** be validating to avoid +getting jailed for downtime. +::: + +### How do you know how much voting power you need to have to be in the top N for a chain? +This can be seen as part of the `list-consumer-chains` query: +```bash +interchain-security-pd query provider list-consumer-chains +``` +where the `min_power_in_top_N` field shows the minimum voting power required to be +automatically opted in to the chain. + +:::tip +`list-consumer-chains` shows the minimal voting power *right now*, but +the automatic opt-in happens only when epochs end on the provider. +In consequence, a validators power might be large enough to be automatically opted in +during an epoch, but if their power is sufficiently decreased before the epoch ends, +they will not be opted in automatically. +::: + + +### How to retrieve all the opted-in validators on a consumer chain? +With the following query: +```bash +interchain-security-pd query provider consumer-opted-in-validators +``` +we can see all the opted-in validators on `consumer-chain-id` that were manually or automatically opted in. + +### How to retrieve all the consumer validators on a consumer chain? +With the following query: +```bash +interchain-security-pd query provider consumer-validators +``` +we can see all the _consumer validators_ (i.e., validator set) of `consumer-chain-id`. The consumer validators are the +ones that are currently (or in the future, see warning) validating the consumer chain. A _consumer validator_ is an opted-in +validator but not vice versa. For example, an opted-in validator `V` might not be a consumer validator because `V` is +denylisted or because `V` is removed due to a validator-set cap. + +:::warning +The returned consumer validators from this query do not necessarily correspond to the validator set that is +validating the consumer chain at this exact moment. This is because the `VSCPacket` sent to a consumer chain might be +delayed and hence this query might return the validator set that the consumer chain would have at some future +point in time. +::: + +### How can we see the commission rate a validator has set on a consumer chain? +Using the following query: +```bash +interchain-security-pd query provider validator-consumer-commission-rate +``` +we retrieve the commission rate set by validator with `provider-validator-address` address on `consumer-chain-id`. \ No newline at end of file diff --git a/docs/docs/validators/withdraw_rewards.md b/docs/docs/validators/withdraw_rewards.md index 1a9ab1fb3c..15d27b3006 100644 --- a/docs/docs/validators/withdraw_rewards.md +++ b/docs/docs/validators/withdraw_rewards.md @@ -2,8 +2,17 @@ sidebar_position: 3 --- -# Withdrawing consumer chain validator rewards +# Consumer chain validator rewards +:::warning +A validator can only receive rewards from a consumer chain if the validator has been validating the consumer chain +for some time. Specifically, the validator has to be a consumer validator of the consumer chain for at least +`NumberOfEpochsToStartReceivingRewards * BlocksPerEpoch` blocks (run `interchain-security-pd query provider params` for +the actual values of the `NumberOfEpochsToStartReceivingRewards` and `BlocksPerEpoch` params). +::: + + +## Withdrawing rewards Here are example steps for withdrawing rewards from consumer chains in the provider chain :::info diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index b3a22cc03d..e73d5e2a21 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -42,7 +42,16 @@ const config = { versions: { current: { path: "/", - // banner: "current", + label: "main", + banner: "unreleased", + }, + "v4.2.0-docs": { + path: "/v4.2.0/", + label: "v4.2.0", + banner: "none", + }, + "v5.0.0": { + banner: "unreleased", }, }, remarkPlugins: [remarkMath], @@ -91,7 +100,14 @@ const config = { { type: "docsVersionDropdown", position: "left", - dropdownActiveClassDisabled: true, + dropdownActiveClassDisabled: false, + dropdownItemsAfter: [ + { + href: "https://cosmos.github.io/interchain-security/legacy", + label: "<= v3.x", + target: "_blank", + }, + ], }, ], }, @@ -211,7 +227,7 @@ const config = { toExtensions: ["html"], redirects: [ { - from: ["/main", "/master"], + from: ["/main"], to: "/", }, ], diff --git a/docs/figures/inactivevals_after.excalidraw b/docs/figures/inactivevals_after.excalidraw new file mode 100644 index 0000000000..9a618ddf8c --- /dev/null +++ b/docs/figures/inactivevals_after.excalidraw @@ -0,0 +1,847 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "id": "nJJZVzll88P_dmpDsWkuC", + "type": "rectangle", + "x": 551, + "y": -843, + "width": 657, + "height": 655, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a0", + "roundness": { + "type": 3 + }, + "seed": 951962170, + "version": 63, + "versionNonce": 1865032870, + "isDeleted": false, + "boundElements": null, + "updated": 1717506390574, + "link": null, + "locked": false + }, + { + "id": "fVs1LhHvrrvCK3ZhJRtu5", + "type": "text", + "x": 575, + "y": -891, + "width": 249.3000030517578, + "height": 45, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a1", + "roundness": null, + "seed": 129610534, + "version": 46, + "versionNonce": 1276535974, + "isDeleted": false, + "boundElements": null, + "updated": 1717507131314, + "link": null, + "locked": false, + "text": "Provider Chain", + "fontSize": 36, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Provider Chain", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "_Dx7IQJkJzNifgDjIf2sI", + "type": "rectangle", + "x": 622, + "y": -764, + "width": 161, + "height": 281, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a2", + "roundness": { + "type": 3 + }, + "seed": 1049314490, + "version": 59, + "versionNonce": 1789968378, + "isDeleted": false, + "boundElements": [ + { + "id": "1QU4AFcgTvpCQQURDCxDZ", + "type": "arrow" + }, + { + "type": "text", + "id": "OyUuFa30MbHO4QszYQXEH" + } + ], + "updated": 1717508356543, + "link": null, + "locked": false + }, + { + "id": "OyUuFa30MbHO4QszYQXEH", + "type": "text", + "x": 667.3666648864746, + "y": -648.5, + "width": 70.26667022705078, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a2G", + "roundness": null, + "seed": 335756666, + "version": 18, + "versionNonce": 1919688890, + "isDeleted": false, + "boundElements": null, + "updated": 1717507131314, + "link": null, + "locked": false, + "text": "Staking\nModule", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "_Dx7IQJkJzNifgDjIf2sI", + "originalText": "Staking\nModule", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 230, + "versionNonce": 188847418, + "index": "a4", + "isDeleted": false, + "id": "wJsk4gejRqDCjtFbAeg8G", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 962.5, + "y": -756.5, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 186.99999999999997, + "height": 309, + "seed": 409738746, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "A8ifOchQWi_H__sEvTMnW", + "type": "arrow" + }, + { + "id": "XBn8pRQaZVQe5gai59xYl", + "type": "arrow" + } + ], + "updated": 1717507815940, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 351, + "versionNonce": 357216442, + "index": "a5", + "isDeleted": false, + "id": "n5HV8y4tI6DZYWWA1Koq6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 620.5, + "y": -376.5, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 164, + "height": 120.00000000000003, + "seed": 1248958374, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "TKqZQfAcUP-6Q6EoH8fp0" + }, + { + "id": "QVrMGeKQYVvkrmDV5wKWR", + "type": "arrow" + } + ], + "updated": 1717508356543, + "link": null, + "locked": false + }, + { + "id": "TKqZQfAcUP-6Q6EoH8fp0", + "type": "text", + "x": 652.0166664123535, + "y": -329, + "width": 100.96666717529297, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a6", + "roundness": null, + "seed": 438334118, + "version": 22, + "versionNonce": 2019293562, + "isDeleted": false, + "boundElements": null, + "updated": 1717507131314, + "link": null, + "locked": false, + "text": "CometBFT", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "n5HV8y4tI6DZYWWA1Koq6", + "originalText": "CometBFT", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "FPk9JragWk96YKRlFekY6", + "type": "rectangle", + "x": 1026, + "y": -678, + "width": 108.00000000000003, + "height": 98, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a8", + "roundness": { + "type": 3 + }, + "seed": 580928678, + "version": 174, + "versionNonce": 683525946, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "R6sc8M7CuGEvv7N7-fcTZ" + }, + { + "id": "1QU4AFcgTvpCQQURDCxDZ", + "type": "arrow" + }, + { + "id": "A8ifOchQWi_H__sEvTMnW", + "type": "arrow" + } + ], + "updated": 1717507761939, + "link": null, + "locked": false + }, + { + "id": "R6sc8M7CuGEvv7N7-fcTZ", + "type": "text", + "x": 1034.849998474121, + "y": -666.5, + "width": 90.30000305175781, + "height": 75, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a9", + "roundness": null, + "seed": 758773690, + "version": 153, + "versionNonce": 596469030, + "isDeleted": false, + "boundElements": null, + "updated": 1717507759332, + "link": null, + "locked": false, + "text": "Power \nShaping\n& Opt In", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "FPk9JragWk96YKRlFekY6", + "originalText": "Power Shaping\n& Opt In", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "1QU4AFcgTvpCQQURDCxDZ", + "type": "arrow", + "x": 784, + "y": -617.9538520826802, + "width": 240, + "height": 19.20103304326051, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aA", + "roundness": { + "type": 2 + }, + "seed": 75530874, + "version": 385, + "versionNonce": 598135718, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "teEeVARH2zRlZXGyzB2PV" + } + ], + "updated": 1717507759332, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 240, + -19.20103304326051 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "_Dx7IQJkJzNifgDjIf2sI", + "focus": 0.08197485638165014, + "gap": 1 + }, + "endBinding": { + "elementId": "FPk9JragWk96YKRlFekY6", + "focus": 0.23696682464454974, + "gap": 2 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "teEeVARH2zRlZXGyzB2PV", + "type": "text", + "x": 837.0583343505859, + "y": -639.5, + "width": 99.88333129882812, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aB", + "roundness": null, + "seed": 918244474, + "version": 27, + "versionNonce": 206748218, + "isDeleted": false, + "boundElements": null, + "updated": 1717507131314, + "link": null, + "locked": false, + "text": "Bonded\nValidators", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "1QU4AFcgTvpCQQURDCxDZ", + "originalText": "Bonded\nValidators", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "9Z_qOWKQyxwUvelhZMZx6", + "type": "text", + "x": 1011, + "y": -751, + "width": 78.66666412353516, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aE", + "roundness": null, + "seed": 91824166, + "version": 99, + "versionNonce": 207872422, + "isDeleted": false, + "boundElements": null, + "updated": 1717507131314, + "link": null, + "locked": false, + "text": "Provider\nModule", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Provider\nModule", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "A8ifOchQWi_H__sEvTMnW", + "type": "arrow", + "x": 1134, + "y": -632.7473377850915, + "width": 185, + "height": 10.747337785091531, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aF", + "roundness": { + "type": 2 + }, + "seed": 157350886, + "version": 351, + "versionNonce": 1955289658, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "IWrcqs7yN7FdMaMGcNDj4" + } + ], + "updated": 1717507763008, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 185, + 10.747337785091531 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "FPk9JragWk96YKRlFekY6", + "focus": -0.1320442396210268, + "gap": 1 + }, + "endBinding": { + "elementId": "zY_dSGPd9zunChgVkNDpR", + "focus": -0.020248008412827926, + "gap": 1.5583343505859375 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "IWrcqs7yN7FdMaMGcNDj4", + "type": "text", + "x": 1190.216667175293, + "y": -647, + "width": 67.56666564941406, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aG", + "roundness": null, + "seed": 1111293542, + "version": 19, + "versionNonce": 1166078906, + "isDeleted": false, + "boundElements": null, + "updated": 1717507131314, + "link": null, + "locked": false, + "text": "Shaped\nValSet", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "A8ifOchQWi_H__sEvTMnW", + "originalText": "Shaped\nValSet", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "zY_dSGPd9zunChgVkNDpR", + "type": "text", + "x": 1320.558334350586, + "y": -645, + "width": 84.88333129882812, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aH", + "roundness": null, + "seed": 359543462, + "version": 97, + "versionNonce": 589863290, + "isDeleted": false, + "boundElements": [ + { + "id": "A8ifOchQWi_H__sEvTMnW", + "type": "arrow" + } + ], + "updated": 1717507761940, + "link": null, + "locked": false, + "text": "sent to\nconsumer", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "sent to\nconsumer", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 259, + "versionNonce": 827676730, + "index": "aI", + "isDeleted": false, + "id": "kTEf4qbgYHvfyWHxD6yV2", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 977, + "y": -555, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 152.00000000000006, + "height": 100, + "seed": 1312320038, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "TKt49fH0utbl-oDqZWAHv" + }, + { + "id": "XBn8pRQaZVQe5gai59xYl", + "type": "arrow" + }, + { + "id": "QVrMGeKQYVvkrmDV5wKWR", + "type": "arrow" + } + ], + "updated": 1717507832443, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 273, + "versionNonce": 640336678, + "index": "aJ", + "isDeleted": false, + "id": "TKt49fH0utbl-oDqZWAHv", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 987.3499984741211, + "y": -542.5, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 131.3000030517578, + "height": 75, + "seed": 489960806, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1717507777794, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Filter to\nsmall set of \nvalidators", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "kTEf4qbgYHvfyWHxD6yV2", + "originalText": "Filter to\nsmall set of validators", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "XBn8pRQaZVQe5gai59xYl", + "type": "arrow", + "x": 980, + "y": -633, + "width": 15, + "height": 78, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aK", + "roundness": { + "type": 2 + }, + "seed": 2081760186, + "version": 43, + "versionNonce": 557255654, + "isDeleted": false, + "boundElements": null, + "updated": 1717507819360, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 15, + 78 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "wJsk4gejRqDCjtFbAeg8G", + "focus": 0.5684407679100983, + "gap": 1 + }, + "endBinding": { + "elementId": "kTEf4qbgYHvfyWHxD6yV2", + "focus": -0.5651392632524705, + "gap": 1 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "QVrMGeKQYVvkrmDV5wKWR", + "type": "arrow", + "x": 981, + "y": -466, + "width": 196, + "height": 106, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aL", + "roundness": { + "type": 2 + }, + "seed": 390002426, + "version": 59, + "versionNonce": 832345722, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "Usz338HAejcFqJG1vmJ4x" + } + ], + "updated": 1717507912037, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -196, + 106 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "kTEf4qbgYHvfyWHxD6yV2", + "focus": -0.000672043010752688, + "gap": 1 + }, + "endBinding": { + "elementId": "n5HV8y4tI6DZYWWA1Koq6", + "focus": 0.01070799921768042, + "gap": 1 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "Usz338HAejcFqJG1vmJ4x", + "type": "text", + "x": 827.5499992370605, + "y": -425.5, + "width": 110.9000015258789, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aM", + "roundness": null, + "seed": 920641702, + "version": 12, + "versionNonce": 1488639910, + "isDeleted": false, + "boundElements": null, + "updated": 1717507911327, + "link": null, + "locked": false, + "text": "ValUpdates", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "QVrMGeKQYVvkrmDV5wKWR", + "originalText": "ValUpdates", + "autoResize": true, + "lineHeight": 1.25 + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/docs/figures/inactivevals_after.png b/docs/figures/inactivevals_after.png new file mode 100644 index 0000000000000000000000000000000000000000..fb9e862c025176a63c1d666add74edf6ec59d97f GIT binary patch literal 78614 zcmc$`byQVd7d|S-0}_H9kdW?95s>cgK1hRfNFyyJEueIVba#WK3KG(df`T-Hl+<0v z?|VP>{oQ}=xMSQq299xrefC~4*PPFM<}-J=sBTJf16g}&gu9p&fGb5#HCI*X6xM5RmVpYcp|MfuZfOzn01>Mjh z{(ldXBBy}!Un8f0Fj7FfOQK-7Ks5q-RY3}B~$M`Hbwg2y# zfGb`{Jqvy`z)zzz*}T_r{vqlf*N05+UF&Ox@V_secn+?!e`vYOM(%f-Giwq`ihk7b zy`NZVeK><_8cPfQ*Xq^Cf-yw4YX|X*{1}xe(5W;G5y)^IlUv)a9jWNbaKrd}l>#); z>dE~tJ_;Uw;Ii19D7H8p;^n13Pv}L*5vc-m0 zZ?S!I@zEcHrs#yK(@wk){%Li1x*9{U6TQ>8ytJFLGV(%T*GgO0JmKQ_5$2#OrL z-C7I0-MSIs^W?3{&JGlh;bB%X-ydp+Q+iKQ%wF(GCoXThrr9w4Hoz2$Sf(8JwG_)# zG+a7K$aIIVckQy@xvuRzm=`Hy3|oZsr`Ej=E|KfA5n}x))y#)Zrgf0b?Gn$!HC>Md zxmR>4XNT))c-ru;vgWnawOPxodRFs=OuwHSZc{egGJi}Xn-A@^e341c!{ZsV!LX+NGDWU21ONw^!=EGY5(HYc^r3zmuVgF$xQ zP*Qhznft|8c7M*oOfQ?D`weq8%snHAFY#F)J@z`@wg&dtEUVOyvrTUK$x?jV!1bfl zu}qjjzxCYM`CjJ}_`YNKWzLUA{iyLNjgpvuOhVKU^|f*lQioC+&srpV2g8r9j`LmH zna<;3fxVgVU8C!t({$&S^Y)G0>E}n|Syy$t=P=Ii`#pDft=1PkmhBtn9aWdrcIn;U%TyM_~}KJ&+-F(+m>w>Ud^Cf}){Ok<+0{?QD^c0h@dr#=WD{ z`BN)M&vj$0Pv2wF&7wFzv1F}WtKpxafs-W)gQQ^FY$HFiEw4wPl<5_^{4u^3PM^sU zBXpdM=h#(u^>ZstV6Sbw&StWtLcs6Sn}D^ov?mUu{R!HS-U}YQqsH4?B<8V8ZvMGh zN*wRm3zJD!U~7I|p*!~Qc%9NONX))U-TB3Wir)e5Vb?A4WLy=&k8S(i7?@8-?*LQt zrj|xs=nA?upS3y{iTA)h-1jM|fV-V$`M9#c&}~8v3j0Yd-{0;gdlwBXrpeHop<&u% z{Y9^>awT^tuH`}<8@MORba{0@k;TR7_h^XO>wF#m)6chv8mH+LhM1^o=GgQsgpN@*% z!b`4A9VzjP{}JPV(Ub1jjkZ=lZOE)YY)HI7n`G#Pb#lfKV#b>6LK72jRiOjv&FK~~HIy6Thi+<^&> zaT#*o$BrgHG%5|-Zwp4ymObteuwp!s!N*9~V#4UY)%9F}6@!9RuOaH+*~*b9 z=x9){gC%{iedcVP;WkxWk*-Fqjq|Ms`MBv*AckFV2hI2sze8d!hlM5-srycMo^P|e zjUZercKS-s9gzovtc~f`i!JrKo?jEFwVb*Fkx?-2R)ofjEmJfw-lTMWgLEqylXrnb zUH7XYbTG}Kr8qXaJ&vT?&?W|dH~%fEhyG_TePtuxqeVa{LSM5 z=1M|numXGnyH<{F7}|QWm(Oh;4O8_%yrubR`mVN=f8%w^#o?%Lg^^vuTPC zSc3bagSEwyVcrAcP`ZRF*#`Uh1~DhNNA z*vjdM|JAtTu#PHf{3eZLkceD=eq}tfUiE!PU4f0)uh1)ArI&}yQz7w2gp2E-tgHe5 z)A&kD1RK5cj`G6U?B&Vw6Z%FIM#8VvAdqR-Nh*Q8tQLXoU4H#rr#Xl(Qm7}dp51tIYSdR73}?!9Edp;qaz*n)?7TVuN;3Ilplkmf*C zzoBHf-b(LGdH#JSi6GHOZN6Be5CxwviNIuSkAUWevbwey{_QI9kz~#uH_%gjF5vG|w{+{yQNLF6e*Z}WPlt>5LAkqna_!S7@F4D|sG2!H)c zB}Kb#CZyqRLA9k9mk#+<^C1cKz{%>Wy;HX z7Jnp9p(T!q6wFZaz{LFXMU~L;Ob>eAr;egQw$=~&-aGY}5%ik;iP$XIs8ae2^h&7{ z?=l>>${QOxnG+o2%$C&{8{3WV_J8WgXHdgSX%pFhb2Ee~-DQ~1eGk_ZDH7YewW^8K zXTK}D=9#oW9Azn}H$}L$I*ZK0oz|gGHFZXc%x@v{oMT+RD}X-linw=I zAJw+spxSlXz(cC$G%l(7y%UBSWa`Z`@1?YW3A`GhW0H*&Qm@w@7}@fFQ5`wq3ZA8^uMpqvfaY2 zjO`AG&3M=M;waoDrB@7eT9=5AMa>SdrG}9P?WQQhok&;EIahndW;mgWYffe^Xq;k; zRi7@ljIM1say$~TJnS_RA9SjPQR_ctGsRfu%7&ar z?JN`^s2|AKrJ${6UoZUuHV$8^0B9(vf+n!GWiJXZfSSZ zoZzmVg_Ji${sW-DgaTYjbZ*4f{$mW{OP3|&^`pw$WX7Xsne|a!QIW@tM4#jo0Y7Sw zI_z@6ZQ1|2Jw?d7Vb=fpl6WzxT_o7jl3kU9Pt0k_bDjG%p;H8n`Ih&hEGmiqw}{Em zY&^-FALVZFL~M`O*{Wv#Df1$|nZgGseRpx~^jR5S9XpZcCLKdrjp5gGb=KoW(c3X; z09^)Mb^G4`)Wd&-Ja7Mau4o?^xQ;F5yjaD@=sEln*oV*%Tinc~@o+mT$F| zRNcSkVjHNYc7}{`BmHnq1`~i6m7NrOKXKPHm{#QC41tYU7t!5? zsM&11*vl-Eiye0LQ?q(~_ZGw7NcG^?i8&F`Z_$^(&u=(tABje5`B+K`70+KiLe^}I zq~YY&=WfY4+T}h@2C`~Z<5@JiGJ3e0zIZQ%g+A3lCOHSB`fK-f44Kdz%9$hDi7J+x zbUd;~H3hxC28%J8rF{ZUCES@I>kTtW683El9F`FefiHf*gx!mty_kEVR%v$U9zHb= zzL1Bq!Ni4d}=1tuG z?l28;E1r4!*`sL_$9!zr^4kH4_jYyk0^Ow-bWzo5$nADSvwlk(+-h;@-KXRjBC*;9 z;qjwCCj0By`*7aXABver6FX@&c8sYy2ofL4dc%{Dbc3ez=VT>%5``mM=fy$yb&zdMpvly*!eW_^y>U^xFvkcj|l}JG&>|Ll&RYKm4 z$t$zD8|ZwhXpI4(Y4T_N)^IPu9`3JoaQ=x*Zortt)ZAvV#f?^KPEbjTi*_z=BxOrM z3VQUGVoEsI5=DdKn_{(m?X5c)F4Z^q#7=aU4@mCD#t#LecXKch`fib%#Zupk|Lvbe zp}DxS(W)4a9?Vn*;n5f0U0BDXCF$_r%f>L_cqdVn3D2lfJY{pJ3l|c(>fq@m31GRX zovmU*?!)p<#}?10(nFCr!95KyX1U7g^_!5}93-m|x%wW1Vw;+k9`g1Hml~Z@^J8Zf zKDdkiL7t*Io&8&)cb%|h#R0!5(bX%=(aRAh5d^vAAqAy>D|WZG z14d)fd3kKBX~7uRlVZ2y9RHDSN8@tSPp|9)>shP;MH<7=IPKPh~%xAut`G zF7ocSDM^K&Dq)#iA7uK$r1Ei=$)Yn_b*R?(o!tOzdT07>tWtXp2sOlWd#0M_A$sn% zivLfIpaPd*h>XJNIVoQyR-=5<#d@ztrQ2$!=H2(%-YniXJhlHe1sE`eo(LSl6EqXN z^&58NT>#3>f5P5!W_53Ztt=4;60@RP&<)guyrJyF=^`I~xO&?KL|Obxp}_Z9f&{H$ za!ur6!R=1aZ3YWuMlH()Tr>i3!UyLSP<>;t9jAn^qUWh!xlkFlxc=NI)NAaQ|CPFj zQXqMT#Eqomk3%od0lVMjd^5|^W)8-d@^H@&~PM;hsThi)gm55G=7 zeqiu1{?<6>TM~_Aj--}j!1**#4qd7qe<9~}&<`3t&p)_zLf3x2+d9ScTq=LYu)vsa zJ3;&d%7_yNnRAp?Pt6)RpQ!He9DYcizf!fIWhETo=RsDc?^`fl$wkS>XBEXtiwq30 zO+19GFsI-_3hfznv_>^(nTwn23cD2_YvT2&#GU$EVFFz{6*(V(AFM8_pEkO^Z(vx> zcArNU{yvOOE+aR1;UwlcDw%WUQ_Et}KhjJtNHNUD@u*xxPGvg~iL{FC)WKKnJfYn+ zjDBHOKBUl6!}mM;-J4Lbpjd3o3^Uw?$in$qK)>v>)!Q`YJ- zCr?U2R#y8&>+nQ#0flc})qBivQ$*v7>)Mu!M)55x!a%J6ZL3<$Ov;eKf?8P%(0Bysp}J1MRme z0uI-PYCqyR8R?sZ;FW!4ad>#*y!E-F5KGdVM%<*zUNI4t#34;W2}LC2Tf_J2a`9S4 zLSx1oK*l_JMHKhwgWH|zp(UZfuqNkXg7i-+q=Dxr*#1opI2=J-pQ`3w3sFX)QFR0F zC&UT&hjLW}LYEwO!_?-&n3>jdC?_u3eZnY?-&Ggh&It)=(#%dVJ?Y|}%CLM3!xl4% z!Zt5+>^Dg7pkbjgLX0PRwcG&7w^WaX#-n|XSX`4b8eviRh zukjmqfe_FQxattt*j^gVvxKOg=)B!|4E+8~#)Z>?YLsGyKVyVs_7a+G(WLjC>1 zyi9gpIO7q`b~aQKW^?Yz<*$i&Awn!^smz)|I_2}< z`fW7*Hhf!)EU03Q5X=m*U6oi4FTdO7V-zeBD}MKF_^IwlrqEEfSP;<>{QBy0s5cyU zXGF)qP3sWB(Y8EK(gIFvC|4?Sd+#|GsZEQ=-qN=g=E}CQC_>Ket8{|1nQF7h#K}CF zJ6!%(KHee&n`8M3d0WyiNUR4}GBX4`co2ss&o=o6U>DygX7En}W^*9j|LRO?kVwR@ zErr7*aA?G>=Q$=bzcV7biW8q7@7Mw^VDuY*XBm(E9DKM-vihz1A;c_S<*lu11$6d9?Fn)4^OOp8f$A+1q?~&HI-Dtn*YNpd_W{&zE&Zd;^ zLQGAOPPJ3k7w?s-9xUc6kuR|lAND`@5Pvrn)L_S1wFNx9)YjLZpVvaREvqemygC;6j~J?IN_An?c$L>n~Ko+`4)P}!29AG`<4H=5-*-FJxAzD#>e$!AzC)g%Ul-CiJa>On+8NV0_JbEW%v@px|c z*G1lzZFU?CFh^(R7`Mx_rb`y({9Q_doS(Po@z%{S*|v z`4vOLFZ>xx!^1BzmFnAh$7cJNTH6`8cQNw&ZGIh!iJBUU3Hc*4T5;Chu(*ScXn>gl?4CFL|W#Y`Q|?LAiz7nzVAROcNR8@DC_dxpMH`y1O@7N>|DV zTea*?xNHm+7rwh(6KQuTG%s_cxR>t2xdNFBeGJ17^&s>Hr6&`GV99G{QJ2n^Cu2c!KaR0bG_UqN2c5r z$$eZlxCk%G;ywG2mwxiO4`?VaED zOjnsV1?Je9ch808btkeorENCnk#uHwk4TvsS*`_i>>O4$wIYho4VzDNH1uw2PWht| zq?t_!oHLm5Hd%$M+S&->nH6LKj*vzr+d@1#iF#Ma2lebU5$E1}UNzd^X%|?2sW;(p zd;@vbiqGiLlWoQAMY${xs#ubMRJ8gpC1o%Fj8-;sZ<-BTgl6*F#B6lw7ZsqJ8KSx3 znB#ojCUASkwJYsCj!EI)VWda~B6jl5)H`>pdeP<;>I3?K-r&^h8%cBT=F>4J+kaEL zqEIIKPsfe5{^b*72LlQ^$}sEz3dF^cgu$}Z>Fqo@HdTM}oruD#s5uk|*M==nuQ<#+ zK})6i&vE|p>;8zppGg$r|BojEUlV<{svV}Ly8RRj2EtbnqBd*35U=n@^!_9QMWvAW z<~Mvn%w-YPn<^cGN(1V^tdy}#(!Vb|kTw4DE{#D~h$ z7aV&qrS3?T$t!6U{SmoEnb1hQzU5eeAT@RAbh`h!xGax}7NSe7+Mr7Pz!uOfbv7^S zGqrtxuS>Q(6qSkBZBui+*~PM1SUbErVu(DTCS(p#R*{Y(G?5cJ`|_&5ZENZ*uK>(* zEaP45KU#o4o{U&6JhXV$35$_Tdz3q5b|APo{2v8qusSpf*>*XJ+dEpRe}5ZsgIGj$ zJNVzf|8I3$auW7GFc83kYn-MCsz`RmaRE1PSu``2w4y#>2I#}0uQKiTW{CR2_D8fd zK7j(8UVT9WlnR4eTSglML@CcQ`|EEGzhOr#Bjm%qR`(s7EkVFsBWDe2?iJTqQ(?;$ zHQ&O@IR^2wu=uJZ@{h3rwZIQR*n+L$=X)OxfN{avZ z!Y>};ajdAWc)9stqQ%c28~5xAO29$*TPrY22_E|SXP8#>&5Bmnjh7iy#RdPmgeq1H z5*PdkWj>$j_gsJ7K1|dCU_JAOElsE2X9S^K2=Jn%$kDD8Ds}&DS2hM!MvFJkkfh%Vaie(&Np0%RqyNr+&undW_6&iiNPXIt?K9wx2$Ayhq znzcU=GkdZOK-T|uB~}*_yuLSAUs~RYSQ|CGC(@7{ar@8RAr__O4K-Tvvn}_$?B-sB`&5I_YR*~~(>0=qHdU?{ne~?;Kadk$FS33XCMpP4LaA`z?ai`>07FiXUkk?F$Ql?-t-)52bpWF60_D!OmgLR&;a_WQkb@uZ-L9D6? zQrTySuaRoc_+;b>{64p$+Gti-DU+ER?c?Gg2Cxd{cp5i|NCE4N8^tEpV9yGLG~W-!tril zC4Ue#|Jj7N;JIKlT*bjeRy=L3RjEIZ_Wb|^L0lBGp5@<>D=b}5fFbp%6AU!fAO5*a zxAsS@^_M?~D@j!aih?s+|4m}ZfcORxX+?`Rs>Csgf14S0KoK-ubqi!-8`G6W6Lu}i zP)QJbAFGXX{Hf+DLJt6#Ii)X>APu3?0o7#fuVhS`(9Hy}#Ce}r-^TEkKdK)itM?*B zwn_TEJemP-x1x z;7carG(9*&SZGm<+1nRGLL5kcPB~247$~u-#dn?)J8&4ZxP~Xn>43lh2gf;j^x`JU z?J9ziRPMn#tB>N}{+b6x{4=aJEUDKRlG!xCMesO(k>z^)4qNZdLbFSV`d@RVf;o!s zTpW(@wtF2##LFP6$rnk#jP^T7rfMrigBv_c_jghj#EWf!QThl6`hB8zI zk&>VM5r$y=J8b=9mlKFsW$(H5M->0hsmGQFD}6VP?av7#J_pPJ=U&SCWKrp_af11Y zgP<8gB|nV}_0X*{4k*_IX=_^90ua)TX`Kbz;7;uZJLH-EwGi2}sKB4%(kXHPVaNkg zepjo8h_$c%sMRT4mUF0bB-nB#I$a5&!behHOG+zjvT`!q=YIKuJ3~6e|M6_j%FoO) zliy-zb^>(8SD3RFDe4L4Iv3BV@eA7&^UIVAHmOxgqf&o(8pr2^&s|wD$c7|I(p|1m zsEp$la^v&uZf+a&^5~TA66z9c%{AB?DDW)K->*J%d&%%hPKD z6u$U0k?^ezm51X=7hU%UmM`qSuk__KX8ZG*73eiO=q~_v3(`TCZUQoL)fSsU4ZmVQ6{!c``YV9Xw&LV&%`EHU>a{c|?0x zZ>#Ne1*SeJ;Nmd20FQ%K$K*WX^|47h({nAw0+f713O;!WT6`dkPAl`M*vvwQTzST8 zGHj#XB_LtIOQ>|BJ*fHGg}iz&uaM2O)K2q);pLWL^sOuhdI*&<7~uodWV@4ZAM*le z%PmJTEk?7&v|92a%6TD85~e0DQ{1{!o8_UCnUAnVgU`BrY@AdU^MuhT7W8A;GeUK< ze9N@MMdttr(JGcve)t)>)h*pU=>)`VbGDkaQ%CwN%xCcFg)8nI-O}|X?fI7!Z@9Re zR(i$bCmGBSUbw#vIz{r4*BuL+nb-U=#c(pg{T23x7&%8%&Srq=+t1`x%`io{gDFz9 z{cZFM%~TSM>3zIBXPKl50wi1qH5czPxRkgZLkR90oBn&&%CA3f77=JZg{8S6cf46 z&nIIkCG3dThBMOE8eZo*kQghW`X&7^m6vLK+<~KbdOB0RQhI5VvZu^VAqFvlU@F{x zWi|X{jD}xqpO0w(ji>(+$BYK{&AoLXJ~J{Kx|w&g(&a~0QE@oJ{I=sv64b?6(}iAb zlsC+kIOZI`4&fTd`-oOGOFBs8J@ud=*JV86NbcDQE6goYcNFzvw9-ffk**qVDFt3hwhen?&ADV?P;)*7qpV4@=&CxU zWR9)~o@-gWX>EM;{Sxbsxl%$rBF<_14_4;;YKz~c#8q#I14s&d^+PG@H=7P`Uy$zf z2KZvD2pwte8V!GZw^8E!D?8div4Tn(KVjq3yf0E|ZPm4L=}*bUFPTnszj8w5;#chsWLF z&Er5oQabTy-Pj^;Pg4OVOAG)H)T=k<2ZKi)^jS%mDuj)Q`SZ`&(!>)X?3_2QVg+cY z+K-9GiZ$rD>}IMoW6onlu4a6$FHbCX>ZgYvoEv|gO$td9K`6c+fO?CUK|OnMKL4HLh%U{iz3cod zUHI+uw<1?2e%~XF;0uyh^FXyXgutWVUo(rlSP=hVv;YvF?u;PZOABtUoO>*J@pOWK z^%#wAz^mZ08p-ToG!Wd{>>k#smmc@Y+$1;VX{gQdU1)N06Mj6=R)_6~0fiGdv}_dA zX(}9H2S}nh(u81iWhGd(0M%t1-?!`_BBwVv_3N45b7nWkoGG{ydNZ7Wf;np9N#l}N zDc@e(;dXsGW5cXPn$$qjbmWC>J4g018c$+juv=VpcW!R3@LKWu1Zp-9W^N$8e4mz%AqrdnNFD<5UZxl!}Lts6#f z5g7S6btP2s@vn_3uycdzTSog4ZIZs}i-#*=bfr$))oo7%EJ=CXo zGK3XSM((*1sA$61dOT-K{Oo!qlD%xdmtU#{2!w~gz%s1XeL$V|d0)Ek@$B0&Ajp;) zyaI4+XQX(r{bb4ZBrT*_ZLjnC>KKkamiDB>IuQuhU9CJg+%u1BL4A11 zVmO_zxt3;X3$ER2qX3)<=e;jM?@gl7;iFA13rs1;g_G`|HXW{MvpFt_(2nHakb1tP zO_J$kXKVTdVfLCC>6?Az_w(mg*xQWD)pxhcfprWo05bXbgt@FL5aG2p zW@`)2&PM!~vTq+Jv>y%&Xfu=pd$HKaPjc8l2QtoaMc{@=JQkd$Fu9WT-@GyvuPNr7 z%vT^d1S0$t;64Ws8gy&d4Pf(@WZv7H-ujs9q4w=ZQx>!4N%oG51|Ey%CoGgdrr>6n zTjAowTfXFNo%fzvsJ^QyB@RllJAMZA(%0-4n& zc!KVQA;0q-ox7w{jiA4vzo}1y&?JSL(jB!WP%qa-%5@JVcON`1A&#kw;1>0ya$6b?}Z*)-2 zzSn`z$Tv7k*-YWD(qoxW5GpE;Z7tI{I5*)F6y|NP_y0tn(Af zxQEcFd$Eud;i5lI-nCyI&m%`bqt9jUviwHc2Ck$XOOf+9wUv1XI-&&2#YA{V2( zysbcxk9kdJf@YQ*Qy-aCeaGR)w~xmj$_xCwQu;7nz`lxCn&nH9@Y#MXF3hwE8C$+O z=B-^zwVlhRnl|!pZ@=orRe1o+y~Y#hL(4c^GO3%is2XHZd0Fh0<6+ssT&vR2MCOZZ zCeN%S7C>fTt^H2udoS)3&Nm!!SoPbF$Uvar7a?QSR&utg*Tub3t?2-JcN5Ghxt%2k zA2++^E!8LeUdOyHdwDr%jq)4h&)KB91~*pIS#s%D4xWw(ok(utlxd-ANTO2}z*kQ6 zL-BS&s%J%W>?qI%c4|o1GQ(V%@9SOLJ|a%j;O6a`K}En0+r_X+mpeM1t1EZT#lO`I8p~PBJix?(|Z6)7W6QSX;;MlD)8pA(x(> zN^|p>)0sN0QrSMh+P-qx#!85@(utbKNWBqJ)Kb$m%h6nm$1Vz$ZGjGco36~N_d=!? zPV826#0-4#a7#l&Jo-MPK(aC@3=+40MB}EvV!$Pkf$)P$BPE7lMoW*nUGp;^W6$441$Nt0?S5mQV81-)RLN{o?qg$i<~YIa`2N%6DJoWxf!F7Yze68_g>bQHyGxh zbha;ghs>{o$g}M`W81&bMQizeRTz+RgFE{p^WJHkVYbZLT2gmLcB*uGm}x+!w`t;5 zE6x*F!B}V5NHo=1Gu%*TK(30*+2(@?U$!m423-Ms%v(w2_ocFLeJDaO+WZ zUng3>8jA^Q&k>9{MWKmt#XT&HnoyRbnmzgrb&~=Pk;qfodJMl6tfgaWTy^|h>=W7H z2A2)c@6|ZP6-)r5fw|NrwZPtgRM~z)4M*3q8OnXRyF5ovG4U0!I)^2`$Yh-8 z#!$oUOYjgpr}j49RqN9vtC#wvIVI=uRN0(G)oSce9}K6&#rIBpG!aw~3(z7Jvmg}Q zBa;n-h_Jvm$xg&so{&V5@=_9E!^0j9t5QQ~#O=!Kr)t=u#GFn*Ge|0EF8gqmNqrL` zr=MqXth@1%1{Ra$_p?|iGCop>(xIdm;+RhOdXSNQ{unXBy=1ltqGN<=i|KN5h zcBU*Ho0sV$ekvNJ+$iG{#3c$OkYV%K!yeShig;28fRasOt`B+N8xJ{o&}d$}&)X+u zNNZIWIFzl66=}ipBJcxR=qYmWYa_YkUi`fc!^nzqGMaEqtbu;7?he6W_nx`6;kZ|{ z`IMlQ5B*k3O}OYVNc;M>9hF|1K{StNpbt>Ys5Oxo5lHmq3svqCWstvahPmB@6=5Jk zORL(eFUdC&gm{pmyJk?eMCB38^=oR)=n|mwDCIX@1UzmaAZwXc)-R}Etjk=o`445W+NK2WH*>yzc_0QNxzp9aGo+h}rP}2m zG*pBV?l76xsf(B2hPTu)ArkmNtq`7@0fI_~X-H3U8^2K4(=CD8JrD5QhPmeJIaPwu zZo|uIBK{rG=yR1uor12Fa}1Dh7=UQI=G~;AcQS1zdMlp-t=?r&aVLKt`=t~sqpI-|AWShNB@^Ez2@)o&| zWAm(wzi(#07ii8J0uu4Es`XJ@T0nVyLl8;`mJ&g|rt#R<-6}=ZL9723q@<%A3bw+n zsbpdf_ucrH`eRq(B`45|av$Lnnl}p46bqFz1}d=FVuDaG@9XG0h46tk(81xXliQxe zTOVlkKzZZDLFZg5+YT@?<=Z$eiDKfcmZX{8Yw|_;RT`T45vX76571wOmegSuAe+bg zUh-f($;i*T0ni+2mxyjq;C7zON_{?f`caA?#kQike;eRY^Ysz$=YlVe+D@A1*dYnP zG)jY0lVtuAMU=pv^N8cc;y^sp+Cb}MVF6$_EdWgAX`l}lVd_Li3w(;uoK@f-+aPx!%5 zfqmn4>Wqb zU2u9!YLTCyeIMLAT^HnwxH}n)8U@M1zCUN~&j#&ostzk5imE4tivajqtY>(z(U(?S z-a%TB3QsS-K}>`NC^IDlmf;glR~@IDO{Pd_r-J-b91DIV^&_6q9(q7GadrAu%IO~N|21bY_wK?EjMTBbInTL~Dc8ncsR&zZ8+v|4 z*?rNt?APiRqj;YZ3l{#`X|?|zBr-m&>IP`5i9V)SMKt6rY&UlbtB7Nc!~j-r#y1X~ z;pKS_`weqMolglf^i}fzxD6qhqUmW?FWCo{Vj4an$sti$Y`5Kq{{$gK1sIp$eu?dfn!-J!M zBX{3;V{8KV-78gZaQ;7l6vE^@xZMhsXn|bh=Qrv@&|q};Clg_r8K6I>zQ&5)4W9NW z1_bCDfR1voyWC zI6E97vMp1?4h95FjVB0y9{@r0#DACmc-q7%Pl-*9Eskms7GF$W#mSURpR+cXnuMH8 z*dwkhm5l(n$wA`(#a7@{;0v28-$UZfJmkpfvB%~NlI_8S#c8orCvAsOzo_c;0-ehr zz$(p%zN@#L9!7YZkTO7Naxb=eG+wWB*k0`wf@b3B2(Donsj3XnZFxMs5ZZ2w=qL6B zX*AK7&!|X&`1Mbgm!v&uV9$b$86<;)yFdM-1&IC8NAUTIy>uiN%4d12eTrUrb6t&XZKT(Wa#Rs z1wM+yRzPG7d{?KdJJ+)|ue>ErrOb3_AX z9J(BQKhyVE_i(p$4_}{X*39EeoXp(v`A3?JE#jkl4;_s=P~5_&_;aL}AM#FkA#-^j z+qEXec|Hbp>aF?|P!!S(0o+09fWcOgDq21N=7-xnQsS&Z83jy9G_eFZ$B1rp@$aB5 z=yJ*c#;gq*O<9PcMBbB*>@=}qxR%4*cXcEd?ga(h0|O9tnX@jO6@+&oG=tc3s6ve* z9|*jg#Bl24dUGbXb*M*CO@~xSh($ACCV+IPzQl8gM^zg3p>`4(4(bVc8C*0EdV7Zg zkulKmMfAxR&+I+@Z-2o`K7nN)M~XfGA@}3MgtiDRRbfef3|cx_^U5#~2&87>8S|kB z6cZhn$9gUZB=$X!nevui>jS_$A6EKb4n~xMPWD-j%O+{(otFx1)(f-dsPqeTLE-Ht z>0J$gR!au0-vd`frPH7x+WcAw&`B<1a`fEqp5v8)0>@MhFUXM7$WP>xu*1Uy)I0qy zw;Nvsf9e)rXR%@LIL)nxP*DNja^9_Wvw|cr2D+CqW&(d@1IlU8S_djf$}bdyarniO z3^$=hCjg8YFT3QO1$FGLoabB1prO|8-mRM<(5_mYJ07wu=I}z`6L}6>moJA~gqA?t zm&K%(PQ9+9nPjjU&ovpJ^W!f5&}WZ87wk~h)sMnJ?x_2yY|h{syk3H9_w&%A<$mHP zcC4OIHmC3qIVz!_;?c&mpx~csKlrID2qQ8PG~Bm%ehwk{P&3G8yU1T%#dsNWLtB%| zY|TWZ;HLppGTRxfbwX_|Up>=*Qa0dXF|zI#Mv0OI6FG!5(coCEehwvXNUTvu6AO9h zLPne}(`U%lOPJU|>ORwj&c~w1X5uCQ$h5LatejrA;5`qvaQG_fNDMt{A}@d1o({YPW0JKb3ib611pH!) z`wt>V#F-G46b)&LJL1vV=&0;eLc0KxDjnZA9}PnZ=Z+9EMf4hX1@@8gTDf8_H&hEc>=w3)aD$1+*8xv!TkbBbpJDs+~fDa8}?mcoqSN@ zU7UC{?->5&1QCK3m!(N%p^S*P5D;agNsqn)$#>!@>eZxd>ri9D9wqwjX zNvC*O!f5nq6i8)M9fWGUd^3aRPQS12IAKd(YI3BMy?{@)HY1qG#+9iOt@H4QP+81KH7-2Ze~9?H2Ktcd>n&5tEn-B)iF; z%APnjp8OFMBW926E3pvCM>mqoIZz8}7vkSz(-LRx$qj>2snHCW>s&YK#6$E zD~ATW!z7jr*zd*$#w3j}2sWp;wZwT)zsMDt=gA;wZ+bBJ#9^DlLhTxaJmmn6i&igq z>~+~N8*RB0Ua>5!J$R*ni11=S0F4fAz!0C>B>nGr6}^to3TSYHCuvEP21;dD{K`0# z=_eSZyR=QaHIHl1tW5QI?wiYUB1Ny?^>|T|$N+98=~Ti2E7AjB<80Ob=cc&x@Y8rc zbLfLi4e-tv;>P$__h{C0CI;e$nWbnJ)4~A>~53pF7&Zqxy+k1^>B}lKN`87Z8naJ>= zV*~uZ;9C)>u(@LtSD$HSs4Ic=W8=+M!MTb!>*Q+dE^}eH{i26c1yRxW^wQm7d$U8j ziMy_>jS>c!D$l^#R15<%0+|sDBz30$7X;&YvLrZOZ6>3~jBF{dyI#Z}4trOs+QYR4 zIBxl~{5QjZ*z-m20 zm{e&Yp13xM(l00^*B`z^NFKsVBJcu!{$dqsXW!S$i?i}2G8OwE$}F6|KYzp_=lZw~ z#HoW7XWSvwV&+8LAv{1sj4DPEO`dhOw-&^@{32;Dr(t~FX1506Z1L0zIXp|nDux;bc&#-bLNbs zO=<8W8pW0(c|<}9)$ZdV237F7{Yg86Y+{`h(WT(jH2MvadZs%pct%NxA{kwv(n)LZ zBLiWA6zllRkq@p3Ohj?O03=mgSZbjMOcQ_<+$bVRyLi=x#pxOwgprSs-Yb^7~*3asQffVznHo-75DwzF zD4K|Spzg`CVMm{otU^)WJ--2BAp3cwA2^W31NPB+3pPn_jo91$G$1@$A)yh9)ih)S z->uhI4f`mIR!_Je&yDEwKqUD8yf7)F7wuHMT&q-j4bY+T7i3JTAo>aaI>|BsrUFU; zAAAFGI77htsLwE#sOLg`a-_S!3lNm*eDLT187Bh%VtSkpj=-}4vPdu_7N3E1afG>T z-_>GN10TXyG)<^frxDk=SN^}bE}ls{oB|gEpQY#jNNUXh6k!i!ysOV^Cei~?N zDqot$%RrfcSJZ~_n9Fm5%_$Igi&h8TY!u%Xi^dsvvr+WQy%?kiA^v8QXmn7cm$@;> zhSygKw*@+f6TWz8OSc78-9NBIh(M%ZJXw35+|ab^rQx21fuUE3mJ~#7Q1!S4D4%}m zcM#!p2yie_WK}CY(&9=n8vhGT+`vo{3izMy8*|xA6iE|Q>6Ch(?7H7k)i=?I7FNA-h(W?zB-fORx>A~H%rsZI>{Ws`U%4Yv3KSOoCXSCunsYhv z8Y1i7N@Thd1C)ifuPDHY2D+0tI$%W6-a$_|FbcvjL`?X4lwvNm!oEZV)_*I%2=3AC2#0yZy$$USl<79H-*l=%4F3LmiBiJ*GTk`)U zIsTjQ(@^9bFDs|qH;-`hbfvNf?Wo~Ri}_Xm7gui`6=m3k{VEbe_t4!ibTOJMHFIqRc($rnbTeC)>FP60cgpm*kn+-W*D zu1~(k(MZmPmIE$@PDjEP)z!Z~Aa?8#P`BoiXI2gKEaq^9#wuYHq|yT93}s&`9_8i` z_v6ceXZOPQe$84D%H25joRg9#Kkb8y4hs?UN|-Sbj~yng{Ik*(2IF?7f>wUy0)%}! z7ig0{6v_b)2C&`=#oA18^SUf$OrZ zts^M<5?YxlDc7i-Ew>bI{NFh(T>Ii!Dp4NyHcmd;r!Q6UX(T2egO>JCfc{_*y$A;= zLTJE$r&aM0Se`x;PGkec;A3*zff+7}ADM&1Q43`u=d8dYdFAAtE|h!rUgtHV&e(q{ zYSsT;DgD3>qsIENmFSN#G*|aGha-R#m(yiF21_-qPFJtYC32YEb)ABteoO|cu;%su z8WKRNJ>u}h!rU+_?IC?q{QZ>f;WF~7hd0nNNDJ}r-NoW>r{>KxJK&$jDo8abb%to7 z-qFxx9B6LS%q%hMYZEy_K^u?I-f-1_ErI`SKve0+pdA0tN2 zKw?zMpM~bS*HdK%SSku{%O|VMBx>#zoM zt$`niAKXefzs(K*=;%LzVY+@I2GkeNM?8R97(PpYc*Fy8;wo&irdoVl1)b-F^ws1N zfqOUlDGNwEo3)DO=9Ka0nO)L<&6q#~Tz6dJ2LJ)u`(Og>+-rZ;Qcg|&=hvARmhFoC zcUVz)TWhdR$Md}+tJX)GIpCGpQKg@J0KBx%F90B8GFH1If6uDwcq)GS{`dg<=Oe`hi@s~UTAE;){FolJ zbO^i(7lb-N`@k;2X<2_pl^htoqu{d$Ud;0bfD)0WTR{2Z1By>gbZrq}w*RDl_ix-% zY3uqT&YmSQX? zXq7r35k^Qnu>Iyh@-L5SF!4*i+IT$t+{YA_J%9p@Jve?0Hv3!EGTQoYLSqXs!Gx)t zza>6S0$Apmc`}pb*AX29^>_>7kcybw+A&$wN1advnrf{~fu4VVe)a7<Mz zRe5xn@%?q{k_jXqMw9RTi0uF`aMmLg;MB6;@JIj%17dWQACRC|`Rar?1W_8X=bQx$ zEm8-4?{F#8FUlDR$V#@+3Z#(V>XGSdP^Zr1Ig!U5#zhjOJ|u0#j?K^!7>0tE6`cUfMCzEP_yizzS4u!Df$TeUvOYab zE*L=*0-0fo-h7CF9aQPW*p6OVav8E;xV;v{z2sfxnT76GAl*4!IVg|mPFydOKx z_t(GM=hmO960<%3mdM)Tb7)TRp~6?e^^CAUK_@2x7m5!{1bX*{Ur={#l?{Y(~^;AWs(GvbeUqWH#LnkNG! z^8Y#Sf-6mifTrYRqn_?I%Y1~zla5+e>gCb-a&QsMm=F7#J8`E--}0Z5nDc*^L?VX) z?D|Lb3X92<_7J!tsy_}?qFMoI0+6$ve$g*KDz%T?Sdj8e5Goan4><+ozxY4Ox^qA5 znpzn~cMKKDc`_aajz<|63nn%wx4=MoB|gxsycT#>mv=XOzn5vB`+A~MK(CvqRTauD zpTVgPbjgpK*^FoZ^T_|J<1zq0+z6k0gjFhadl+TXC{dm-RJPw=KgJ8bdP8wD{>Vz) zcve{UQG3SBTE|Nd1Any1WizoMYO>rV0|@}%IReI$cz1K*p2j>NJMJ&HnQWcUySf6O zLZA-F{LBJ8g~=_Z)rhO)yjy1BLSPduY?l84A-4$Z*P>_Z|L>}=TFSyZ>1NWpQxH8^ zTS{mXwt`>u-vF-R`z%B>d}LJS#_8{p?;uA>#>@MY^l7UI>~+BInWY!QbV)|=F{)W{ zcc&)y$3F&SI{WdcVnPo9FB~v!AznOhnPsgHssGgU(F#(zG+A;gSI!qI+iqNEeBjY# zQT)X7_@?BrFTZKmD4p8$Ow3ePD>Y~@cWZnL^vby9+f70IYJ@S@$v zCVGD0>M=;PZra$9#lUIYgL!f=?=sR0;jc~q5j0IG+^m{t8c(&Zr@?ItNUgg4&yh-~ z^fzNODqBPsowyT9$r}$%+H0e#*T74*cP~b?o!ETm*|V!eQMLCOB~{T`U+;HwX*`j` zs^XvZ$N2?00f2PJ8cUeqa=4<^bzOAEIHyPJ{3zY(;+?cK%4 zFzt1tIVHY%4HAq+dp{K<`m{38S$+BaK&_i{2fr(<`sVZd* z%%MChgAG99;*6cUTupSpVWszXS3Lg=IQy`^hktGo*a2=5)!Tnrq1ci90Mx9S0|b2V z1C2xMr?smN3Gk+--~yU>82Oh4!^(P9LnBGYafbNc z`s1=XwtE9?vnn(yJY6dz{cI|iLtj&Dm#O?`=&H6jYWfVbe(vlZ_~f>s zEZG44=p8a(*$E^$E#q1aFUnAjCSC8l2AQ;|`}r^q(qcR$-AXIDb1BSMe@bxkT;Hp3 z`203w(qOQ}ti{_7*!o17OmbFg*Pqs0c7_E`R~RX|hO;9ne^cjQbkEUlFPiYKUWtRB zx{qf10)CvyGaHDhrS9eo#*)gTs07Tq1lpO=Io{FYPz7DT3w(T3U;|>RdTfJabRevE{*G z!S7T~>fh1dz9X5@nW6GT4ute9Z!kM?;ni{kmPRMUT`@m|ny#vYVyAvvbj4<~djmdr z!y~o*suJFG`Dji~wz5aPvw>7sS3_427Jwp=2oOptPDc^@4fCV9(WFY6=5C#6A|L25 z8OVzdbazd5DMdg30>91xAzE+Tu8h5=44hM-crPO`G1o;C7{+d!o3eQrvo3s6oij{BQWz);TqWK?91SuUwsc|y3OA4 zSD|)Sw7m78u}>l7cLj|225govS$in5uD9LHN*muLWA6{c_a&e^bpkRwoX0*giaop8 zo>AE@kvwSX{_c3qF#Y8j2E$F)8jz%1YlZi|pElXKadG-N67-_$?AB~Q1(vV;l9=!P z1#>cV6h&djLzz608={1ft} z$USS@r~TTE3m(z9^lR45M$gvOd<&R=WGP zNiz&!tdI>001C5#RumU{&2$3FSV1KwB+0blJMIfX9%gE~!7_odYl!^-l$yTl);?_j z(_hZ_pkIMx5TJU$>nK5YJ;7kiXnY?3=WrsNU`#g5d@&#^1YK)=ffGq#RR@#To8X*$ z5=syVnC2C7k!OIz@A4=e+@z$wB|4M`I8?6dLiDMdIwe z96&?;gqQ(lmP__fQXY8b0Qwe}CuFqC8@SnX;Y^JFR{K^@L(!N*`l>T}T6(xi_zy6< zHt0%6fB3f7h?zL)f(a4iH~qGEr( z+Z&bU0DDz5E=poCh*6U^H=r)y@~xgI@I8gNYUtc7Y=5CczWWiM1)6W8YXoEH1$)5VZ;o2x$jN93sarIkubW7X; zj{xjBg$JgON?5)|t4SvIO30{x>a!Wb*dj<91{1!b*(+c+NAQN`(GeX6HWInyiNH>G z=IvGFG`#7-_D(53$Y13EE$0v5H#qG8WmN7KSSj~z&uB9f$l+d+arYOorH*H zCLU(@H&;K)A$DjD$hllG4wMPJ^?gjexgqjS&ivdf*L>qYA&@&*sggYaZN3=1IYUi! zEB_9!1~H8?)5xC!v^`}(KEo?to{Sf6Z3JT&m_sB5ecCbhWGuM(iW@@d8G8guCqO@2 zmj;2w8Kt;kXfs_e%-Y3xErgn8I3XFj;`8c`I@ho;vBkzX)7~^@gMWi|{T`Y`A z_uX6J5wk5MmF3hjPKHoddkfGKyhbzt?)d!o5&@YE)kmIcTI1;u${`^@eY=Q^}Mfrk{LHmeyG2X?~yFx(TANI$_{tw$O|09cS|L3 zy=3)+cQM;YK=I0ZQDd9Vln)cBji9K7OuD_Ke^ccdU0|yz;5U0h=pnOI;ZU`ZkkV*WNc3F9pW}*a7akNj;4oYP6Ab z=~0{fD~FsB$s5A4+ZBl_VN~o{Ap3LAfhUdE{A5qT+A72in-!G=B^tRA_9}^o0YRXA zkl-w`Ru_~!fJGcY7D4xyx=QijR_Mf2mX%#fbYnf!?)Vw@x4Z>&k)>xm4pdzs_94hq zvW36BgF@H>Q<_Gk4l=}w0_$k*+H@z87gW~I_zxAS-bH0GM_YsZ!uZvy;-{!B2U2LZ z7qgV|dt1=?ds>6TX?orG_#0|+6XCC*VOKEUC8gFD0xJmR{|ozWQ%g~08w}8DCk1tU zYl&~4>NNU$ne*^`xI$6o>EoAq>wt=Op(i06{$`_5=DbezbzMy&f&z1ZX3=v^vbyXI~P z7wR<50zwte?)zu`po7ypqyc z3qGqmAjXGg%&3>zNPL$TO{ol^KagK5#a>ucg_z$0&2gQ-Xm!XcY`nqQBr6gr!@q4c z5P||G@0B=E1PQ}(G8a~$VJ)@ut`Ve^@B3B4qh!X2ZJP{|mE8$1ol?3RmkOD(yr^(bzirSrDmPMl!g$K6{FCy)^ynlfLt z=T!^PrxDI*!mdR3X4~QWVWeTMQqk^B;{v&tCLGyv**>n|a7r+LTRJmi_Cz2!n7}E< z3o-yXAaGA}JqKdPU6%a=TGW~n_{ZGLpT-D-OM&KOIOdRl*{b3tzVyF@E8z1v=6wO! zxRHa^9*3@RXf?rk&V=b(qDqRk} z$Z^q|?^DsAq6?NIQ!lg0h#e|+n85C@kBF0P%%@v_5{BuXU+Bn;f6BnQiuxhhI+NK? zG|Thlw8Vk`^SUP3LASkP`B^#Fm{_v?x$|+SJxT}b+wHRcLjZD-vOH#KW{-jg&5CJT zok~rc1l38=k)8+hH(OeUMg0VJfQudBGtDd>v64=6G^wj#nCYdXJ(|MLnoGIG?(+aW z(MFUJ)adQOW(}hKRD^TDC%0c4ZF^H(4Igt~yfic^J?^x9AWxQi`6`vj)U@v`pvg}~ zfWzzI9QYcM-f>)FsfNZJW0a!?T}sL9gbD&cl|zdED*;S&vT?z zF`G8us;wLa0{QZ8*Ut#;+%y0|Y?*ZVYDwhr{H;_40KW9op z1enCyXY@Qr8LsX?2JncLoX&3@8sInz9x8$@k0Xu>g)mNQ;DZGUl|Wp@WY=4sjf*qp z$=lE0UuoU$0lbStbtX|GFW}qm8(AtfndW&eFo)c{$shsylY^cOV^c(R*are@C z+ZM_K{XaMEtk>z^cw zAWP;eQDTzr2OQ2xb1Fo@r4CtU%(d$%Y8+$)5@-QODtf9tP>myo~Y99 zyR7ixYC#DKF323yPlAIUqGiZdWPr-Ca@6+~ZYx*=^_njhGoNo> zX4i49p_1XFBx9O4G|8bRV~>yB)hsbkn{hU@N0Lbq6A-0gnu?m9u&oT1pKy%vK=zi_ za`XJ_F$2=0cg$UXt?(KUN9W6|IBY!P3^L-4>v3zEL{Ne~*@aU@8$^*|vf7D2F{B4Sm$yL$wb9XLUmA|Nz16P}RNWMsRh|cz z+sL%7iE6`Sl@fxJzgecc@L$#smqtM5R#LkppZ?{_HE+%1Lp{2;s^Ht+$cp%BzqC`a zka}d{9vlu@aJ`B<#oIFLm#UkT65loYk~-P92>@>jhq8X}@|ATrt15b0-}TJik&)p) zfiauM;YgTb5?YVCF6_Izi>~(!6~#w}OcAhxrQ|eGj0UWxmW^5mkHvkw*4}sE4%56H zX?Cf|T?J$h$5AwEfNAwkA^{!%Qn~Y*MEIHY$p|yP1`01~60Z~&y2*MBkwg8{QL87( zpx&69Zq)24=?aa2lnL^bh$!Z!&(&Bz`(K+I!XTu}g7su??el(88o zZL@C-lgMD2UE<|KG^j7t#HR)o=uT*WG~XIk3CmHRaXOW@S0!V9+7|L%#yh?AU>{NQ zrq3xq%VGYt@G41#Sj5jBaNn&+@xF8hiR*>S>RtF*HTcl2{h;%TR|QF5WGYu?wU68# zpmo}=>OVtpffWelQx9SF;cMv=b(>>%{xZ)6VYA$G2!8tZM9AG;`XX5r#WbYAf zir?JPvEIv?LYr!yW+EMM@VTG~_%CPfX>WIDXZBQ@a2giz*9dx9xZBfpG&Hn}T4*bT z>foKb!qeYWMxR)n3k%l@>SI{9$KGFBRdfN|6jVYI2wgO}7g2cF{br}eYMXMgVMn~3kc#KMmKGbKH?P5uUk?f;o<0E z#^N_SzW2{4b#e7sCuMwO}qVnae zUaNkVi6H)7M(X#Ld<0^=Kw{rJH7WwP+wAS({ZsE7!szA+7*k4{AZW#W$W$z2P@F4O z+_@OoeAS$&q{zzbPT>uizGnI;_!1UQIqVkHbw^0p-CjePknwHBI9QSaR%?Y%ZMXfY zIZKVsf4(W#UB7Bfe9Mm3lohk0zglnf+1mN&B@}nOM+VRIdB%?7>~eSX`-D!Zf0_la z*pf*PZ1KdlS) zP2I96Jx5cC2zzJTt!X0;@U7wlLs*i%9SFUO3a7aAdrAYs`V9pSkF)a*}aP1{GJ z`$%JCQRWZ(CeaDn<+tF9$aYaKwdjv6_-kb4obtK12)hcm(;OeJqqv+b-=iuZ9uz>>@5R%h#qVR$*iPiW1#yy+ zmGZm=62oJR*sjTm5i<8H#=W9VNyw(vX1klG{w&F=)SpM1kQ1w5lVo;L4O>3iqvyf< zfQjNP&FTvyCxic~Q9eFcrC8HWxza1%FX5qXbOX$4vIR;)^H!5=;Sb>qONmYMr;Y9Q zX_ee?HKU&=@iF-_klm&Z7)UJl>x#M1h19iucI|e|zBoBEr+cK$aX;EIls?JLXp08q ziRv*~r}rmIolF7%3$j40SHT7n1QQv&U!k#W79L%FUp^A9lr3&oP!i{V%_gXts?rzV z)F@3=(D*GP`gDm5ZgEKs_vBOCvt3dErlhc~FWfi)Al77oX6H($o0leMEg2 zCSfu&E4we-%90_cUPgKH1NWB*ozwX^Rg0(7F9&*|ogajgsZfcD9gt|{gMl8A?l;k1 zn&|E-Rs#6`_w>^E961qlJvDR;R9^1Hw8ri%sjfZFW*Sabg$Nz(N!-WKp)?T6 zcI+!yN8?n*xX@*quy--`6wn;1kUhoASh>6E|uS#ynX&ZC&O{{+>CEvb?@xDamcMcc1eQ5{rW;yvb95u)`m?&S!W-&k_aQ z|6+a@O)FF34*yvG%wGvE+{?HHA$IZT!V*a)Axfr)wP&K9xGK_c4QnBg0G6@sy#o;0kj31*#{WtAwO@wK9~S~dpw?|U_-*k z;w}6Mc_YT;55Wam^Ly<~P~%E=te_fUAmrf9{@m1eWya4LOlH7r9jO^hU8O|(KhM}iY0;cxRG-72P*}Vx%o>A%JWZ)GZ z?e8~E($P?fuZd4j4Ps5Lk84fELm8N2#LVwSBE!S&pk2AsMMUKd0Y!wbn#9-E`nP<- z(8{~0BLEZ9))FZ|2Yn|v;_L+X=r zdW5IdY+CP9jF1KB~_@vv(K9$$1LxK(GU z4@y-Ph_hgrG1nKI^ZrPs7kAJ(4LvUQ%}pKF1qi2zBIk~!M;%6Doak+_LD2p@5?9uK)1wF`{Fdu<(2w;DEISK zzkXoyA;;XCOIDK>G2P8-;zK(RSgHmm)(Kl+_0rS>8krXd!xdur?uGx_=VwNXx~^(f z21*<$iB+Mcx|~!~nf*0MQQ;*McTYPhYpc7?!?d( zcl?6^EU{z-SmB?S>0;Q?(zKfFm;@_>TNEBp5E)xRd+|O94A}2&KTLI~g2r^c4#|JK z>E)QV13STsEEpIs8?igqP}-XMYY&VA=}5eb@0U}^|DC2dJe}6dWjHrr$R%)s*d!EH39NRwr@8|GOzU!y_n`}Y5y1vSJ-I! zK{Ddiv{0b=9o$Q5|*p`L|V0|0(4@ zxXR`Qy~{XS&-Hy`VcTUKb@t)mv=X@+HZK7E(7}`n63Mle!mEBuh=>S>oJU_J(h*vf zWP5xtqvlNWrL&m2Fe@q)@V5G*hi&}j=2rH6^x518#=rN)Ok31^YMljMV~qIvI+OOMAKQC`C{eCC8Fn@6_ z<5&}XA@O3r?4ZhQJNw-Z*^+s<<64!D`e zh>{_G!+b^8LbFVGUU8*RS>R0~H+KQhZfMpiGyZw9cTUvMZ6(biUsp34QtIy9^+U^r z&dRn3fks<^QY4)4+cIeyd<|k?Y2|<0Tnx@7lwX)d6x`{Q?-R-LVE_hxY&6p37SS?df28#RfIh-1NA zr7aO%6j&C~S}2m~vYj!nkXkSXTpN@u8$nP;u?8 z4qn5;Cg%IF4B%)mjPxTkt1_x_2l>gF;t+bYAI1b3`jcj>kVF;oFG+p^0NToKq?QqU4u$ON@Xz`$-X^$HsMyvy(hJv zv#-*?x}mQK8bXS>trE~ace<+mPh*A8O6X4<@g9jBldKsu}kK ze0&cxyDWs?*|gPUY9Od`cN$_`U+{fkYWf5J&Tn+^;KYNjX39~6J-y}_{m+OhIiZby zwQer(HfDS7#C29IaSG!pVSQLrbSVoeU(YWs@nPni`R_u!GD#~@L(k{6a;?&#yrik6 z#}nJ#I@kRCUA9XV6Au^z;0%hy+8~vyd57yT@2w!bYPSRn8anUmFZ=oju5oo4LCJpj z2b{I~eU}rX>ey;?J)_dc$9ro6Y-PeA$|a$c&;9kCJ3h@l_RWs#YV=a^_bJnnUmCcn zT`i4DgOm(tVm$L8qiWHmM$b8&!$^?0`hx}Wn^hFIX&I=2l?P_!HyP=InrGZ2=Qai* z#r=x0hnUM)emokw*rm7;e z#no|%OYBqHaphhj`?lQH0@l_0KK{DB(Y5hz>E1PwS-#6KZYA|}=U9-dgO=H^I1GPp zUB;|Qd=&8;|Qmc4u8Rjye1fwnhj_hdJ;#WpjH5ujV^fRkJ1#(?1^iE2SM>Ixb6Gw6fe< zerhU_4^kYN)WswoRTnCOvA{p5Pxg;7UXWo=|HN+7jGzSwgPr5yx|lModG?SR zUbZR=GLpM7rfli=`n99w$)mdax_a=o>9=a=7B~s5`)lLP0WldXj%5stA!7Jn=mNO- zL=3K6n8wHGJPfbQq27cjP!dI$Ebu@XXJb?ZE`GVo$x1A(Cq2w#>4K?5GJCbsO;Psf zbA0bd2@aPdgs4u!H|jKCqx7=M!878aF&XwlQs&BSoP_*PoRJoTI198Oboq5!U4@5Q z>T_%cma zWX+A6KYMVS^H;c9h67@*o)`*v=gh9!4cCcyyBLuNs|bsKdQBv(A6NL5Njb*Nm*><$ ziQZx3nZD}$2ged=a6P0m$;NqdN8ABiX7>EHzpWdgm+-RJCs-8?N>WZ}ZW$VTm>C{& z>hc#j<7FrX2uRLj`@l}pD=Z=q705U6HaUXV=ZA9iGm>s?Pv)&;FNz?8i1>}oF^<2Td^XBJ|sVt5`Z$`h9>>RF zS@T3WguZFe687(ec_m1Zn>umev7D^(`6%mOU=`to?pY4gwA!7UujY)Po4yz)XjOM2sqTfl{y4i8 zeSa~5C%LENeO;5^;hvz&NV}$JTqOLp&^+=&AZ+^nQ$;`B{g^WMvKxY8^(aBG7v+$B z8AE-x|0GI|U3bX7?(|og9g_p3T2om(;}z;uM8aU z<<6;x^;glsvQw2%7)2na36ge+9Vj-yG4lV+0KjwJIQQB8SY*1Jy0?OOTs*`){}ZZ2 zAECLTGqni3X&OMj$p$p~y?BAlkq3TJYx~qTXqP4;%#E#esxzBFGM9kC?VD2O9krfn zDTCyX7wo~-+x89;O;N{nx^!2Ij*nS5d z7Da}(0TFOls}RzsegNWrmvI_vRhS@v69$11F~65Oy04jx+#yKGmMpQ_%jKhL2un6d0ci1 z!lzakUUN-CV$ZiWDRm9#PA8V$)^{^L3lXKOToFBoeU=7k^XbV~!1%p=;8! z_6*g+L(oJMI04C;xht7{m{7!9Si)X4R}A$xZkNlP@aWoS0RT_lut7g3ZKOz0^(##k zb3Za{Ji>$44Q%Xt0L*$VPLNiw7P?;1ZLrc4Ytv~?C4~~2JQciF7zOn)Oj za`Ya2j{J=# zWe(>P0OP)5N9XGRnM7uA19)m~cB21Cp2JD#x{RX)uL-K+B+=TulOp$ycwIV`Wn3pE zr8A+hw??Am_9j8SIo3rDCG56ED4u{de>-zF+xT_1K9&*6digci{=wu7%;QoeA*Lv`ivWEC|}w8N#<#>;9$|kPOdb zZzavRLp=TnIm`E0u<~MAPM^pw9arr7tE&Z4roaTyi))Kd3HWoGCJTrft z>%)lddwvW-AEGGo(>5!Yc`OOYADIZs*FF;e{V%|gIwsJ$oLklO@m9Pcy+3n{KJ{@Q_# z)1Ka^ROrkt^Q@RHKQ=1lliq%UJ|cOv0U5}r25~`%x!LVkd3)WKh2@1 zcSZA(5}DZsa8%IxO+VuYTq+Rmszw;WF|{!s4ecNGi4g)b)ojbI-lt)>1<^Gb7A4Zd zzjDvBBVJL8^N`u4ri;_1m!e5iO{YUn-((IgB>!v>@)!nf+YV!DF*%j%4sX5Aw%Q$8 z(Y4No@GkVmfSwFJtl2w-F*=2HF&-MUH9Bb~N=Dbbw{~a&4rTbh+|=dt+$2}ZVNzKc z5z*0&e`Td5|K`bGT#?@gP3w3;bb1{0Q5BMiT86hFxE9kKP94YQ>px6JA!Q(|zPsi& z%v3(ZXjbGD`1Gy1^+cO6wyt&Ghj7Md165pXVRJiHNJmJ*A_v$j zOu)#DbDsYhnR&wAhs5^YGv6q|Akd*zV*df@k{~#8W3f8n9Y6=SQWB!ZRihoe#+EdJ zrJ<}s;SrpSFfUVX~!+Y$(T%EY(Iu|{syz8Icz&Pd-9i}(_ zae|<4&^cf_XzC7PTJ%P}J{0pSNuWf$I zuB%btl%kb<>NRD@;2_VBzi_kHkR^tJQ1}Tl>7oKdV3eBE+$DUG+rdZ5G4Xuj5Qv*m zhcWq!ggtj^IwNlm?l%zjbBn^Uf^-oK(h_(_ZK(E4D934yhW+tL0QIFsU14t*>ALMO zf2_l6UI!}D$kKhh!TNM28sDZzy^E*|`-@c|s+!JGbG4}mc1!(Fr8$K~dJ*B7%pU#V zK{K7>L^RZ*;ghKur3lp3#WnHnQ@fU5!)9HsI;BTSVgu05GQFjMy`PE%pZOZ6`O;;Djtd6WHy;O?{6~70jtgpL@JF~?{ai?W$ z@}CXVbuAZPY|4C#Zb-ZFm2;sF0z*ylT<6p%P{C%!#kgX$mQSGk-5v|I8Nc?f1wWIA zHRwsVmY%XludngkhSFlrkq(Dy&OM*Mt^Hel+##8cMsoT-TV+VYju=(i8Ku_*60Ec|4j_s#uP8*`b}vz+_7cUjJaeSyZQ4CeLnRj0>mj zT8@hjJ5CE%5YIH#5?mFXejXpQKh42C_(c13jOTB;1w3GqGN)Aqu5z+uWgYK>bsFU( zR7|1D0+JxYX>ZtlbAoFn)A>?8HPTO%?>@EdX+TLRYT~(k)nMX3^|Pyt!*gjo-V9(2i)hxDz5UpOp;J6C^o z>djQA%e58xi>SujDz35Yl+4BjfgJ;$b#>7j1t(whLqCkfc@*V(|0DxDJ3Hfj6BZd( zm=}_NlRps`v~V0NX}<6^6Jh+~7Oqj7|3YK^uDf7%w>7mz)LgXSX^3B&??XoV$)|ed z7<+Injb>EME6kybuMNs<)0s`C2~4JA3VA|6yby{3NlPr zaTVM~zlok&c|93Pi9CSmqx7PuSr0i~43 z<|A^G6=FP+ID35csq`-RsVqAJc3W3#%Lx!E6aq#;@4|jR>-2RXqV80dRqeO8jqeeG zqQyilLr1r|fPCBZ^-jbp8bWj+y1d+>voiI_EC9zqF2i9Tzj7CtFLrM#--K>saOr?k~*A-o+^@TtT6;vjzn#?=eeHS3^FvtZ}|UV>(Aq%4BPi{JQ5?@SfcEMq9Q5#7GrG5 zGLh`5B*vDVO7?v(DNAT3owS3lm|x}(E|c`)5NMZWG@d0I3?%=tQ|%SUE}+$j@b zyIjh4L^Cf$g{~H3;}UPsPxyHE=1+%%9cVG^WtV{_lbV7uc$XD{vSsJ>9v+^XIuhnJ zdBAS0)Au#@#vH@MNA)%jY0e8f3WNYvJ-QqL`Gy|>Z)vG{B2$8F_s3mibAb=qBAS0B ziu+{_S~AMu=+k|no&1MY@AgX|~HKCGolu07k`Upo+--80*2cl?ff+?m~cYSF}ow1ASkw#V%K$Kj`n{!hZWSvEyZWctUuFr|MN5@%ziJtO~EOX%38k-nlBqinPcN zoMCv$a)O@j8Q;4TH9C_(@bcha zLdj-yqm1o^nX2C2zTYzLysKR{pzENt#5LrpJf%LhgZk8Z>)5hQ2kpfC((F4`L2v$(xv@W6C&uNKC0&#_AH+7%ZrQ58+8?v`Q+z^ z{v{}$Z*|oa%dt|>mi+ogVd!Z|pLeIjG^N31R)Mcny>9xxUhV4d@ANB#XzrIaDKhk@JUa9*5H`jc4{DRW^-H$fLt;ZF zUx!~HOzF0l<{Zq==By@ZosCIoxNXi;VrU*`Mu zc9@H6*RWyJ|I9Ve_|2aDhOO|_I8!-zUbm6zh|TF(O_zwC!TfMFF=~irSpAPV6K>rp zH#B&Rr}h_{|F#Sel}$IpnT?~Ow{#bh)2=zDR4I!+AofL8MhWH7ePBI{jp%T%ZduLG z-+$prFSf8hBoh~?|fN5`%GOK|Cov{L%9p5AuZn7BJ-bouGw%}492 zUj>U-`d!=P^w8YZVWT?YA-WvHdW34FBqclIHaCL=r{=Vq+B@;fhkt}jGjuD^Uew*K z(7a$~pgSV7=*(Z~bfw&D-^3+6w){j7)t`iR)=LV1jN=a_lO~ceqn8w}4tA&9<#Qsd zJ09XcdC}ZVdO70i%8#daSRsHAboOm>ATKhVuG^^8@q}X!CTw0UW#X>ZCyXD!`{ld#5WQDL%ez_ZslxC)P;A- zV);EwWht@rnk#1;9FC3S!uDfy#DfHHP0N0+boY!j$MxImh^$3Fxo0AXDgP11KGeDx zkdjn#{;|1(Deo#?n)o(^heen7qGeC!U?o{SD4uty$(b1+(W(4S`OS14ty5_D;H+~= z8_M^iy|IP2qTUi6X4>#$foX*VeqjyKQqKA-wbvCMt;JVnL@b~ybrI8~5DjGb9vz@I zmmpL-l$0N*A;LcQDf3v#jM)9M{z6ECb3~xPyr&}ODG{(Wu$;zIK#YiN)D6y zkntIZ(pYLmue(;za+3L^DubM{iLg~tz3wsDHtG&#n;$Lg>0#aHzNgMqhm)TyEBdq^ zS@2NW&2%fy#%q+H7#o;ztT53x+y1esDNL9dbpe!jldQf@i7`4rbQ2wsdeYQZb;D%qRBb!Ae);c5PZh&V}kn&Cqc#_?YJdgo6{5zdWK1stRjyW zSF|WbRvI6Ef~?Tyqql2Xzgbs5=PS6qK8k zwMc{Z@k$5g^1}+UgD@+3S(M7~_|qHH(L?pK-hK;SVd$txwX*rOa5kCrD~U0yE4C#& z=0XH=yOr->N#w1ESE5N=)aLIU8w@GUEoiPPyOrDPP0f2nw(~h5SC?44FH+k|bUF2MRK`d#|f1mdqOrIKpqVkIWzi;pDz;&5h%Nt+UJ0FCMS zqOu+81sjj^?C>9=(!*n9J#^ecFBr;H)3ZXYf5K0KI25+l{RA#7Wn^?RgB~vY3xuF15dSWgPqm+27b2K=Qk8x)?r$Ja zOq^P+$fLpO*wFsvf)8;-RvD}SNCC{g;iqFfoYbNN21YsZs4zAe?6zOW$H9_X(sfo_ zliBO6S_;hp-M8@>U$RPW^u)lc`2)Hb-T~Vi>&xD=eXrp_V!(^g`^3?t5D@L!{=1CN z)%sQ*ujyoT%jVch0c7e!F6E?Vte`$JqECkit1fl8(Fk+Te-e(WVzs z7S~YTR2ZYf$hKxCBYZUP+d?#iO4!zFu&s-6aL*&}-uKlYrf*L`;pS3pl~3f<)@P7Q z83RMANw@P-KR`(2&G3l_HzN1t^8h?f@dyP0aTPMRtq|c;d`7uAO*#|8LlQngOhv0b z$wCENh!falj6@lNPq32OGQoW*qfz=??e3q2mmr~Q^6A}(fa}3-pPL*Q`bdtedcNW) zZ(c<&65=XkshU76|35CksZ1>!i;9Pkalm)3De&zpDOcT4FKzS7?9}n0u#JSHQ=c4F zr3JNN$IPrjQoayDhS~zzP!gQv5E~SQE!d)aj?2dHH3)6^G+Bb-M&TV$Z6kbY`?!hN zSb+q_t&%m2b4L~o+J`J?+O>wZjLc9Yh!D;E3CG+0KfsBJaAGaR_S!t9MHqdaVuEk_ zsUSo&{e6>EzK;S;#xV2zOt=QT#6O_VHd`1!Eof-=qJ5Ur16peoxS7?ms~eDh&>sPBE{SEVh#pwAE&<*P9 zA^5fsJly=J=UUI}qAY~tF0R#9BITQ=kxCa2H936%G<7`Tr8X_8j!QQX@`peiaw%R{ zFSU`=ETaxZeY0v6#HiPIl6vCy+3>$@P8A_K;PlrFP^jSFkR{sM-)A5H-+GjQ^>`6k zk7&|hW)tYN@g)l#-g2BSIuM_PNW^UkG{WM$^eab-CBGS6PblSl8s|cetT5P3;l7$> z>QrvkEaq<1i#B2<6YSFx4pFy3ijbK2jWF+w3PrIwaOb#qN+&kwAWeVzfL{s>+JA!0 z%WTyFBH{z0P0Bd(E>TP^{i)xD%IoxkCQ^Qi(rna1gk;-(b*vidFAMyczA*UzHfX;E zit3AV_D0?Uly_$!EG)ndcidnX0^9+_b;5WjU3 z!z7<}Uf;eeXatk5+w&lKvEYgIpRt3tfYTOCArL#p0(=YT-Ff=1-Ij|ts z{nq7?6#*GW1>)68;iLE6+`-aZWb?X9!(7yOw9Xxa&vJ}MUxAi!4WR|}FTX+tQ`)Nr zi+3`|tJEZ&l;nOXch=J^51xGaQB0)cy%m%p?RY=Tf70Oalgkc}T}GtZd8gjS9m%CD zZIMpaF6-+x98=2PAl5GOUEF^#QEkMNd%fMJ@wUH}Wc{qraG_x~XI$X!*3CNbRCx(H z(!aAYpT2-%yFiu<*rOLVOtl!cU)YB#=XtJP%`PLW>R0Z+u>oEn7fugqhO1R0+Xh9Y z&V`skaBAV3>J-Ztw1wd5PMOEnF|OYJoyMp*H_3 z21VK}J{I}^%8W=OjL(H)QYT2w)HD6!S(Q5*UIPXCp07t7p!~{)Rk3q7_L12&dc*z* zX1@8oFF#&r&`0PN9#ez8OXa6{3B|#PW{nSYg1pTiuhunU09Jwx}uQ{*&whUe%bQWO4U3&Mil8*&qJ;obLxyTAjP3gm7 zkXH;cE;C(CUYTm&?&$zyt%5`N2hxG;2IZMvMUa%TP5Nl zcTJyFX~MIOL55uXcs&s*>b#YmA-{Fx797DFBIQZh%{}O7Ft(oDtG_yg6YXe&B=}#v zhI(l}0nD0Aar!cpGoek(T&KA4!h47fj}IaP>p?kqZu@{58Fo9FAZb=J6)HK}k1f`G zgWV}pfe4FqbKRU&83X2#x|M#T;6OD7ny_QwsWbszRfjfV$&jZ>PY)iS2z73+Cta50 z#-E&*FZqHMWI_rkqS+}am5HO?_2{TLpdi_iylg`SjZPA2d5;bEHgj1zOKpPRQw>^X z(8wu?ejuoa1Ml=o-5A!>lYeo!;s3%rTSzI^`cgQtR0PjkPS2#Ea?s zi=cDXgHa@0Jc~qP#$1vrDtP4I7P|R=TPW_ZR0|Ur&|lHu55gJEPiG1mIT0f&bihd> z0F`%STqee*D@=_O^5Bi&VgL)$VVRP{rv6u;ef}{V+60yxN61_DE`{J z*69$lOiysIct?Mppd~B}chHerSj!MRg2Wx2=f^s4gSDYAgLs9Si{Kx>?W)CrTv zVn{M8UpZ@>;Bu0UzwSf9(>_{p_01>{0p{`ACU&6tD=~|b)~+i`ZWnOg-TLlpUGL?N zqD%)nbH$UA8Dehxfg0;5XuhXk4=Lip=4c@yd$8HzjtGuIkT&+tsDh_)ye18`fgr(I zErC~|pH=a1_TJyZ11(4p4SY}-LB}McQw=Jk_0W>b@Qj8puuLh9NZ!vAfDLYT?*zdeVI z-kf|K>M%U5>gPw${|NO}O+xn@<3d^K6F_|Z`S^N*JLoNcFwhBSP1P>L7vA%%vBZ@r zyu~;E2CRWqMyCh7h=yW5Izw5y2$rBmjWyI4)ZS)WwSLIe?!}G#=bGYlzo4ryoxM(# zCF3n+4Vj2rQqCv$qf57jvv2*F;XN5v^7P^PgDXf+k@)0&H-ru}`C=s+Td|xM=I^r_ zon-NlhN__$)rQ`%n7{F++6Oe_Ze}H3ktU|vHF%Yy#T4Oo%Vzh5ub(q(C;a`rB2;}f zXl}Cz>FQ5p)|)Y-buvgyU@CYA-wo0v=U#w0;dD+R0jt6qRKWz&$J&es;u~6x%qy(c*P$K6k)7-b^r~K@-kxs`5 z>HeHBtsauvWT@hkmkw!7Y(2?LgoW%3KEC}YKU=cu$z4BekrRK96SRXDv zylms>=rcl-3suvBXFNaYjqa==V8y`xW5m=#`jXlj1Qt0<{DjuQ{`1(&&agj5m298E zN1iiWZY22P%WQ?xN_nWYi>tBKDz5qOJ`oW$EH8x@`06kp-UhPVf}| zq_vrx;%lVN96NF|bK=$YN7g=_6FM@156*{c_NN;Qfl{n5MFW$>iCiK%?j=db&+^GB z8fD}zP;eKcz9$a0(eZg1G4O)f{oPZVIMtnB#+#6{>cPgWB>;%Yu25k6_)+V{Cuw69 zBpa5o+K01BH&7|>i)uJ8$McXu=)0EVwSn;tVkx?*-!Whn9}}Ix zPL0j+f#rF$RdJChG~ohS5se?9?gdS)^SYAdbThng*Y^tFOD)fx9QzIO z#$EuKlzn!{jUOf9b3KNe2;3ZufmYY!Wk$iOv{<2WvJ%$#D^e^fxIkNw4T0F+tqCp? ziE}qo70uXbIR2QiKlXmWjl8US(6fFCY2r_6g21_PZ^SgV%r)R->p2_nL`xMY2jOg2 zfS^5K{l2htArFp%&W?D|_uu>tJ*E9J1opUg&E` z%agK74)&pdIU%IVfB6;tRG!opOejPnul4X$`mG1xY(2RNPr{X&h zgq|XS;WPj0^Vk^s44rwy0Qll1EQ|F{KB(4!!WqYj?XRIM^^Ke3pYJ?GU3Kni+S|S3 z3ughIgX`xD_=KZO0;;0|_n;JbQSz*5WDGnY7D0!64dV+Qvg#)dt>?Tu3xz02N$)I1 zV5|H%)%5$?CbVSFp<(acE3$*9DtQTRo`g>gt(ymjO!S=C1r66^q|`86eTrwC!n}9v zwcvd^isEo(X#zo7OBqoXxrsR=S7L&oZx82jp2&!tWf2AlR_GvGJ1SJ<$4W3A|E&y{ zTJukOL9EyKrVS=;WZca1f5#s=9KV3(epiX8;BLAeh(CRPQTyH}E6<*9f&oam%BSSR z=%R}A0N;DDJEI^K`W=YXDgvvYz(Eo~#Ftg=0pKS9d%S6_t?@-*miXhsV?@)Pj{hs% zzD;~8ZCY2SVb~c^$4CJ z#!;{xF%D5$t%L2uw+Yg?{?u9ywhBssY>$Hc`?o{FNQ^P8LDV|yCL(wgu_v3spivSR za$46Cv6Xy@2>xSkU8@D7h2MP_-Y^<|1P|!T8)w8THX$&W`g`Zo^>Zmlo!j~KVBu4B zq0^V9My0vD2g>ewy$_usJ*oci?0zhzD&1e|yEM)ma=F}Dopb7tPmlO~K4)hxZ4*Vo z%IDLKH#tK~;X!CIq=%uebihfl#O{y3v;qs}**B>_xjR2}Q9~g0Y4r0dg zc-=)}=%A9DeVz-dfmy09!*PvFy99-qWskj3TBg;_$eQF$`_@{MtE=#( z+)4aG5f>%4m`-AX9wlyEuL<|TG-2QKkE@;+w~fjbRJ&-1cxzaLsdNB4gt*@1zQ%Ah zkq`JM|H+K9ZT#DM;33ai54X^-$X|3zpdMF$35g~kKp~36T2JBTn!-BvO8Qf-F@_kh zQXjw}I9g7-wTVbWnE@BI1S+pF2wj8C$@&*k<`hm7X%(h77@KzgQ+s5skpPs?zl^ zmU|&Rjwf&413}+zjSP8m%Wmu0lyxhK|Ch~i z6luD2w&3SW6lFFt=|HyrAr|WJZWVhRlV%$jo>UB)X;hUrZde%J5>$Nb{|POa1~BmE zG%JBVcpG+IfC0}7$LX4V(L1f6fA5C1I!am&;&D6|N99y&>t&wY z@zK5=x24HbCt`x)|CsU6tk$TN=_h(Wf{3`NB$Iee=xTAKY(mmW6Mok9S1%);((1Z@ z%Ng!Y5OrfXs$+7rb6qIYeYWqZ>fPki*f7NlI2w26uJDs`Zi2dSF3bUA^swb@$rI0^ zdsy*1>+|1+S${oPX@p58pZ}H84$qP`XX<;RlQPJt^mq)4b65&9$ z-M+5SdEo=utgBJnf1=tMKJDa0#x;oRm?bqFfivvySP!#v!DPYh?jm=H&~&@{kC{x* z_ok0?yQ7jiKwjcoqkB?5#PYWc33*pL7J24s7Tj6hF^Yqm_^!4e1Kvl(gu>X%AKrq0 z#duOBNlPi$N@Mje-l+I)+(8@BH-cj0;@tSIHh|26pGz`2QX1o0=&$#kH{z9J)(ox>2J=96S&Ry zNgT3>OqWivfMB0Eu8cD`x}EXb+0V|^4;%TiPMmK~DVcanuk&7b(Cx)_$GR<03SQfk zWw96;em1!7Y~ayc)3mNBMDS~Hd-094`FIXTxh5l7f9{%gUfgAD{#;2!} zgyA9kne`&vD zmYzLS*QBFBU{d@+s6}@iKnnNB*EY43m-vQ2>}l`YNP~Lqb-@FV7a4}-|d$L~3* z4`@Kz)Xi%CdE}|4$Lp-eygrvbPe+ClkF{wD8jK@s;H;Y_M~a@>`+xz|b3m@;4_X_e zEliQ)Tlb+9pEc123qVCc2mwPm)WC^9Ig|TAzL68}lv#OE?+yH{utav@zqM_u@<$+Id8~-h{ zJ|^ny-jO7x?nzx_$OW*dwqY}ULgj4r(lU6pESXxlx6Rtht|TMg$B4_c<@&A9E_L34 zTU}R1c|E(63BA=K1P&2_)3$2GKYKp6f!F;6Ei{SIzra3gbx4`4jhg0$ZK$O~f9PBE zNjS5g*4}UPb*eq_GJe_0aDB!(GyJXuh+8ir##!$TiZ6#_)o?EUOEPcn*bmjYUGarf zbz72Wytd&Z0_{h$#xCDTH7_XWsR!_V%>Vn7?<>%3s*GN`Z2b*!vaW-OvK`n9Jy8)^ z8z-TVawTwwY-t;O;Qkez%jo}nm_v+-#V?&Cmup1sl(+^Nh)GjxQ8>1*%sTd&Jdr$u z-v*Nk>qut4Q9?=Cj0Rti&zAt-X4W-Gv)>7oN`UZd^KT;)1F&EsrN7r`wJ(3Us0f(t zttInq7)JADwF6T{%DXD{06sR?)xtQ)`z*lA9>GXLx;i^TF3FH}NxwWb4^41O$($F) zh>!Y*eQv=~qA8!NqGB_u_0wMhr&KaxCXBdtxP~&x-a<0_5fSWLFul{&etu=-YJjdi zwa6S8{dxKQ6?7&`Gtf0cgFKqI(8d7+yk>pB?wgXMn0puT6Y;p&4ZUo;qO zxzwh)eYt!k;2U^e*<||;g3(j=$V>QX#q)FrqPgXSTLJm1^@OjMwTWfp%%X$<12ywZ z8Q=YcnD<=NZ3uKfA-`}VN{pswr*082I3G4EmTweGWqmxi~e9~h28KeC|u`|EzW z8}B$ax4vgTQpsM(0&mrXq@L357InR7?#*hZQpEd7qJEYbodF@|FxFZP!VmadfH~rO zg9ksH|MO=4hw_$1jetD$q{=B|EWx!Hgi(nl^4&L-BvLX#gs$YlE>19Lruas&Ij3-7wWX~J%I1` zOXNXc&y7dcLp^7@#PJ#O1McwkGVW~utON6zpQB(}G+5jr$A1>fvobSrLtL98m?seM z3x8r2}c}L9BpmqDj2Q8kX%}M2gGzTLfsZ__T?)+IdW;RXh#1Ks@M33DZi?1g2 zm~&BhF?|Pv>z2R44RnR_=BkM;T^f)Cq#3u`tlN@Ld@K zNt2ljzf#A01Z>{`Do53@Z08mPi7%Mct8W$1skW>?#0K7C*+bj=&y94}#cro?cX{1N z`#&y#!Z5t^;>&4_BjEfpHB#rcv@zy;#qb(9lr3uTCEFOD6o|W}*>DwAbogmrBl_~9 zUeq^aTmU`fWNJZjvv$-CFu587(~+d;k1pah{%#xyq(QRpp7C;65@G%@uP|8GVfL8P7y22!CAgs|q=gzp||U z8!8xvX0+k8K=2_7c%FA;idsR&P;^t&jU|zL{N?$#?qM-t8~C*75FHm@?@ZPEUe=iy z+_U==r0Q5i5@29IJf!XSrJPXaRXSZ_^J5l#<8A$bHxLGgA~#797L8i!oBBM#7HF9U zEx%y#_L#mVq-g{Xj@xIwZ^EE+-1yC8GY|lFm7PIta5E;-Z>C$2PBhDpxF;F-1*R&h zEI*!4C9Lt2z$C7V{S;$wA5aB8&fl9kGHq2Jz5^b4SynCp>@Gs@^6cPZ?5X+=Ysfjf zyd&-(uSWWZzx8~&vwm_N!E zQ-7vqK`?5|x<4OaLPN4{oz&^IH)-{<5*9RKAks4X*_-`ci$5D0r@rsP;*)G1eCX)c zGATE98Y;GMu9z>Z#o8}8JJS3={Z>#gNuqTId|ZMi?sOAUhcQVyO<*Y*WW_JI$vg}n%f_)9U(9I#R;$F)C{{66BrSz}+Nxg8A z^##H0%8ObHdTIigQ5>6nG36Kai%D+ut4eyLz`f^>#tW}-d_E@5_9j->fPb3Vqp=Um zkbmZzCguL?4q6(XSU;ziUUT<7h|XH2?~;k!N|bqCx((w@T7!rwUy9b6{hQ2CDx95=w%DPz4j%_B0u8m+~ko_ zaMcZ9K7_H+Iw8nD6RdGNJCI$=fm7tj-)_{nuIQ6#W`${V;NdSC~y8 zJ)bgmLoj_)#>tZh^=$kdK)~*L_Sa{Jg+=vYqo_p=2!*z% zpH@R<94U^Ba{lbSURgP#P{OGCGWE*c|9vylJ%XiYiWkcD;^%ZU zA1KRlq+~t&&C^6JB^3GD5a2UUOn<_3yuFd@LreZ9`0vR%^a)D74gPR14z1B(%%|wJ zd_Luy3Ga#(tL*u6Mp4s;yQ<$PMc))Jp6J=nj$+K~Qzm5J`%}av{sL;1Mmcm z-#tv}V#){#y;+;|I`Hq5!0zs048e~s_px>M_0AX9t5@Nm-3GN_(reiAN8jD}D}~mH zWen;Lp_)4HaGZ7=s9G78;1#vAhspU>Xr*I6ouQ>{gp&|5QoI0JmV(s(RQ+FtFl7}{ z9O?Ob(o)p#44o!lOZW{>qGbe2Wb2r)-mR?KH97iz6Cn(zW>NUolVQmv5s&DW`hYa} zy-^+^f^m(QLHfKqcKU3C{j^i1JKgJ-a7e`BTeCVX-XpBr7Wfv8EN;?O5p)byI^aO6 zFrS6UCG485$v!pcR3UOJSSB6mDiM}u?^l3jxMifuZv47LdzXt}B_SC7^tl-!MMh9k zl5|?Hh|1$ypwyj9nk-+`x(8y>^nBtn4JOm1 z?N4mF*uhW&ea`++T?{#T(yPQ8PL^qw3WndNdcJ zFUdGo;mn82xv0q^gkP+c=)5tEHkzi%)9*pZ`M~uSp`LB*-SOKC5??OIcn=shEvO68 zm)h z3=j|f6yZBcBP59aRgh0Mi@IgW2c*mhsPKDohT@CWUdeU$fmZhQ_#T z*ExJ>uGXlN`zof^@4&~}MR4b1ImOyRiqeRQ>NzQbe)jwl@oWt62A;}k zwipJuFhWC%@sM(#Y%S(4>uWFm+W-0z@DNN7m?@gTRy0Aj;-U9@Hr<><9Sp`amP)!u zsH}s!EZm*yxo=Wg?u(+d9aDc5WszyL4GKgZD-g}*T&FvdZ#bpPbSBB+0YIS65nx@T_pyj zX)>hbEn4h}YT(Ltujg>0f)NT%>O_a|t{N47e(0dsk}VbKSEm6`f&f)zFh~d|^E{y#i6!2kcc}e1>5~3I89&3CsHST)r!KWqN{{ zjnUxuM_EX7{sLx6?baThM-c?TdU8Rg|3DQf*+PVP%zsxa{U^a`{6Ev>?D3?hw4Ky< zq1}@Ri|6Zw^3dYtg}K+G6_jZole(A{d6n4jKJABODk%D%|o}ME?G%@%URZsFA*>8e_8`axK$iZ*{82%TDbJiGsk3-SLY;T->aVl294GBfdXTWimow|uBrySn=o zI+HJyyysIE{qQ0~Nfw#rlOm%i0IWuKT?kf}vB)_dTeT%QYgIcQ+lwR3|$%9@DrX|Fk5>u@&)e zf((Z`eqmDKtNQWVcI7d_z1rRgO<%GG0t>l7mp1?XDM5tG5%ic+(>48!bp&fBGM|(m zQO7iC9~QqSyqSogC}qmG8W=vMES>ow`a;~ka1)M?6Wg!8s%4p4P{#_$69Y~qqk*F0%3goHHMy9#fs58#jA zOnMBU$^hbzd};j+v+6==b;IQ+2Nt0enKyFB(cj<3rZYq19WxBW0yoPh_Pgg$mrIAT z?)`CGQu)`JL*rz;@=KG`ycK`mwv0Sfyuo=%U=O-}#qq+V7GN*Dm|vU9dZlvwLCBcb zfPN89k>j|w#3=|9C=?Y04G(FCk5BEWdbNX_^^c#?)_0C65b1n|5^mZ@^CAv=4>K~O za-$H>UsLedW*$dPb6?!XNta@@+Q#1W<=!@#ZMU+#8Rn3#5Aif7s&^ZugpnRrBfw0g)v8U& zw97W|cN&J50dw#?xA(W&5=5%U0RNbQ`Ou8y7BaHc=J#(!jymwuF?^f$1q}HYUX)x_ z!%!@mwm_b*UKEBXv;%RtWbbgzCu;1eka4bEw+PEEe*4iH2Pan z;ZK<7{SN&1!NkAQ_G1rUD>{Wu zvwkS+&f=Vt&c$j9yvxsh*rx*%b*zSsPBOHwngXQl;)ZKvsYVa1VW-j z9fqxaCG-@R#U8FP{)9>GA}}&HTV2av%&cy5%eiKX9-nb<@vMXTr$$IA=>%%XKEq|E zHyD+6QDkX-Ka29Mf&yuDaOjtCuAC~_$`Jg)cH{d{+Sbv{LU!c z9ACBn*J~4rtu4GZ-#3jTbG?XjTA*@Rw+`=54Xf~b0N;#~Gw(}mp1&h3*lG2QVPAa_ zl!4yr@QkM_77BnGje3eQoJJVtDn1}~_o8?f<>esDtKo+%nCp_%*}n>f@o8RB zzJiuNU*+}VJHP5XmKXtWTBhF{s|EA<= z>g0)fzwD0V$h5avb^{{IONE)oZ?vy`{cs!h@Q#Y1;+%-&#Z>@z{8ofY%TDWg(Do{? zUASDNwg&BP-wEFZ0M9nU5^AgGwDsjtr^4bY+Rp8+BxXJS;9Bmu0rV?B7L0#TSbVy+ z3j#=5ot@=l<>ek4NQ5LT&ob8KdkaDw746ZJ?=pLg1lGB=Rt)$Q_$C zwOP<2X6?Hg#&D5=HIdc-Qq3C_AO9JSluCpF_$MvZ^H4)X{L!lq{8B=anUXl77|#9c zz#cK*r(LO3mhDQcUa$(>S+K!M!j0IfBYyng6X{ZHW51#d z7@+ncDqh^cN3`wV|B>3wHMitXSbfNNDhxw$G%#mo5yq40+F6N9O%;`Xz#eHVWMpB* zB!s0s@C;WETi*ASq7x<4{`F`&9L(8SVx?CXZ)LnD=f675x!T$r|Mh?h;n;^n?f7## zzv=Y8t2rAbwz1!gz>2hET&bgldyhQhjnJ;}ny}LSBXEYUXzCB5$8=7BsGCh6JN>7m zv?^xLUtu-;Icn<#TEBzq=Ubx`#x9v^PqQCWX{}<^21+60-4#-Lt9Mw*zh{g1-R}PI zDnQcy?N`#e|GoaD~0SYz!T8db9fjbl}^gxKVP1D{^&g%_gO+`FaPe`lVI%SOng z;|t+9Rcb7veKi`+WiuOygwdBUp&QJmqZg)&JFVFr#T^r6O8qLvfCbSFl*hh8-~)lT zI`_m+q$Cv{O*Ly_c$D-kf^|{nJ$D#g;wOZ_9?h?CV>Cnd-o~e!yYf0m{jX`wFltB5 zz`>i5^POw}qt~m4(rz{7&~&cr~^6)$w4c^er;ID!@A&Npal8lw{45yyI`d+c33JLR(&Ya@(~;Q^xnJBut9rB;#o;Z;#-$K{hZwP>J#y=92)YIe(*wW66309I31#ioX_5Czm=Ja|HaZ=2d#I|*F*N_a?^V>t z5athzE%YUoU{(K{x5C2h#QjGRbkUh-lr4esQ5!{ z=qDUdT%J6_S>N%3qgjiboGEZVz!_TlG7f04fgkDmKk?LmzO)3|fv zC0gkxM6RYzH>S-C;X2}|$8~mj=Bl#k+SHcsvC>9w_NDMEFjF5~$#ali{re?g^U2X9`ahlTAcD7Rl|0u`sA%snSlq!HIiY_X?ERX=Ig+j~cVH;$B%!=~ikaZlM27FU|IV{zdraCD-BAMv=AOZxZXx@z(QG2h2r8I1EjT)Hjyr z)xTEN2;$##rD-u;V4y3_Bc|O5^a415h8t1(etYC385%D*0!%@DoP20tsz(tNskIf& zK1jsq2~eSqwmwT;?-s0wLlA5E2bX`S`(O%E;3)lS_+bdG zh>Yf1V&!eIf3E>W1EZFN@6^eR^QnX9jq)&RmxS4clfn;2SXZYiJd6(RI{MW@KC!O^jqvpK!R^6SmBFdQ;Ija8MlV?)w9PJt%=1&ts zE$80i-er9#zYhVo_fAM0>Qqk5zN!=KN7(nj*?F}P@!-*D=Hi6^KGHm^AMp09>s-ey z3`$Ln!q~U$G1n7Qlo=+??bGuAM9eZ`md~No{-z~{sTAm*3BfdJF8{Spo+_k2K@$`5 z4`4SJZyZdn$eb2vETmi2St(* zqCbHH;e!lVk-_5_kVk%M>LxvSL?28*cf8Bs{Kd_6^kQ_9eZ%LxUaz_S{Pe4RmDrqR zB%+}&YHqdkvQzzgi6naJ*A*2o9DS>wrTk(tAn^AD9Wnq@YTy&6NuDWe;?jHu*gjL> zc)Z;BtQk7CbkOd1`pmKa5{EW+bO$mxGr!>FgwknEym1g8i&>)p#b_#q!)O2bpNd-W3p2=)dhyn{5!ATVP}0iOFzfP0R{xG#{~ZbmzxxF( ziQ?XZQ_Z>$j`!1hy4On{OS)|;3hbt;dGwZOT14V$Tr(66{6dc1i^puy&siv zqkN)G|E!g)Sz?(OA@OO>!ai8ESmeW*;8i)a`Ti{pG#o>`1>>sQOGjwUL!&Bh6~K7` zr?PL2H=~qmoQB_nJjjQi6>pfc@*bWl#{>XP(}}@cn2~K=Aq{<+CPcx}ufH6IohG^# z%YR0z9iBd)PGaU$q+qgy2DMduu{nxJ`uRy+si6SP<9vB}?th9THIzwk&~XK9KM;x< zQbPu(i9dm*Y7_q0!jYrO6)IJP(cCB+rc6GsrSln>oU@(WLoa>ZnjJ*!E}B}=Jmw0e zW7+VJH~Z2Qz~_`DEiqd(RX>d<+NBrNo$A@Jcb6EP>Y=`5T`h)e1{GV)w1e}7|EjZl zsK@uG*bS8@Jo}=iU!elSQYJ3Fxf7w&ArvbkA($3GSi|nb!zWL^f`oEG zn)|}G=M((+FLb&?V(fvF`zaY3$nb7MoVHSfq^n48Qe(K+;P=~W3xnLZ5)al(18N|= zs*FFv)1u;^!H@am5o2p^-)eX3Ebe=0L$YH*NuSe+$a628pdGXv2Md3^^5+vu zaerLyTvDee6G^~@4VX_D*ZT*tf3CvcfFk|*;c=y>*X-V{(R zG4bJdvAdn;?0M;Tb|pe0#Uk^p9$~#Z2`qaaae#a8FkFZBi2{Z5WW5Qd&zpRs-daWQ zzc}93W`x5*y@F8cyJXBU1;kQ-0LX69+K3xhdVL0-5WGh0wzXFc!T)6wS^ zS={b=2Yo(a;izkEmoWY|?zj|TsJ5%*2xOfh9rtb~`1e$Tc;`!kA6;iWT6vh-fjyMI0#78pq zrO5CN)^tSGLMHl~l^^CXY*zUOC&%PgjKm0gd(MKpVfKHZ&>b!pP#(RlN+^G5QCg7X znYZO?@u9~PphxA-D5%dP5&2hwPN1eZzGqEbV~PmjgY$1N{uq-c@MPmh3c{=4D%<^X zS*7)Cp}*7}ip8dbePdH`mDdB#*rHd0Qdq8FxuXxRa~7Y&E}WCb1_H23>D=9KaVTL4 zutMg{hw!8`6?duhTZ=f(;!9sTjbeh#{#oLP{A)TAI^#;V&^%k1q0j#%k>+MIbD}nb zM*PNH(yVMC&rOPK!oOSqz53U??CaQ%X41EygJSB<=NFwJ87JxkBZSmbY|Q%;^^vya zU#E?s&C>WLrxVlh$|DM!e}eXJ_}H0WU{Ed*T%W!Ic*CUM2dGLI?VTke89^LUGc9BY zZYF*y-!F+dxSafPY(HLc*^R5jjvz85(vOj?P%p7|Fkp{K}IetUTHP-hyF&R(}r$z|eKIDm^&kOKx((zj=zip?n;r}AD^gS=g zZ`H6_OmgPj&v#GuM(3GoVn_uX%ys0h;+3X;g%(QNsNZqOj?~99hsHD__=sX8sesU$ znrq0zWLxIfXxO(_{FBr5}@Z=RKFP=LPN=4!@`y5)4OP%=^5> zfThbc51DytIPf-!bUp`JH<|!Nkr|4`dqfY_!&}w6Kiho^_5j-&1o*?vB4;DpP_ozz z?MN!b?D$2RrMEV*q}LB0rTyI@fzUiOo^uT)82k$E&>eqI_KfY|Mn4w>9A z&VW04Q~(R1acv`xpwKf(@DQ>iQUzoM{lyP$Op64VMtx~xGDEP%g15sSnbCneJlqfG0|xKRBN zMOp$53j*VQtDVGB#A4P6b^z+iG6Qyb<7Sk?1hddxPcE*4z1*W(XUPBj7zBFI>N4ab z(Q@csAjvYu1^@PQ=DoxlG8_L8Y0?|OHNN8uDTzO?-Rm=h&^uAR`a!f#MQHeq(n|Z` z8orQXb$=mbpY8R9uRd$vn4;m2^HET?+W0DYFdP95pfD?dGJjs}(7+sJ0ylaXVnI0N zr!Wmwg?TDy$z8d!1ALRiStf+K%-=9v0*xo~7vCQ~!hs3vQ=h^pjg|mKRUy&!bN0wR zl+-T7TCvzeSm*dUF{(3_|?qlR}u_`YviD58FA+C#rPhRq7$@@N1}EAB<9L)w56)pj}RRP zL(}`LaIlJz5CT|Fdm4&^%3yQx;kMZT7eM|!=_oO!m2gJ!w@s598l& zH6IAJqDUsyT?yI8KvD%7oOpVGqgSa|-yzx=R~mUnbbH$>)5K7{74%w+}M`Tpw$oiW*R z;sUmhi-EC}fpvKPmMR0vXNOoFvYK6_{rd59HKoHpx=)HZjjKw7OO#1Ev#!F1TNZj! zG9+TenoYzJpbp3Vt*@%?sxaRGK8!DOBql3DXoPK%XAkx}h#W%Qk%OIpgRb_%Sl!5< zf8X`z-6O_jV3J=WC9n)EgnCwuH#~qvD#q*k`7ZSs01C_fbWHFFgeAB&AEJ*S|C(oS zSY&K(EG_KAEGuCP#(s9DXv#l6$2sntipH7Br*fD*LHSh}wLt&W1 zK$xH-1b!0c{tkD>k<2F8BBMV1R}C7Kl%v2BpDiw^>yF1|!}ryY&Y2c%DK+Tb_)z}ftA zf8_jQzbQ6bm5OGh+_zI;+F!}YI1W=aa1N~=QoXjg`?Q1;q+y&)7uwSszRn@#h4Im> zW4}N1dv9sMJrqhQ9S)FF!^iX`z+8+?pg#9EjC(aB6lLhiY_CCrvE?Q8qyI_1A2aFw zd?p-(|D>eGGHF&Y00*lUd_*>a))c~G_wnc6f6x*?(G33$y=ow#^*5;49zGRqhpXm~ zjCK;;{+6Ayog_F^d%Kqjg0uXylE|o&ZE6+ajrnL&Yad*+t=BVzwOG5k4y~xSpa`Ak z^bU#rsbFlMtV1mr^)aM*>LT0~WYVX9n1{DAqYASV-l?mn(&B+zfHwXJzIfX_q`@3% zJrstZ>iW|k>p$KxB1he&^x-kkNVEr0ho(2?E28#L^gXb}IgSJ7@BKGWeK(%U+kuWq{kS(`&g1O~4a_z=SEdvAl z$2-!?nhsphOY(nWaM$cZlC}gj#tWVZMU*tJCsh(u&@nIl*3Zq`NDC@d*wQQ79lw8i zp|1wfA{5*5@H3jh`1o3GebotJ=*V0%Tr22wP zZzyG(%$6s4OC>ygQtfdFOce^eff0bV(a;*0q*bNO*|@)LHwb*igL2rT4+zMwT^;LV z=GA;D(Jm?Z{DWu9js80c4J9#Rx3{1R>jgB)WX|s-W;}yFzFM$ClLx0=PRU-IN;wf1 zE%{L305}&5twB2gWQ`$=t&32Kev|pgWi)s7P!MzQzh5i8Rj$GYul>o8P5qPtqD?^+ zWY~MFj0eBu!>o$atQMRCc2Y%m7R&u{tQ6$wkt;06M(j$LuA4@R_r75P`Ap9F&aAwbWQ!xm~qy#%{8h4hLBn0D8BK#6o)?3na+YZMVJ zt|VXHQltWgd=Pc1sd-juY&9W5}zR4Us31+tG4^4*i{R zH?FR08e07|c?y3fF_eKux{w8SlWK%*&V!h_L8t7U^Cv@OrL9Y9=L@OM%3m8m8sGuq z5^OydpvXF}LOKIcvOB<KhlJ0N^=wxooFdG zUFm!1KvF^eQ!JUG`UQzR*P0eFl}f>LVjt)=-F+*=N( zz1>2v%Mgrl4Wa|0qCajdjlMf$oc`Y#u^>&6Fo?hig!~siS|`fB;Y&=iFp(3baWOI~ z#)O`m!gVV;14it8@Bj=1Mr#=wOEBK4i0+~iklsZzN|7WO9WSNLC~=k3Wi~(dvkbhw zNZ=?g|6VF_9DyxN+!ppKBIok~~ci&!*n8lvs%a*IJ*{ z)VR|TL^33$Q6nr8EJy$TI12^E(+gu{sQhMYv_B$BYtUuh(L9%6vIl+k{4O5 zU0kPQPk4vyx&(|27igXjxY|l0Vsm=pMRCjiqb3WbjhWxcr<|whL2HzxhwVn^qslIhvT7%bh!kSa|T1fGt`$rNm>-bVH<8PfP zts>$K0^P?5AVJZ5{*|K|@`yJSM^QX(8C?S~!H4W5GYK+%IWhSi+Cg~CS*FPO%Fnm> zMgl*ZUF_Lt=B5wizF&h{`pWogHD_66+$b_*zIs~BoRVLi##!(Ip1!`X^ryE`8*fmO*t&ClWE#*Jzr37{m1209j}-LdgJ++!g4cg zrY^kdR%vDZ{A7*aI>c#e{SLl#3U7Vbg=gPi{|;#Tk=U*un`3qtV|N(b@u<*1EKw$V zDs^W~Kb@tYImVejSvba6+TUArQ( z9ZqLl7P~>wjSO=e>lB`(FER-Y_ole><#_AD9Y3;?s|NPx>7?&jErILyy!Z41cx4G{ z9tExUG$Bb`kOc2jc@3#e>J{S7=P^pIQ$e&s?L;X=1X-VU_S>pk zJ}h?JQtet(?plMc1QM1}Bct`XiR67x?L8&8@Np~i=;@*3IJl^bUY!qqj&b0lNpk`T zLwW|adPVwsv(Zu~M8|R`&aPi)_ox@*`tbB~#6{g+KVgdtefl>E65^AdKtD*q^yuj5 zQt-$`W}KpOmiG$+$9lJM_voU>!OZ`DPhkgCefBoscpz%n=-1Qia$+rzrhc9&1h%e!Lu}nLtoW z-L2jb9cz55^SCc~Ci^Mk!J_!aD8BGBE^o+$UUug;*#+4~;44VVt-j0fnP;cF_bo}M zVP0F0ZUt2-x%-*q)^lsT(CzH$`qbbyaEXJ*ObIBuE=`}TYx3-^7b`ycRbw*DCXutt z;(g!bqxzW#oF&g>XvcHi*z3Lw6dNo_7979U5I`W?&(G$z$-gczKS@bi_c>+4hx3~j zdVco%quFbppW>qfkD%~b_MdTniBt7eL;SY>ZM1*Bl}J_8WoG0>&}ud)T-!&t zuGo;E@F@&$K4!_k;K>IzfMRU33@{STv!QU z0gZYL4IREh@QJ6!4I>u=vSbxgl-fg&pkCqm9Tn_ZJ^s#I6_+$$8HZI=T}XkI?_)S8 z(HV0YI4l1MY0)|pV8G1fS2+yFc z=Udes;>)eyRCCeF$xM$3Os)zU&b}*?#rD9iVq)+NvDbBUtgaX9YtNLsUB+!Qcv&sq ziD#>=t!)Wd!k2M<+o&U``=@}cvVXI8du6!%ox6ue^767H-BWho>|kLFL9IeR*1=1_ z@GHxm(+SM2*qIRgNFH|e4)QYec>4PK9Y4RctGKz9+gMw-{;<9!j~+%f2Bln&AN*y? zMc+O&Wj=YKf+5J2T#Y*kRe_|rxw%acM=xe|>T@pvLxu+i;^Z5>@CNkB5~e81ErhUl ziqpY49Bwn|ahypE7xAMf#K?lwaEPq>f_s{F##cI^E^7^RUaIWMmWpFZp@JNg4X6qv z@#z~JOvO2RY=|k!{?CsDV$yK&`=;Cl^9fP-Gpx@%SBzJIi#T#*3C28>H`ANIjAFX9 zf@)JT&2~naG zP@>30NmQEYE6>2h(OCd6gc1#1@6$;5y$}JMRLS7xhe$-YkVXB%C(U;Whvf_thyfNX zghBE(2chQ(wT#XC9*TGU$@;=zSKq)uN;M1t zxq{Djx>u}%%b;rLuGUJ;SBBNiri1YfEc^X?D2Nk9I}P1GUYP|Vn*iXn#rJOY;)8Zz z$8ZH$`~f|(1YGjVb&vUQ%zH#KE&S6&Jxh!hwNI@Kg8&Chj^C!%J zH0LJawLLNn_AK7W$jHNe0Re%el$4YQ_RJB|XbzBFmGc914zoV89w*qSad7KV(B@T7 z)D4X1i>dEjV33JW+%%{04}wvH+{*5F(}Nx*Zb9hONibrLAOdr6XxH-vf-ph)If5x0 zATztT(Bg%c`u@jY(|)B2MbF2NH~B?4Fq+&c##HP)z53R0-!%^sf$!2vMg0CgoFwW5 zX+9->tSKo5ofgOkpC4`XuiF~#x@`#rT%pwW>i4DBKYNZJ!uVsH6&8{-mie&Q1;F=?8xbk%Z736-d=?1t%>3UpZZ^wksR z({6-GlpP*&eCbQLFu4<22XCaLroP|SZA^?wNmO_#ti~)JaKGea-W6;xZv6Wn$yOP> zP22sY4;w409Y!trMQo9rZqtBpsj}3c3l`B`na7TgjZT>VM4U1}WIirK7{eY4So;s(@1L0d0(a3L)!=ZWum=(DV4dcZAeOZH`nxuxX z@ZMd4^}>Fzi_lAo%bhGvhC#=m+Gc(MXgw;+l#+;5jvPVe%+%?w!>-t9E;Vg+I$3g6 z$WAZ`(Bk06p2M!-{G?}DD(sz*#{YH9_U@$<7Kkk3#ot#aROZYK^J#D$?=#zgazQFG zCd|^+5BPx(eFiFYD}A~JD%5dCpj%k^v4p=XR|aUyAF+}Jsnj0&a-AffA!$4})5_cDkRcX!!ySsj_%aqYQbJ6NaB!3m}4%-q~_iMCq1jRemC9JO=2iCnazzw(L9 z8*BUc<5?+ImKt9c`lH&QTc6-1UKJBG=J_Bsuvn z7zhn%s1AMq+}sIR+cjXf_U~YhO2b=PX6mF^n3?i+dqeqrhoP6T;9_AMpTX0nvUc}u&1cmbA zC#w2$;sJL}tW&7(Bi@Xve&7zY<Qd1^)HW>moOwa<6~3N@k}IUk{YPQKVT zSC(l$xgKb7zjK0$L$5VVDR=%a7XTmqiSouPyXE7!uL*I9``jNuYh0M5CMrscdt|J} z%^~aVno9EV{-c@3r+kvgz1-G%%-74$nW^fhD!a!q24rA8p8a7a!6fdGgifEjn_ zG;M27H!2uaLMMVqwm*~}Zk5~ibF7X|?hk;e9l4EXjkN#5s9vQG1UyQ04=D;q>~ypt z4pGsddw5HWoM^>ka96>EU>kg}se*P1>AqPV&i1cx1^QGSFY;%LD&nLBm&0hpnZ52a zPtPrCm!P)CQ~9l~*)k-}zU@pE=3eVT5!5%Xrmqa4Rk+EHojiR5IumH=+|PJ@3QD-@ z)-OP!@+!+`1MDfo=mPjk3apKFiN=y08=+n1qlNS<4M;#bb>aonzSt&3R~o-|B%D=l zF2}bU;{~6njf|l_G|$_oPExb_wd)<@K#XFDcv;G1tMYhb`G{556if>9rPy`p{`QB+9R;0 zF78?@UkV*qbnfDS6$xQ_CE8~4DRyal@|7cD;!HJ8%B-60H|Bqlcp&Bn1knW6OMK=& z;eBaY(w2*yH$2!2J8%U~YP^aYJ*S#s59vTzmGo-oK#7sv*GzV_=uEUs2Nby+-P3{v z_LOl_d=>#Kypl>G+u(p)cA(6!}LU86|9sAOL zFdiX+`>_X7FNZvS#b51n2&dv|d(oJw@eN!=QrGQ`a)bt7hLbpOxeo5pSq$!PlP&yQ zqc5XkvrdU+S7}03z@XkCZ@d3-P&udYDe~u38fV|)rk~QRosD1apgo&=+^m}2r4`zd z6m^(B7(PeA+$X`MrKKwW;Q`^@-pBjq5_@y1sfc&a?U#g@vlC{a-GCl-i5(|!rfoWn zJ(jM0wAPB`S$G3_gvF*#bhJo76EBO&ju2p#RqFWW8~RsGE{Zp4+_B52Fi;Izn-J*y z@p0-CZq*onKx%=vv8Nr))8V!r0 z^Ve3#D(1ZKy!9yzg2vxTZ19erdKWzS#qYSfC*o%=p&Vb_t`g~gTYzUJg%v|m9=x+Y zzNHLj%cwW%Tj!D)-v89iXu|)ZYlmk(FW#H`Mv!s;dsrvbp&a5uUZ9mEHKTLziYW8h z@qJ--bSE-J)C3Kwx41dMn>G3OvJ_)B_phmss zOC2X^*^HG@UG3JG%R64iVnav#`TKvOWlB~IHsReDWyTE!Cw+z_dRoPoqLLcoCMjmQ z3}buEBqf+m@Z(+TVEwG1oZeMnj%c|-h{iW~AztkGVc3kMrXLAN^S^v9+QI;i zUCr8^nsA&YER@PwPft70rx^*hQysKc`w`>ZH(hiy3JzQVN6*@VSoZG{A8^B)gw=T7 zrVTgvit|1*6R*CZ7OaV|$b^L7x;$v2^j1= z1}Fs0z~zqc7zAg)!97c=MqUK8CK@i*X3(gb6NsNNle8PSkUCJ8naNb$!|CVbbe4?O z8>+&X@aplQ8@-;jHHkqo7WC4FUn)@I^=og4L z%Mu`q-_jXAS~)OqT~kx@lwrC!8QU|&?n|)~{}D1$w&xfurudD=!!L6U;wa0F1!{i0p3ti;M3SAu{iP!i-G9>znu#axb|krLfmet13$U zJy%68xbEpE!3#`8jV}|9$Wtstk9c36@cg#epjtEV2Ta^Sgnj3flWtI5&?POSAeO=M zpdewg-1_u&kw!_5uSC3x}0Y_>DiYJOqCOi!NU zF2)eCAzZf_APUURjDjim_w7U<7;~d4v*O%d8zZkI{`-|Ux`&6~?^e7prk|&@Lm;hz zO75Fqym&4$N#rdvz1(Y63HqD*Y9+vlwl2KCWn-wL|y6#oPx8Gcv62R`6TPjw&uo8>9R z1LRxLd4c5j5!?^vJkRQphcQQsA;3k`jdIJ*vZfmXsKSz-MvM`;zEM)#v>0GRbuxbePjaLibZ_y(U zZuJGMmxVs;%31ip3C_ER@;JlJq{@sx2X9^JG{NHT%MYU9(o56a|Zb-3w z#r``JB=7`HsyL@cc;em77<@!cp2U3rALrtZoXgDr)wv)Fo1NXPrLCPjKR+L*JW?GTaqc-04MO8pdYZu^*@h_&5bI(9m^)Gg+t*+YFA(^6 zOP1Jt8u0rbC`}9x+aTa15S+~>zK04Yow|1E6+HygZ;NFgcFAF>ro(0WK{kVM3Bjxd zb4#dn86buU=l+KZxN4_fRhJzPFr!UHTcW0@+iTf7>1$8ouJJ+Dix-IoM1YC0q#pqH z17SWr00M)OC2%d|q&}G(Z0oE-INN-ZPN)MZ?gh2qYmdaWb*UlmJBmo+OHK^7WiJrp z1tR7E4LX*~V>P*|k0mU3HkLkjY2B1>5m)mCh`SRBy;mWo;@kKMyxvnb zTG2zGz=QDdV3Om$>46xGKbr*(O>0470Y#z%*tguAoVUPxY4)38X8chcynKZyVD~k3 z;|+$}zi!g`vA?K=!tB!X<}i}#%|$5X+aHuX9*1EJvoP0Vo-FAMFo9;Fqqu5%mU5`7 zvN9R&`S>~uT?hVAKHog00IS=1>g4HJ?G3=3=1zgmN`L9?N~gW-p&$$wfp*(JSyns` z3wTsw`$NJl4JC+2*xA`>`K9fVc(;JLnha{Xo=dOnjo-4{V}5|Ls&EXPQbW%J9p>dp zK>d#8Odtb5_;rjt9(hAx&;boLRuo4h;F!gOOAu@n+S4cN0T!xq8;5ET&pJa<-V!o3 zb8E>d!0y)an2nIrg#De@6IGB`_v~&DHeGx_Rs-FXLpRf&e2rR7zc&6i68ZyqY>e_> z3`&{R^Z$N_Q5la5%*-sz$LD#xw`k?y4{hl7ZZJ$e#NNV%*x-e8=9z6T2z-#XsdvOq zeQD1TDoMUL)G3vs`Dxq^D6<{y^rmqzC%9s z=12-3p>eFAOQD<{|3=wuMRb!X6eK#uMG<4x}@bF24^d; zzR}VlQqp?q4fjz!DJ=09e52N&GcTnyN%4YXNOL7IR5Zh-g=Uu1Wb45ejB2&$+KTk7 zXJ)>$P_VkM_6pn5%ZWeo+$@YJlycF3#dk7%+*t!v`C@GRw?ZKDgD0ppi5Yw+>&(V;`<-Wswox*ZOn`rb&vP)C@`)9pj^<)!(|W>X#KQiw9Q~7NZ|h z92#rHUA>Wm&78@(Cxg8O)acQhQM3g42da~nAJS~%?pyEi67{>K&ffI@DmwYR!I9wS z7&Hka4r6j5Cn$R0lTn|{f(%w2@m8N3X03c2O2c87@2OcviYL3`-R0ZyGU#Y03`JQ| zlV9@uc!fII>Go=BgE1MNS;_7BtA6lB#{;&PwQ!Z+Vzj&iK`w=sjayKP()BE?@@h@| zTP<-5BO@ar!2o~%1_UHoq_14-TsLf6Yi8VcZmm04+l=3rRi0yxxWSNb)cJJET(c}3$~1dBM8aC8#4A07 z5JZ+sh5L+9ap{};CK_*)B@W-bV^HlVD7p1s)m}9N#hcTi(-p^ev2asy6qsE%x&Zat zeZ6m_cUq9;Ik=8}aq+#q1TKSzWmL7e=!VK^U{RDWNm;%w8>Y zY+j{D3344Nej1s=FL-Nl2qV0fC$Y{>XKmA4Yesu6AESg5-KMdj;6U&)5<0e!xf9t; zcNC3EJ06ZuJmdVd1*vPs<*%@Ce>Z?}Mw+@FOHTR$O|QC{Bmiu{khdGbHe^td$-$B< z8YBe!eW|$<7uJ8SR~0ZQ=B-rE)jN5&8!S3bU^;!%P?zz-QdV<4dVLJsu8BvRZ1*HC zW{u9jeK-oPt(sFBN<*L+EH8rx$ByHNP{V{n8|pAjr-hQewY37C?(I&O^#MN~qVUDR z(#hLlV=zHwR)%pqny8Q>nq5tkWB}OKNh7K_{XoJrJ1DuK+@N_e@Z)09_s)r z8->EYa6e~e`f*RlqPNmH*4>0luQf9W?(#aq0Lrlv{Pn|tJ324}Mt=bD9ve42XTFhIrXr>dhZE}Z$-#uN>+4|YjjKu&jt!I1uUEw)!NUu zYWPy{aJ2S0e|+JPGM$&9IG`Rr`Y2Q4Prx0Bxdf4&v*UAxb5n&SPtHKPQ2d&c7P?$5GP1r|~h6E8+)hbdMp=`ENwhjcuTA`uz z95=da9p?LcNZZiRWS{Kwl0vLd=URgc!O6V(@k!sdqh?exD%rDP!AOX-ch;vCSgIOyJT?z& zdcN5)u1D9Xi0jVhXhuI-ZyD>x5M}qJJzG$REz%vf+$ z@81^B;oXFJ!a_GwnwM8z(Q-C6@1=P>r7?c-&OIYLz{(Z`{N9M3e*$ve!) zXqu9z%e>0=IT-75Y*@c8`d&BHXSbr%XFFa?wwZ3-lXX|E_JG9i)6pvGPAAQ*Q^k0B zOmP?WS|NtCUT)YlHYhQWep#Bf_84gknFWL?GhIms0IG%0F)ONADiPlE{~(@0K@ zne5GX2kA=D8o!pt?^C?jRd5J(APxl|7lmg_+mmY?0_gyLp<2e3T8v7#l-=#q2C6vg zSoZMj*$)Ns*EXYOlWfMzCI&7v^Lc_8j&)u_At#OY!BI)>c6-8i9x{anVXOQLh(mIV zjE~L)+S0B4Q=|0dL;YsYPIGvu^+yPe z!>XqhAfXkcjwa1t3MePd|IvQx|C9q8Vj&I}(=;(5ISE`BG?LK_J#R*ue@?>9bx#ed zFNS4t`occ9H8y@3xQwcFtuyUIpm&8(jDbPwaE)7DGIWf)2H- zLtb24O3$n9wNkjY7XDlLVvv&_f)3p>NEoLgg{2~oY(7i&mj(hgRm=WD?U=MX(tiaT z2loL23G|HM+5RqhvzxQihhlExdby~bmj4fJnnG}apNf!D|37Es%eT}1FEVl{#azC8 zSs4_!prquYai{6+b8x4)2{uGKYKQkGb=oWfJ6N3Mahp|6T~|laYQ1yR5wzr#e#qH}&bB8D+sK)N@1w5OlqA z`qibXP4}~$Eqh6=?bosq{BQ`=B?5-8Hfd?`gd)5Xgr)FQuiU;LI=jy_pNr2`6g!>R zl3xCED$w^3c*FYPBDmeg;;`BE5{C3OtmRQk4qk#Ni{z)(d#e6AxzpmR))DJ7C2;9dDB~(?q&xDKI zkXCNd4s%OLZ_)o3p{pZDtL*~U?9u{Vi0%)lS6Nw^TUVEgDdtIw|M%H=L*%op&Os@} zR?Ef;vc#N8fvHa$Oy3glL-{=Tk&@J3gMI{+1Gb^Pd0d?SRQ{Ks)=Y0g=z%|!(F7T6 zg7A5~-+~33{G1d4iTPe&iYqH0Da(0Za<#sVnwT&`RqkF80cHXqkIzs($wU497H|i( z(NHiuQ4lV&JL&1^LgG!crkxq$qBtzCQd^zNKV4s>Ne}camI0+o`=eBzIKp8*AG5BQ zlXRs=F_R+z0GCm1Uq`y=ARq4=r-Qn?%DyKKmhN9&eHTGzg=D#QnKdBt4Xr!u1;cMA)}iYmSNtapM%bT{3SaHIVy*w61bQ z{f4$l*`5Rv_Wc1B3H1alnACnCHE<;@9;kMg!)@IUj=#?da&U041SaAJY4DKY%uux& zYQonUMt)cV_24c?itBF!*lK{8)b!n00N$fD&@wa22Fc=(eIEZ0fkdmBg5?q8ehKA#2cc}ZR+*0IuDJ|02?gY$ zXHFcIF$zzTe*TZF_&OZDs>xt>=F=pAWjo6Sh~)vX_8iKNH2vk^EV}Uzp_sY|^?|RH z`fzilQDY!Ogcy^Em{rjIQ|D8FN9k*5WR$K~X{-Ig!WjYd4wWnrBL+5|z}W~c%CHBB z+6pc=wgqj_3nXVp1x?`9ha0ZO2G-#rvT!KlVnCKk;gf`qCax!!83wG7AA4%1?cK!U zVjoj2TwGY#WtEzwzmU82G88u1-|69(>Uq7ZblNshz+Hs*PM|*L5zUClTpjw{( z5*}sn->xfzz@SWY8U!`u8lg}#9GjYwqHJbn7Stu}0s=@ZdA;sLPptd84RDhWpTnXJ zG84>M`sF0WQyT|Chm`Uv>yKv>gzvqq?Fk1&A-4uv6E!*)d-I}}t}^SX=iu8QG z8}`e|uJ!qSh$mKf7FcGwu=6kmeWLM%wU0FtTaiQ}P`S7?a0^KMvsf7OGo$B?7Ut&_ zd0SVZ4Tm2(Xl^Q)$2vtGIQdo`QIR>b?kjBBaXS9D$g*+b_*WCbEVzN>wOtF3xqN$N z#K}8ViQInwv(C0mOZBR+@6K&J8{*WSEfT<0`}+Go+Ql-u4bvA_KcuBC+L5-)_Vxuz z1bej33TN_}_Ssks^+SD#f}p`o6dnB-b1jIrsO@XmQsltVT9gp$ediPM^{kxEnj{ZG zug*u6?f!UXe0oPCA#0(;9=ko&Ggc0xST^z_ODYFA%`cjSnK9{Jc zh4K9td9)b-q44^I%F~A*2`#7-m8ho zC^KAU*|>7(g^_Y zi_rbnt&|vM`H?dQ1_pp6M;u5kf;(eJgtJbUsmXjyw{Vq z`A1{g`xqt!+(@^F`?ojJaBc2B$-D5s*H{jP9wM>-^=H3JNB%?0+F6{V0vPnQ9X=kAXPxNWa2G>o_vHTGz$IMFZ4YysK?b!8F9-9 zXDITEb)Ub6Lf1*?=J>sz@OnP5km+MmXh}r&Mjaa9^2_Uwy1G)49N_SGf@C4-W}V{e zZN)#77vB$QB0?BDd;5paI4EGA%bx|Pu|sk9kt?f>d;wC!gezE+eoVg`-R6}q)=Ip; z`cGQFoJV50-tlpVgbR8aw;$!T;K%F25llNM+%F}~lmGqD-%oynEDA{+pp5sNhvn4O zu|26jVd(Fd!{Q?0$NZDeQS(*jrp->2kmmg_qxR+mWL4yO(*NsAM}o+KH}Z(|vF86i z(qvHo7u^5t48g_jfdR{bQWK{{&q7GaytXLrVRC?jpuJ6*>;L!MFeh+r?d%*PkK);a zBD3b>|@mvp+xege0-d^_><{JFnaI^-_%H?{%&-vHa*JCoGUX$g^2E7a#f#zcs zUtdwDD;z&AVpabAHV$;e4CJXYmfu>^50#+mPRNR7CcUIq2VJk70G}%#?C*7gD916& zD*Zh!99&nbZ;Oi+?|3A+tS%E{ULpi0gqSeEE-q`_C%@9)q5IXkiw@QID(al6@$ zWXQ~D%nqLYr!$8}OBQ)(`0QHzVg3EDW`K@Dc-$iXUmTA7%^PJ1lq{)3=KqCl#1#0I6JO+yL8q?9|fgQNk{vM&j{aXjD zw+ZtNqmq}wYbH0}`5s#Cf0h!l{*S*$)}K_565Rd!a(~X90PvyfUYd&kWRv4Mrq?81 zZ5au+Kx!yQuhE8L3h>UJ=&OiqDKV-;1V?FH;sbO${dv9`I;g)$CsnW9a<~U#MYAfW zNn>m*`!O8c9^`Ae*V1iAMn^k=uisJcz1q6l?Eg3V#McT8^lj0M7J{%4a26As;;a++ zZ#2=dn9iJKow(z~^w!Y(M%^`_$@zD8js(3#K}I?Y<6@sRGZYmS9c6qM3Cpj;umq(P zX7M7J9lBY=bzPLhfoA>s_chN5dffKR|6;w4~+0WzFgSN#RW+qh&PRIiTqt$ASMJQdTWsfNUwZ=oNZhHxP^uAes^jX+4oaySFyPy!C*`B z=7pd}Qx45A4?UK?eS3CbtgUTPH{`Jhu!lxK*8t{B-j7}|`nQkm(*IRBHqIb)m&k-w zE&`1R+6@e$l@BB>+Tt0O)+HX#)!6-*dMhUXsNYD+f>Q+xi}UG0lt7ZF!h*1`0$Vlu zZt3gZ4pO?0jA8)Cu>|*`+4ixOo4=1`7*r{+fcEK(?ahIKfrpH8z}Vs!g-N%S8Et`2 z1S+?`BTYo=ddZ;#%5b0Dw>#R5(LPH3-QC^U#;L+iRm1UG0jy@gj8|_FYU}D(5|2%8 z>p5OBpQG|s%QR7WJw?RLvQ25dt-`COO@lk%&dkltt)AO?)A@VP=@5N!-c-+ZS+C_DPt=Vr>ysNd8E(^%J~P;2 z-_YXPf4kvP&gD94s)h!?=qoxpi4NJbp_X(dvHL%n;}YA)3Lmd0Gzhka#~HTI7cZAw zXiDVykX2olR%D`A5^6F{XNZhIzZd@Zco~5`BBaLYSCm=_5%vCyBysNba~CO;m{tut!0G+ zh7`$w+bvx?=t-OHYu%gCJGZqku{Ox1iZOallcN(>M}|vvpP!xnTDs{iJ(-!@SlvKF z>2Xc`>yv{*uRiz@Y|$KPv5y zHs8i}OWZtK`RdN`QDfoFmnrPY_h-9m&~iKM=r#&1Tz1ZejO1Vm|7XNBd@TL${sqPQ zm4)x#4va}`e)(w70Cx+#>3cp*UiBpL(VUE)$@2C~PlIkBi=99c%~Iu!Ipbl}@)~y* zdc7?#LTZ6>CL_9LP|4&w;0;SIs<<^e%>$gH?U7(@`eZOdJ8M1`zQdonIKLgeA~MKn zK-b$4T)}IgH`g?}6;JuZ_$K4YaCPpLuZ6*Z%5GVACWIQc7l9u={w|@2S7RvRt z*j~opZZJ~VL0jYua(-)f#0y)lk#8Yzzj{og&&u&yDCPr-m85Ui_NlOS3H3W7|FwPb z-XGi8TjIRi8tnt+*y^D9M?DhB!2*wpSL^1L{`*k>GTf>RpL5lYqPDF?8 zYmAz(>5{zPCff(q^3Oi43|C~ny&!d|eF|IULg6p0u4?NwUQa#$S9BY2_ko0o$GLCT zPyXILCswhf|JVt!iVFMUO{{WNfh&JHCInX zvHaC3*}wf&*T1dc9Cqh)|GiU}4mU|h-M;PY z@T+@@Pm<&5B7Tu7hST4snO|?8e6Q_2OYOqPuUsSl*D{JdIk;iM^^F3ltUJT^@^9O_ z_2OOYy;r?cU(UHzCGGUA&i+r`_Q#(yU3|d>eiv{RZ9L+-# z0uJ+R1U9X@RL@qT)QgP`z!oFpLeQi=lDGzFIpM}7mcZT22vZdV0)VXw1(DsT4U?mw mKI=4-=itd2c#D>a>yQ5V+|#RH8(!*S00K`}KbLh*2~7ZgO*2CP literal 0 HcmV?d00001 diff --git a/docs/figures/inactivevals_before.excalidraw b/docs/figures/inactivevals_before.excalidraw new file mode 100644 index 0000000000..ea1d06352a --- /dev/null +++ b/docs/figures/inactivevals_before.excalidraw @@ -0,0 +1,659 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "id": "nJJZVzll88P_dmpDsWkuC", + "type": "rectangle", + "x": 551, + "y": -843, + "width": 657, + "height": 655, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a0", + "roundness": { + "type": 3 + }, + "seed": 951962170, + "version": 63, + "versionNonce": 1865032870, + "isDeleted": false, + "boundElements": null, + "updated": 1717506390574, + "link": null, + "locked": false + }, + { + "id": "fVs1LhHvrrvCK3ZhJRtu5", + "type": "text", + "x": 575, + "y": -891, + "width": 249.3000030517578, + "height": 45, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a1", + "roundness": null, + "seed": 129610534, + "version": 46, + "versionNonce": 1276535974, + "isDeleted": false, + "boundElements": null, + "updated": 1717507131314, + "link": null, + "locked": false, + "text": "Provider Chain", + "fontSize": 36, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Provider Chain", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "_Dx7IQJkJzNifgDjIf2sI", + "type": "rectangle", + "x": 622, + "y": -764, + "width": 161, + "height": 281, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a2", + "roundness": { + "type": 3 + }, + "seed": 1049314490, + "version": 58, + "versionNonce": 250933030, + "isDeleted": false, + "boundElements": [ + { + "id": "SPm0CjdkwnTk8Wfol8gqy", + "type": "arrow" + }, + { + "id": "1QU4AFcgTvpCQQURDCxDZ", + "type": "arrow" + }, + { + "type": "text", + "id": "OyUuFa30MbHO4QszYQXEH" + } + ], + "updated": 1717506907807, + "link": null, + "locked": false + }, + { + "id": "OyUuFa30MbHO4QszYQXEH", + "type": "text", + "x": 667.3666648864746, + "y": -648.5, + "width": 70.26667022705078, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a2G", + "roundness": null, + "seed": 335756666, + "version": 18, + "versionNonce": 1919688890, + "isDeleted": false, + "boundElements": null, + "updated": 1717507131314, + "link": null, + "locked": false, + "text": "Staking\nModule", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "_Dx7IQJkJzNifgDjIf2sI", + "originalText": "Staking\nModule", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 133, + "versionNonce": 1967865830, + "index": "a4", + "isDeleted": false, + "id": "wJsk4gejRqDCjtFbAeg8G", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 966.5, + "y": -764.5, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 161, + "height": 281, + "seed": 409738746, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "A8ifOchQWi_H__sEvTMnW", + "type": "arrow" + } + ], + "updated": 1717507105162, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 349, + "versionNonce": 1873924346, + "index": "a5", + "isDeleted": false, + "id": "n5HV8y4tI6DZYWWA1Koq6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 620.5, + "y": -376.5, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 164, + "height": 120.00000000000003, + "seed": 1248958374, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "TKqZQfAcUP-6Q6EoH8fp0" + }, + { + "id": "SPm0CjdkwnTk8Wfol8gqy", + "type": "arrow" + } + ], + "updated": 1717506820805, + "link": null, + "locked": false + }, + { + "id": "TKqZQfAcUP-6Q6EoH8fp0", + "type": "text", + "x": 652.0166664123535, + "y": -329, + "width": 100.96666717529297, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a6", + "roundness": null, + "seed": 438334118, + "version": 22, + "versionNonce": 2019293562, + "isDeleted": false, + "boundElements": null, + "updated": 1717507131314, + "link": null, + "locked": false, + "text": "CometBFT", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "n5HV8y4tI6DZYWWA1Koq6", + "originalText": "CometBFT", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "SPm0CjdkwnTk8Wfol8gqy", + "type": "arrow", + "x": 697, + "y": -480, + "width": 0, + "height": 106, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a7", + "roundness": { + "type": 2 + }, + "seed": 906345786, + "version": 53, + "versionNonce": 648670650, + "isDeleted": false, + "boundElements": null, + "updated": 1717506825727, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 106 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "_Dx7IQJkJzNifgDjIf2sI", + "focus": 0.06832298136645963, + "gap": 3 + }, + "endBinding": { + "elementId": "n5HV8y4tI6DZYWWA1Koq6", + "focus": -0.06707317073170732, + "gap": 1 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "FPk9JragWk96YKRlFekY6", + "type": "rectangle", + "x": 995, + "y": -654, + "width": 108.00000000000003, + "height": 98, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a8", + "roundness": { + "type": 3 + }, + "seed": 580928678, + "version": 111, + "versionNonce": 1002770426, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "R6sc8M7CuGEvv7N7-fcTZ" + }, + { + "id": "1QU4AFcgTvpCQQURDCxDZ", + "type": "arrow" + } + ], + "updated": 1717506889152, + "link": null, + "locked": false + }, + { + "id": "R6sc8M7CuGEvv7N7-fcTZ", + "type": "text", + "x": 1003.8499984741211, + "y": -642.5, + "width": 90.30000305175781, + "height": 75, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "a9", + "roundness": null, + "seed": 758773690, + "version": 91, + "versionNonce": 1184232230, + "isDeleted": false, + "boundElements": null, + "updated": 1717507131314, + "link": null, + "locked": false, + "text": "Power \nShaping\n& Opt In", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "FPk9JragWk96YKRlFekY6", + "originalText": "Power Shaping\n& Opt In", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "1QU4AFcgTvpCQQURDCxDZ", + "type": "arrow", + "x": 781, + "y": -613, + "width": 212, + "height": 3, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aA", + "roundness": { + "type": 2 + }, + "seed": 75530874, + "version": 55, + "versionNonce": 700245990, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "teEeVARH2zRlZXGyzB2PV" + } + ], + "updated": 1717506903639, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 212, + -3 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "_Dx7IQJkJzNifgDjIf2sI", + "focus": 0.08197485638165014, + "gap": 1 + }, + "endBinding": { + "elementId": "FPk9JragWk96YKRlFekY6", + "focus": 0.23696682464454974, + "gap": 2 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "teEeVARH2zRlZXGyzB2PV", + "type": "text", + "x": 837.0583343505859, + "y": -639.5, + "width": 99.88333129882812, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aB", + "roundness": null, + "seed": 918244474, + "version": 27, + "versionNonce": 206748218, + "isDeleted": false, + "boundElements": null, + "updated": 1717507131314, + "link": null, + "locked": false, + "text": "Bonded\nValidators", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "1QU4AFcgTvpCQQURDCxDZ", + "originalText": "Bonded\nValidators", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "9Z_qOWKQyxwUvelhZMZx6", + "type": "text", + "x": 1011, + "y": -751, + "width": 78.66666412353516, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aE", + "roundness": null, + "seed": 91824166, + "version": 99, + "versionNonce": 207872422, + "isDeleted": false, + "boundElements": null, + "updated": 1717507131314, + "link": null, + "locked": false, + "text": "Provider\nModule", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Provider\nModule", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "A8ifOchQWi_H__sEvTMnW", + "type": "arrow", + "x": 1129, + "y": -622, + "width": 190, + "height": 0, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aF", + "roundness": { + "type": 2 + }, + "seed": 157350886, + "version": 83, + "versionNonce": 738572602, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "IWrcqs7yN7FdMaMGcNDj4" + } + ], + "updated": 1717507110279, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 190, + 0 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "wJsk4gejRqDCjtFbAeg8G", + "focus": 0.014234875444839857, + "gap": 1.5 + }, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "IWrcqs7yN7FdMaMGcNDj4", + "type": "text", + "x": 1190.216667175293, + "y": -647, + "width": 67.56666564941406, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aG", + "roundness": null, + "seed": 1111293542, + "version": 19, + "versionNonce": 1166078906, + "isDeleted": false, + "boundElements": null, + "updated": 1717507131314, + "link": null, + "locked": false, + "text": "Shaped\nValSet", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "A8ifOchQWi_H__sEvTMnW", + "originalText": "Shaped\nValSet", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "id": "zY_dSGPd9zunChgVkNDpR", + "type": "text", + "x": 1320.558334350586, + "y": -645, + "width": 84.88333129882812, + "height": 50, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "index": "aH", + "roundness": null, + "seed": 359543462, + "version": 96, + "versionNonce": 100973798, + "isDeleted": false, + "boundElements": null, + "updated": 1717507131314, + "link": null, + "locked": false, + "text": "sent to\nconsumer", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "sent to\nconsumer", + "autoResize": true, + "lineHeight": 1.25 + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/docs/figures/inactivevals_before.png b/docs/figures/inactivevals_before.png new file mode 100644 index 0000000000000000000000000000000000000000..ffbcd584b8d266305d54a6454921bbff818c9d5b GIT binary patch literal 65423 zcmb@u1yogQ_bx7ovbP8l0@AQa>F$=06r@|akw!rpX(XgO1d$GD5b5qN=`Lv{|L^vE z=ji$F|2M`R_ula_zQMu0*Lv6c&UofCpSgk*;orM;>lUiiQ?ci_Zr!%HbqjF> zau@u?G~od8)-BRoQeq;?uXJ}(kS`y${k)MhWJ(`;gk4IZTGHXaYZ{b3i4v?MTuKLH zu?T%w2g5WJ4{rB|RMOBqs)JaJPKM!Aj+@b^ON2?>ybiyq>2+yzs{;RXsdGzv-S7&* zg|D1#KVc?ifPa9WZQ|@kPC^PvO!(hFq-;oQQ3^e>dbuzdDdN9=UO=Dbnv({4LH_k4 z+zxq~Yh3U|nFs?N;a@)y3L}sH>rd$3p%@VgJ?a6uy#Km1{7xA;EdO;wQbas*(u~+r zG)1TXUZ$|9oZ)}1To{Q}LRgf+kSKHOUkik<*DtaCzn1LC)b4jn`;@px<|@zzyyg$Pbx&c3=o|f{)VGyiY~ws*&BeA~f0P%OD7;YC!^pOt;-b6R@3!AiRkPrO zlBj?+_xxXHtQjtx<2SwUdE>_R=EwKvOa-5ZrA-#TdXKN#c;CS>Yxrhv5b}(B5y_#4 zq3UTaN9hAc%RkQ5dz>=jafb7PH*#VCu`A7IF3!mpx9d!Ug$S%aM`}0@iEC9&;13?A zxO|)9zt}0y=G!f4L0b!^D>D0igOtt5WZ&+UU|> zs5P97YmF1R9IkY&?N-fmqA*scYuI;D_F+Ba*VpQ<7TBv^zBg{cA^FEfq$eP;QjV4= z5We}|q;e$uS%2*77TejZgIbEv0N$7LEjl)j%U4Gejn`vVjaR28U^8TAlht%zXY2TN zsHkeRp}+VLGu(J{^^(nEG`F+iwW8HVn%>R%#M+1V@~o01?v5rH*Q-pPEQDQy8BdTe z+%(@Dw6STasmT6bL$Exlk|^pVn`u8gQc*4?i@u5IWslzVa4*M%cE!WUI{p@aR5ru* z(8psJmq!C!U^|~>I$s`yd$M;BI>;umj_bNvx2zXNt@S1to*!=-roK7sQkQGT+#xYt zFcsZNaT?b+C2wV1X1CmIIQzy%|Ejw6TH#!av0Y>P@z_6mk*)$UlFvo>A`{2B7Q*y} z=A`Kz-=5iI<7qp=%gLZU_|6Akm49>H#_PX2?|SC({D+5_?5xYYyY=+z?ZT?WlL@`X zwaRb;uKxRYtRLh&(CUf#oUQtd*B&qLOqKT`AQKLngr_pScofj2+{H19Ya!NO;6#?0 zdcQPh7uc({%}|!)1BaihaY-as8Crc7i_p9tO3IcO?9;N@~ux@@GEVExyI&Je&9Q>~lL~tp6_R zaL|TZ_1FQNCEI$kgM5a@F!$*?nTM~4b;)!4ceCN1mxf2z7yC)%@3@=!uZ~BoUkyIc zdfDK_CjptwcoHx@V7J?LFR`Lku)dFLzFw!|oxrI&o7rG`fr{G6?-1hMjMbT}(30q# zlp?cJQ+qmXN#~4&Wjg!0pZ}7@oVu$&-zr|?Pc9=r7VoBo7&(FFp2E*0|M8rPajz|^i-t(Fg#gO2hlL8 z#l5Ye0mvfq+8jsq4B)X^Aaz%=}pA^=gdu zu~-466unN2M89QmgURI4>hQ1(leG@dvP1#JU;xUFT|1uXB*fi3NAGG&&7|26Y8`B} zM0|frZ!Z-dT*uMw?h{5O|3etxp$M zk#`Jc?1jH<%lRfw_{nhx=6$(nLG|c$|9+u{=-!-=Q&sJo-M}Y z&m0X1y+lW6)K`4co0GtewR1Z2k_kIV!N*!zG=0wfY;J9*e1KD(>&g#h`=EnlzTaR~ z&zE@yWHmSP;`y{gY4JR}KrCl$V$_E75EDI}C33^@$?0sYv|0i9icOtP;kH+U-h~TU0xjPZS zl1b6T>@GWmuJyUs>1dF;oiH<-(kPaP)%s%?3hrxm>}7zYm78K)=V!aDur9rsV47MQ3G+qZ^m$!Wy>!p*n+~&Lal`2}9Xqq^q&pri zWKTs+hr?!sPItYI+Mev|WUmFKpNLP`taA z6gH)yT>Zk!q_5f+5-p4H#zNKS%ek9%pPt{ND;h|>Kn{P)eKM-lw-`V|oNuK=@dwHp zj0LF~-z|Tsc0$~VVjQ)<=2=h*dirm%Vda?U{_fs^xCKf2s)Aw%scw53w3b_=pG+#oR4tV_ zWA)n~A;*=I+Knnos(coV!t0^G(lBrGItU0{Lf`(d2|jO*rTlij#RrAaOxOKHg)g<` z`RJsSCiN=rKLOo46SFf~;mIwsU<)~Q4Q?T;BTG+>!wglkm_199y6sdQ46RW0+qZGJzx-Sypd)nm?wB;ZUn|zQ^t{&~ zkmPGeF;ndH!b?U*E*E4#)7(~8%3G(W8L`(NrmRm(eS&(Gc z>16h5K({7sI!Eu>RKgHb=F zS$h3BGcRlctFwhN9<$!4v<=6ygODX`bvH_e@o~@+yN?6ucb(j;&u!w&uR=*?+aJu4 zSkc>j+Cgo#Sf!@_+*CeUJ$^@1!z97j>IESV>E*+U^>>z6S$HM(OQ+k<2U$CtwnC2< z5*(VGUr@?A2oVQ{*08Jl=ydM8OUFAR%Ppc) z1(wK@w`k2J+G0X3bDq~nBuC9COz{9}*37w2T|9Z^e2RGIJ=Q~j7&ViMFR!H3c_z0d zL>CrBaaBotRMFoKSB>jyh|Wg(h=yGm+uWeLop%yERFW;RtN0*0-Qg6dJB{_(OaE$n zI9sNUvrNcl_=A-7Im%gA`h^AaD-_Ye2R9_ME&&jfWuk&x7p1o3Z7R&>qPDy;I?-lD zr@A6>S`#jf7jyf)ff(epH~~)EUboR`bg)8$yK(7n+4d)qa2zj(3sss{{)7&#N-Cq) zl`@U`_;Aov{_JF?(aXY5%xyF*6Ul z<2dUP;zs1wS@I~dWTVDmYiX_6kw|qMm20-d5$YZ^b_DnJ_kAZpO!ga0^dBh%=M6#_ zrdJldEYPOWa_oyD72WVPX!M)>TH_COtg~hrQod4Q(xT8al3l+EvA~yA@&Emx4^u$! z)3hxM%~#djeBk-R_vh|QPc7P_S){7jt2YzeML`4<2tD{0k;$Dca~KC=&6<)QB+rP3 z9@_~VV=eAob-oUSoLbyr2=Q1zInAm$YVf(}Lnp0nyMuMIa#_7_U0ed?OT$Co9CQQYZVOFIAwfFO|Lhw&=t&$SZnX z^=Di&R^^-_h}trqhVE_mwx3VFTIADq3S!;dXLEdw2I@U$oA(|9J~p}4YrJ>$8RHn4 za5Ss9Sh?4hB?b#B2mUQhEp9bIv}FnYpF!zlHbTiaJY=USmLK-Z)=;<$@YT7RhdU$5cRjM~ zH$hfm)L5J>_g`>?9&{c+^SI*SkYdsGvgMtud2c?~A2X38T6bhAQLF3I99Gi@e%u?)eO9 zi@}@p-c2lNe%XhA)NlFdouLXXwPIfAac|;^*?C)BHZ%FJ_mS5FYXg`@mo(kc$*R@P z1H_SU$0KD4EpZ0sws!j~d_T)p3BJFnMgEE8qCap}a#Sp?y8@34eO5-&_Q5>jCUPt( zg`nFP$uXxq%hNYX_b?urLFV4_v(eL{5BW(wbL3{l6mn4!VkCyi> zpY&pMHVY-8=08{1Dd~WcDKnNCGdl`-lR(;+NThcpQ$BpzA*(wcmO&k77vez)pEt>r zU9#_5NwqIot6q^z072*-M}#N&mxNr0OA+;ZD6T`jG~N(ZKTGD)2lrWIR|eC+HtAqA zb=jfok8}C7?tC7R-|eQSwyc2O;+5HVv@*SDwVxa`By{Mt%}vF1a=4gh~uODOqq zX}0AbzJ1Z6o*${Ip1ONSbuhTciE$yU@zKJbh+}_A`2$~7f%Pv5bwLrVixMjq^Wqf^^cH>2fSGb55C{sbw$ ztVt2w7?knGNjVOFh>|itE{J%F(W<25F6V>xb+_9+YiOcG&eTtD9culH+X<8;WfMiE zlm0$S?WYoTyTl#oW2&n~(vyPxipfQZKsUYbR-d`!6KFHh$`7id)w~MQ; zL_OQ3)Q2J0O{F*#+97y`^f*6)<`Kp@3u-C)&z^+Vwj%mCgq&nK81N+XIOM>&nx1!? zMLKn{t>iZC*Fyw$)9IGKiMI3@_~E-Bc2UFY4eJqHB=Q&G3iv@?Y~#1%;zQ5fI+kXA zrT9!s?=ax59_9?}OiJP({&;IV0X@(#mVef*LfnWjf$X36%r7`p9p8hiq%gXzrYjl_0OM&-m} z_Y*ZYB}BYiE1JxL0?D=SmNv)ARENP{q~vE|d5ZLyt6u|xV}_V?52>oopEaC&DNw<( z7#Me5y@8IARYXY?hFlbH8?1k z?sgY34UU1-vs2w~Kbi{Rxh0|#Gc{V;T5=;LJ1ABWd26a}~~pz-Ytwom)zwpwhY;i?uD>UsRk ze!W{UQP4w-g9jr#$Kjoo?AbLBnR#ZeE9n*_7WAl{DAM6uvRCHZ4t2{I#>5xE=zN?b z=JXRVm`fQ^-Me-0BE>yFvGF73nWVP5FUs9xvJ03mvd+b78R^&RGaVXVNkR0@p`h{w zmWS%mK?Zoni>s-&Ef!DfFzO&rDgQ=Z0G)fkg0o?h#jQV8cJh~A-V_wR>ihHt`@I!C zCX&0bGSUDn|CG4;?iawban{22Lf{NrMKUGox~{dr?8&INS-2R@{mQT|)+NmLKytr@ zZn|QtIUZlt&m|WQKe(;6K&8Ap5je^`A<)X{b_Rhhb!Y3^`Up8e_U4~lF4jtYz2EQE zV)6dOkC`eEV)&Te)u7}WVxoNqTE94pvHTfBO}YQcliZ(fKhZ^YA`PG6iK3v`)d;ic zpEYrerQP9dJ`eLc2o)l#9 z^xj>1sO~mm+UI**6-vK930xo(aN6P+!)Msg7nIAk%heaBK5t7+?{R&xC=l7g{A1e? zFlcxI;hTA8dwW`PMFP=8+i6UtbWh@y+i4kwxIG|40%Ig`gZ^PS!7svefC9J7{#N9m z1^wKdV2kvGY~ij5^<-7Y_2W|_ST{tp6qIXYHB_{J@&v+2hjM`3p1=Ay9rEYZydV!F z0Edjgry}=XOmrs~SlFAhGz+HRwFcbg6@(EnE$-|nbNrd-Kygkwk3=zgIOm!72lj-g z0$~Ke`(u|VjZysTxzWAfU;!%M<>u4rZ%_I~;NPJj%~1U+uk!wPEcsRY|IZH~yyiCz zrwV158jKW+OWW~t3_ISf6;^#?1-$k|sc?|i_ zJ=L^S2~SH3*wu28izTXt!p5pE%Pt%h`^3_npn#DnENQ-%{cX~wZnt-#$+r(scDm;U z&(Z`)y1J!Zazm$@Eq4DHpj7`9KARhype&GiAUVQded>Xz?a zR92;r@*IG3PUZnrB`uW^P(%J#H*p z2DgVNK6j!-zeU>mLjiNf<)mSF%&VAuwb?Sj&JnXY@2G2GZ}kbZ3- zC}01?V79JHs-}#__W+wi^>NP$`ISR6l=`#bKy`+0$+}0DL>R3WQ+M7mL1q{rE4i4y z{K&kr9&9hM8>qHx%&;H8+!EKA4KK@8o2-6z#8WyTco99hU$dTS(i(`d`-&y?6K>D} zhsWiQLD!n=Mc!)p1Xjx9sy>IYFs62k$$ekb-D9hN8MXahQ$4pVssTBy23eXx zlwq$YYc|9TBxz2-;M0qwaagKuP+(=OJ+Fbjz42L@mLz`tVa_NzC__(m*0n7`A=-`R z<5c?#4ZCUecWMkLv|OcON;u0yxGZ+t*y9qOFgd+AI?E9`t_mE3xTVlyd+S+`i(MHU zvu+eR6qW$5&_tv5$8>u}{WnDAdGLln)dlLEZ55kE3i$>fu%|m$uBEjC?&rse+t{XW z;Q!*YKM^7|3`pj=BHb^{D>6t%lS>goU%E@fXTqD-)h5}fX>hv3#<-2MHHxc^S4DDT zwmUTaG>2IhkAk&SG4%1>m3JqwY{`P{iE4DKAZ~s zGsn#LwR;s4x{=0;#mp$gXGX(Ys#TxVczR;$-a$1d?{OQK-rIX*FQ)CJk!6qgR=a%!tc_#`g+}SDW-p9cY?{S{XG^y{Otl9DTDmiJ`?pj#xmwjv z7~B<4z~k43y{7<}br;xzlBrXWEmqtz-Fw zN@ri}2a2V&ZYz&J@M~FnByLJ#x^owo0mCAuUFi{Cc`MZa$ji4739CdyeM**j#GWFFrE`KjR$-^a z_(xjuzQH8*BFwnpIeK~d;{ekV9~%~d3DRJ+aNeWeA2Sn21WmP4#YU;ycke5tN2(Gc zSvcrGMkz*TySs7~vqT?=7s$w|260)?rdI{;ytfbc$kWd~wZLO~WSCE{yxg$f07 zc1yriRait-rK-CBL37I^L1?+0wv;d4{80S0W{4 z*ZWhn!V@*Ysr}RaE>{tB`CAL{>yJ(p;5KfcpVbRmiE_od4Lc-%Vz>Y7sUuXGVRX2m zLHfUU8vz4?37YZo|2xh22vbC>_nY&Lji~gjuf8wvbBR0Qdgp+zThe;WY5zWqVDYa) zYI5G|!DCexa)!`W9E*Z?z(GY6i3w(eYLk9%-AeE+hxSwfw`tx7B!b#a>-J-Ac~-HI zR!oaM(aZ7?lfJ~5 zwDC_lzqjkJeT#U4r~<8kgMiJEkLx7~d1b%X@K;5<5+F>U;lE9;%7IqB2YQYknjin@ zJ^ux&gwdd2Wjt1Kd4C?ruRGLG0xiN!ky6|5BmMp>Ta%24e=i8)pNZO;{S7WvM`Oi19rV4W{s1WhsHyL`TSn=C&Ne7S|>y=X7 zo;eL5daH}>wqiZ|?9>22K)HhHn8=^|wv1%+<);bgNs?wQr?7rg%+oc2iruT|Aa?6L z-kY1@d;!|yIhGSe3D%*sAh`TvZxKX@ffbB8wPx4xDU6D8_G0O@8JwW`JyNJuMac0? z1^W;0HM{Fw_06@%3NYNK;~;AnY)+OMvgKvC1q<5%oVZ%Kt!($((>fUu=ILZYuBLXW z$LQ+-zAT&J%1iitFe|aQ7Js?{*tE?A_SQzZE$J!g^IX8Z%@lwpOl2^u7FX%VKjjCV zc-~}B{Ns5X*5Wb9B~}X7@`@nrX~G{AvVsFSqTYlg&FklR|Gxe&{CWUC(zcFtoZm#% ze-7IjE?xP^q>S}@#eexo30NvS`tLLNt9JzqlVX&0oGkC%zwh7$w`M;zN~hgvmDYcK zi4?~h-a5_=$JKqMU$E^I2?_jq0};E&aijbbpo3P&y;+URe|;kzhLDn#g8)P9f`2T9 zHtl|i{qI;SOous0ScdJUV=ez4JoJ&;6C*_#tcLF2(BFFrbAj+1NUSrQ3J#r1r{$We zLWq%~VOrsMZ0+OedW{|@`9acuHrQz%BDCVWjed5@QJBkXXAcBUGM-+$!TH-h{x*~w zV4OMnfB)A%|Neh1(h*jK(8NDgbbY=Htm|n;`-1|P{cn{vN;$IT5=2hV{x}?OLQHkg zQ?wfG01zYzP#0?@cYvd_hl9-+(SO^wO*p6V+anI8g&jKUPm{M&utBQO*o2Nf`TdXg z#1`NMM$*eKHP%Bv4wmHrjJ`L@%OQ@m^$ghH;(0ZouO<^^(*zr?IfjY;JfwRf3z;E| ztdPnkU*x2BM0_}zau$9N_F%9GOJ#9Kl0O#wpU_MK49%S4H?j5~`}=<+okEw%l}qLx za@-n~(pTZo{d1`XSdVz@KZKpX0!<*gEki4dS_LEzQuN28mo4|w+)p*GI@#_2^?3|+ z&MOp5Y(%huI5jBg*HZK4SiwY}*XAE8pY=6v7Q=gt%PG zU%v9!|EDt|jcYr|9Zi|0CH&{a##f1Hm63v_!5$BN2fIH-Uo~q#ouxXenEq!3C4%&V zDA1e0)&YE^1}!`PDFzKE2!Dl>kWp~2KOz$Ny%PuIc&n2D3-Ujr+AljDavN<0SmDn# zf#1_hk&F~A>0i#t{r5k?KnxRy4d404xWO+K=%n$TGcOwp1H&u6Dy7C!gYDy%`vPo~ zb8A_SYi{)LE7G4gASL$hCWAFO~Ln6`x3wTSQCsSxQ)hulil2p2ew=UMc_a@=sDH>iDzbS(+a0UG_M=C5QKHFr# zeIbw3%WUbvz~tvU%GhIr*-jK+%VSN8Q>&c(w8e)Ak6K@beZTC(Iag8EiVGH|0#UjG zfS8Ws{rP!S)%D!5j|1q`twr zd4Q!O0u(4d9W&aBqVCnNM}xgw!U}w7QI^{lfVVD9J!pGJSnMsOAKv>rrglL}MMYhV z2DT>xTvyB}_-+LnT>#9x<>}tSGpo!~ z@VdSQ$Y%XG7*%BZ#>#T2n*wQV;fF0?^dLjC)&Sl>@ID4O?LnbHQpa0GBDNbRDn-{SVIk{zmJS7;$C#`UP^6` zd<@59HF}z|munCr;iaNSmC>&v8C#KgQZoJC@7BO`*m`ZN;OG3JT4|g}3I#3tm$vtZ z-Uyg#S)u3Fz#{BG(stS+Ro%ALCpV9&l8?|zS1%}2pP0So*wwJ~mRG|fhyEA}tcfp& z*gc4)driTsgHGzTP4Cuu)nMt`pTj4sUcI(~UlWtlqmo?#M;2?R>KOfx;xMz#5U**8 zV5n-60_mAGo58k-^((*wNZcgQP1_d{KOKA+8qP!dApl3YlyUa3wRewLGF9wy=N_Yz zK0+N(*DH`q<<}UPdN}#K6>$158bT<%lo0a_G~p1Sa5oKIfgo`d`#Xy-eoXLJn9l4#&xm2;DRR~ZbCO5P@--+Xftqw_& z$bC8{M z_j$=zbj*>lb%u85RZ|QH9k@Fw3XopF`Ww|lVv<)R-h88ZPgQ!ZR>TM-93rH^$NsvNLg1C*HVKMFWfmVK`~*^c$7i>4razQepqA_m^w-jdkluv9trv5B1GJ*OKo$B84Ldd$ zE^v3;|2FqUsXWToG#R8hLzVSu%VG{7ut{ui{*N*&B!(#*x5l*K+isU@_&l@WTXAu5 zciHymHCk{~?%;OY@rU7$h3{%}MpI@DBnoU=JBX7TRa3pXgALnqq~WHomkzldHxwND zI3}Xod}B~$`ttING++8*_cQ`ce4+StCwVwKb=n(yBOQNK0u$Q?D!WN;$)SfFn|Mj` z1GQ~d8dM{TpPp-mfV=f9%aldxY`nA|=&^W7{&Pe3ggkvC{KPOns{9FQu`24kcm&&r z@3pUhdi{R$24KNy5CB{%mnrh=OZNa&L?X~s&VD;jcIaoh*saoQvw(}kD~Ub;?2wop zr(26RX45Hf_s;~)ZR!ssF0SCZ zA2_u4eR}nC!1G(q{nMBRU}CB?40StYCaJI2%#W_X{+dzAC!3-1te|iEOJXZQInW;?$W!GpbrK zW#Vn-YNt3&>`3@8g+L1^DAcc!-++iYTp8s4+;`yc^NXs->v)Uv8ww|s+N=(M($gYG zF3IGf!iV^)nXSS@oq=c}`+61I_vs;4QGkHkDf@uH zS@M+m#}v^zqU{+GWFn(Bx{#0RJte)7=zN6wURs$B;*JA%{n~Y0=EjO-saLw875j}h z-!4HgD6>gKVfY*|1tjWLq>xOF=boqKrNw>E#Ju_8de8jgFPi7^=jcW~HH~w&EvReJ zO7iAvB-6HClyQ%6(#oP|4GLyY%SP$)LLi^fK)v__a5dvhJ@7sL7pVfQoE=20w3BI$(AH^||$FVS0l9LEn%s1=L#t`Fm!g^2H?zdoicitW!6z4-YC zOpq{xe5TjM8-TJ_yIqu&P~>c=Aj-g|lNlT+ECX7fGLv)ix#r;tq7mJ?Sl}rWOCBr9 zLsp#L+$@vaFvF)vvg^BP^CvyYX9K?nssuN@XtMnQ;&+h~0>$F_hE^aR4hTiCwxM`&iY-X$NPWepT9c_ZEVL;3qoUPl@hiB?qFcW{z%;}X)ZNoqB*tYgHOlw zNl~X5y%Rh)vuwi$^*aw}gUSL}Y8}bg359KfDTS(w=41kjar)K|C^h^0C`S8us;sAN zk?7i>by#+@W`^(b5CPU(;|jYgrH)*47x$SMp|{dxT3i4{Mr?rYb0YEdYLGfHPYeAt zMZLOH1HGChshdCc;!#JaWk{5SV##wiX*T#^ko1sISKk$pOg{M(rI01tjh3_gj;~+h zrK4zHkWhDPTcj5nT!7oRrq!w)=s|A|OuSa0z%4sQmG*LMr?hY$v~=gmf+G>KB#9Eh(I`PZ#O0` zsQcFUw~g(&J_zG@YVWLZWWaG=XGbU%_5dMmNGHW6FH44axy~@ z7)zpfLZ$;qJj}!&;?NzEkK2}tiD9Is(S#vkH{tucEq(RA-3Jn=UhP{xe`Ljqo9hd$ zjP?^yqkf!g^l$6CLy^F49_17!hO~4Tu0?^M0H1VfajACik7sH57SLeQOQda&BedrL zoNLWs5}f)zRXb@>p}Gpj=06B41xpn#2g`!jknuWwBxVzC|KZuv-NfGY@=-bscDIdu z@Tqy|2q%`>L+{YW2j)%Yt1(@$;4sh|t9O0#ym7z4JF5eli$06|Le*~RNl!m8R-*M} z@Mn`ax_+RrkGE~I7s`*t(}+^!uvTIodi(d(&nlZF&>f?9eFAMid<8s}W@U}~c}aB) z$}UNOQdV)-_9H9ykJ4u&-V+*IsAH5bf7wC&Uv?1h)&9c3kCrqG>5x~-InxqM0aPGx zEK&3;!RG-ACYR=smLW3gJ+|(x(rcK&(THG6kh_?&J2K?oA$w7N?GK2b@A{-w`&N}! z>k~OZ6$9N?Op>fs&kJ78e;If6{|@t^FnD+RoD0Tt9&}}mB;$?ZUJJ;QXvDNu{gGbF zL*BbdUG%SBrko{Ye^byolmHc04Yu3c8?=2*xu_$~l@K+(u%@MxPnyTK;X7!@LlF!^ zGy#)6;d3c|Et2UNh(fd&Tf}Fg^e+iRQ`qft*$`1MI`AySyu<<-Dn_4=zh$A>gR8TT zz=Yl8J`d}{_m&4$Dhp-^nNl!fq3a)pZfFGaN@_moR$!!zGm~+NO8Q( z(rKVf5xhKp15zu4hhpLDY^tupseKKLiuM<=u1}n#-g{AXnGYAd)Oa9p9I;ryvQC9p zPq6pSZ%fbf>SS9hGFoQhkt|+rFyMW1gMk^VR8Q*_NZG@E@b})cOZA&|M1R6THZ~N{ z*CRHq)3=%4CTzX33on79Ik8BIS;vToe|f@@Xp)`&}$@WduCRbSZlYzMQvt z*({TyDTO(~!gm3lrQCV=KYh+=BO?G_>Sa!nVe1wLjUc&hOo;=!wJ z@vjY@j_*txAQQTKVCK&7?KEir$%4yUFwrdYP>x2qM7T+IxwG@g#0g@Ps8Et7v+aMqBE{%1^&0@&W}Xy!-dxPjFrSa*fXFy~pO}A=So#a-$0#QW za81Ai1}$#H9sPlfiNE7T#Z^V}U_1Pr*%*G4aCYFan1+5v6K8USX@feD#Z)T1jNNd*B3GR}bd(ID$)KxBaT zRw_u}=Oxl-sA4nfXd}aS)hiFiCX$ZrHw{E7mTO=h#{cjd3_TjdX&AQwphNE6sa}4k zGEWlMQQptnqYb7iO~8a{5wE8%D|bdtn@|05{MKW{HZZ^&TOvd`iuubTL2mhFkqV$l z1tB&GjLgl#$0+ZriBV7LzBv$g0GS{Gu1qKZ3FOmRKLFm^(`x>cybE5p^S&S>qFPP^ zLZuIIXIf6z^+rHxB=hW3DojBZtQmTtBFaD}Z2U~@mP-`8)e)QVLMTXq*5NMnp-!&A z_pi6tz;IyY3Mj~A9RSpy_Dr+ye!S*SV8aXqL?y3*q_IyFg(2Eve-XgnM^Lv)SDxba~x(jB_Dq`7(;gh-O3Lgq9r@QL`EaPe*d_|&IyCYiT2F7C7ZyT4+&*^zmx1m@np3rs!6Mo9n~^LT@;LPo>bLUpcSPFr3oA7% zrW_m^{4@`Xnva%2K~r`C!&ac+c@{IM3Ab)0X|#H(B@B$z=xKPvIM9p=xV_2n1Sr(N zqxDrKH(_##%@V#|uT_@H1?_M*|F5Kk+znvLxP9*(TR(S}qt_2G_N6tl@^j_=vr3zA zF!NWU;qh~IX3niYnP&|E7cRXw2X8ANur`174;UpeEGJb-1Ax-Gp z#0wXPZQFC34^t56&S!%jVh^ExCz(lM#kj=?vggkpy@D6#pr)~Ql$?F|jBl6S0aQ_m zV1Q@%TF&)kOwHOBT@VF@@el-%B+6LzObSRi?-q^2gpNxBQ2Ta!>`|Xi=-Xwz1GO>ID zKIVOTUlobyaky!bR4%3GQ|^pPAYDrYjZ_LI10Idxjp^^x1u>Ycs zvG+NFyZNSM(q>Df=ZfwE7NvZg9nl|7r=0S$!l-#s@C?ks7FEDP&X|0H9RY=auT3VU z?Q7P&`yKf8XSY6xg}5j^L&;af9DoB(Z>)4S#tW0MRs1g2J=E(!M^Z1r@EuQ1*!O85 z+mc3**OsjHPzSVfA7J`-JJi3YzFLAF0SR8LHvW`h6~JjT`&VXB{U>4PAf$3v91I2e zP>eo}`qbso%sZ-}Hr<*Q~?u`Qjrlc7tE+-eGkPl5_%@zZvLm5F!^&Tmhc9ht4 zBjY*EH7KY@YUvExwkC?xc9D_r-NtO0C?W!}Ol{~8i~OtE?%rmbwd){S18Ta8*CjrE z0R53hp}X36#xtGT`chbs2R+H3DwascXiZGx=JetvZ|)bou)4suiH69DPQ0%sS#Met zl@c8-1o3kX3@bg>xU_ZO0RjZ74$T^Asod4PI%N$E8bWx*r_)VK!vxE8Nda9osEm>` zsBA&xcdB=E`T_w}9~dM*0x@ef|Ipat0>spKFo)O|jH?ahnVil(Snf!ACUi9#oDc8N z`)_t|L|KCKwOQ_Ge8RoRi6^^*x_rM9-kO5z4Nff!bY&PSqOZ=moKiW_BK~$_1K)?SGa|fq+Z5b^n z`~LQ*(}a$x$5GO}dR2#(O-&o=3#n=rSTjwMC+Jw`7^OTBW&lI9Yd}v-uhBx|y8wev zSV=F1c-CD#8GX4LqgENqj~G|o+Ds8i><(&|s5Ts}-b!Pj70VXy0XqLS_$;>xfPCdP zDe9Al@j&A`X_;3Jc?eIb&0mz+v;1zw2w-@_P6PXdZZ7Yl;J8ixXp{+L zIE}|pC9x!c#&y4!=l$e}>JxTzF+^Efk8#|h(Z>BA6--TybKkwy6d*$pNm*R8hJQh{ zmjHP8yo$<2%&xOv0@is6qNhlYd4Ormq$EiUz6TFqwdF9M$dgMsnkc1r1~da8JQOU* zC2{tp(iEEs>>`KyC3=YUQNWkW_Im5v6l`#7IqAv@LUx*faR_gaW}}^hl!Ur(+N#Bz z8(6mik~Ld3>7f9EOmmS#^QY<5^=l;IMN-RI3aLQBRuZTsiK@V9N9jD;HUW+pCS%m< zJM!F0;*&4Bq6|EX@MbYFvdHK_{hjwx-&|uz|I$cQEmh9i_r!2gQ`Z@n+RNl(=L;Q; zC#t4(t`#;a&u>A@-Vj($C4v!kr`Hr4lCf~a^iqdR$EdTU*1)L+Gl0)z91HP1B$472 z#U9D$`3cf2e~=+eBAi&q9if{HkwF$-gV=s$P6YB!l&pI%YyA@a#n_-`uo>C&T9*c> z?e%leN7=PLzW&6ud)$2kQjwJ{7QHJHgUE}em?zOa_T!Dmd#Soo*GDR%h0aBZ)MNef zJmTQ0JRzDN(gyjh_&6ue=9xO1=n zp6o}X7#Lz3ybt}|yQ8WaaAxBtAi~HQlJbFSu51K1Ps$y@l(B$(=`etGar&OBf%fWX z9GoQE-#yZ+rMLLG-@;!7g5f~J$J!2nFmM8*iasF&D|A&*NdQdv7+|aO{Z%_F0Ng^L zb%Oy%4*LGs0S#PsHU0fPO>t<2k8?pHB_hu+;8&ikko9Oc<0(XGDj(cYm4nr|6AxT1 z*-70yk1j(syALiSL5~_@FXjAR33ygC}rWCj!+Nz#p5W zDvue&z}akm-R{m30d4({Dvx1&^9M)vrGT#8f zq{HavcI7c#3*PmQEWJ)~H(;+v%>Ew4aGn8SRDS-e9q5gleDy-$MPVWOK%4y*-l+## z`*={m;feF#Bf-YBU^uqydZ9!)$~yTt?|B|r^YgY(&3UB2e(x0Ai`ycsaOBR59;X0) z#*R_I&rC6@c@*$IMs@ovAtqHpU`rg7wz@_tHV?t`(}*5?aXI=B#`SGdHlCSGmr4f+ z5njM`k>HgUtRo+v;a1)PFBU=#GJ$I;sodx4Fu?urMKsPJ@OK>bS3lymO^5SMa65!I zO?ltuJ;X4>fY-$W7GNBLBgv{P=uOCzyKnt8LoT1QPRqh8^3c2(d~o+sg}iiHU@j`q zg67qi4JWZngdYNwC@atbg*GlqZ(#u}SZ*@{t3;mTt<@KNZ6_dh9U=+PGT2u5X`(pV z`zO(4#4h$Ljy)$^NG%0I1!n4GTTxo$Jamk}C*VqG*&CJ*Q-u;Ei_pF8fh#4tDL8Em zHt~bE0m1OVljM*M!RyYx55;a=KHxFPX|{>=!SM~_;R3-9(L35~4){qgD4I>5`nCdh zIk4^{QDoC%_&f3dEsamv9$AKJBg=wE3*gdH@W2a0u53O;iKlyk8%_f(X9Xuej&Gyv zyF)8Ld)j`K0(g~EY@X)dB>6ocT9QFn@(fv6uw9GVVc8uo)cS2DsA%P;1Dr(Q%{v$r zV;mztb>GY2RBTOdZmocY!Yh+0IG3|~{n&n&Vl;TR&LRo2;tRBXvEe!FA7ih5wM7eg z+y}c|ViYV_zr75rl*z4-5Hc-|0m8W*>@g`MO?VV)zK;DrJU>58G~Q3?D$xpbW*vDT zkdVX8i%;gi&Fg;+BnD6pw1z$K@{xCmW7T=mxg75*_C`~|8@(jNhk(UnHw2W=2tq3y z&)2~FCs^Q);(l?;A>exa^rHgEk_@6Cn1=!F<9z~7*~Ond_aV>l-;6~{TT;Na$mF0k{r;*zO=h&0wtHGP<%m!swjh{K<4=e_|TViCM^>qaEs~> zjwyhAY=B2H*STt%RRABesgI`6z?|1YlQzFV{iQyW%RCnD}n-}QWAoI)JS(qNp~vU-L0f_cXyW(L)Q$c zbVxT0-8qD`z8Cx zBMLgz0j(*!lJvhP(|Mr3GYq6LO#Gka_E=>4zjsj$=qcC3Ny?FfZOu^LC>ZG z+^~>^N&ukntQBPOwVD3cd;s={&VzUbAs2iLUEatA zAdt-hC?B)`&uz2-1-AU-!+o@m;Tn~wXoZ9i-CH{#>p+rUa#}X}*Z(M$o7y?Vs`zgb zfm@PS#z{qHnjv%0TtP_p+y7NDI2uw}0*M$ps50Mx>o1QQhV95+V1Zsp=7-oQMDjkoU0M_p@HIjm~*P1ys zUIEd6YHp>qT-g1Q%3_Du^T#!PWE>71_lR==d+<>iU!(Ax**y}cF9l>m(2sXun9jO%5Je+Whc0BUE{ znDjML_32mWw|S;3aL;#B<8$-vrgW=`9|DhYx;er)9zqQ_1emjukQQ;Ek$r5A4?vM| zalofK8Ge?G0knPI`6K1D|EYMiaI9NFFMx@?Cpfn{Ywbth1AXxV#``%Ws6WIbUvGpj z4l&BN{Q@kDp`7;-k&b{T@5n&{ux0|u1Je22rv2C)KyF8{By-mnQKkn&Kte*^KyIn* z9|C_ybS{YSyU!ahUWnwarF=NhYTiH-iIUp`xX}fPg6?P+fZlo)Nd!Dn#g%==?*G4- z`THzUqJqnp_{I`g9))gY8X(!9>VkjMm7>ak5{koM!55T&c|L2sMLg3eF!#;0Ww?3H51t z`W9O1_OmoOlmt%2z5e>k0gG?-%pcDWz(1jH+=eZl?ETDTp6&Y@SC;gjW{swT=|;U` z5*9hWv$t)&f!y;<`uvpNiYm#fG-LAlu0Xd`Gga!t1QPxWfh`qd);tO3E03}n1ezEJ z%Y?u*MZ{|zfWDapypbV~yM29NF>R)rc}0($j!$Sm`kP~L5zz6he0TA3N*4+dPo!LYxN@*1?ryG!mx5q`l*Q{`#F|3?N|zp+2TA!QMLgs@F0U zBf+OXf>-d;CH^Wjpx4x}^92D#&7hg$UbN-#I{EwGlND)Gb93bgD*A?!BcW+5fr}IgQ(09h_df(Iniw}N1 z!(zms0y9};IZ5ub4BR0)RveYMW60g$PG(*q!~X~kzSqFkBN+Ywd!D%J7w6e}|K(|x z!m|ufKJWR|R>3`v`c)#%Z?Q@e>LVbqpA77=2Gq~m!$-338Q|Ydko*?VRd&2&fDjWP zdt;raA2c-L8frK$94P0Qq$oUThunz^A?FR^}mq zGK_8Q4wBE{l-UXGJtzn<*aGdXb%kaElf`uLYh3F!&B9iPxmnnREJHFo9xSmW+ZM}e z(|^nAWkg}j$H5T}0)6*2ZmF+DDvg8K{=C5WA^xEc-WK<^73YQXCXY;Tc@S75LnQ_x zdd2YN2r{>JfR+b$m@vRQ0BXSw5u-y@`)wJr*Dc!O_u_3QR=kFsapE-+`{7>t`q>5e z+)|iOa!-+3Q!|BQRTq|UYsw-%Wo)MM1QBXo0{WZiPaHuDm<$j@HfLz<>-v%HFlY4! z&t_rSl7^!@-en%7n6CwdZQ0hJAmJ~9)#c9~U#XBWmR380o_*%$e4i?WZZ`2a+)oVa z?v7hB0Sm>)hKL;R%lZFUwt-7itoWmi8S%#2HZKdOCY52PPtbiA-NWK=H)3)mghig`uB5^xoO+f>ns<|IhM1` zm4CfZnJ>j8Yn3+u1(ykQ`5@c3n-qoQwc4UgSb{%3s>|h#iw0Kaip4**M|j495L?e`g_&!*fwuj7!BcyAwNR0NKC$m#TzTX#mN|h zk-giS@mQZE$2XiTEkWAna|a{Q6l0b^ZTj>C_~DW*klsb0ja*N^R&*kOEuj(kw;;0Od{m+x#FbQvtUI0k51H*FbOyR95jdrE;`R+2x(q z)|LPY?^sai;Q}l(N084iy`V0#Ww3wSXeT<*kj|Gdf^+czt=`b!@{Qw@w z%0B=KYK(l#D8I?XrCkD(Frh;at9Ic5N2d zTKKQ5E`p@e>}lE+o!4ACL)=_ph~*-XHL1E-7&7~^@5QOT0g!-38H&{*+$}guNx77j zrz)wt@9q$%`3o7HNa{hZH|CD=kfYYxTK$BB#gqgKWGwa0NqjmP*)Fa4Nfgdbov|P6b+%Y&#`7*R00l!&S#oI}7R}z>eAp_geRw+pQcPsIvqxNBHEP zpHT;~&oHU;VQYs`f`=jC#IU^X?x|t`HU@-3?HVY+O*Oq$g*YQYz3pW$M8k`TTK4F? zuKNVqFG-QuCK7*+IP(8J+~1L?H{N$^$;cw38I4aSD76_Pi9F<@39OHKk}sdmYMugS4eJvE z+SD}c_t;CQ6b|0gySL31Z!a)uDf2JIVtX&zo$g1)xrx3%lOqACekYR$5>cD=1h)8~ zz{Ig|#VayQ0C*n8C@ugcXkjHh^Cv6eTY&H1^-%@SB8gNOuqG`eZ6WeEK--w;KHYF+ z1_^*#655b3Bf1c|Ni$GxJ&1=}BA8M@F} z;KW_HnXFZ)ju3!gWKkRvh;a&E0o7VR`nHqvuF=upZ&L z{S;ci#@2mh8^7w3dO~E}E^2CnyRvsUb7H^)Is=R)?Kh(}fEZT3PO&zv&6i$PV;TEN zOgfY%#@*PbUzG6N309^R8wftZEpUTsc#)I)WwA?P#7ZXTJeXLHEg`R_ArEc4B%s zME^kMbMpI4!Z);N{&<9;$cL+uT#lDA=A7mp`gWSc%Yh|Uf!$f<^FpZ=C z0_mjV_O7l2zABqc@QxtuR)b&?kT|zlR4wHl@UW*@{T%@+_^X`}3pf(9sPyyCjA?Zp zCjBnT$}?XV6_(*I_L`xhK-sllg9y))hWz6&df7a}dmv2UgZng#w?nm5;Avl-{x~Yl zROh^u#|kfl(5PM`@q4K5`qD^H&W11CXySVxYUZgTHujFyLabJtr-175Jlhv+j?tTe0~xB$h`QQywnvx%r|VU?8+8LWbh% z+>KzyV;p0r2=g(M--c!}UaZ$1ew5p~+1F9iJZ`%Ub*`(+s}LKglJf%z%M&>JQbZO4 zWrLEt#<_Q&mjw&=snl!U)hB@s{w4M!TqA@z7l!(=K)%ts%D0Zsx>ni6X<3j0io>OG zsxX>MHSUi$9a50rBbX`mWcIOaTaH*h2Oe?~xYnpVooHOPS>6B{aG4(VX~Sb5aq8qv zV9}F;Vg2Q=9#~U=LF?T)n#mL<4*@2)63G`FuD@d#gFz~Mc@#sF#`vh5&fMd+ z*FiO{ABe?8kLTFQBNrL`yxh3-4JjwwQJCllYr~?CMBcUfVGyn7R%}1gY7QH31xY6+)Y*VSMxgnx@Oq9Kw7L-NE>cH`t1{|PI3CW1 zC{SCg9H17A?xwHPiGSVvu2{u~YLGTT+2mVV4+S_{pvt|Hy~fbj)-e|?Agm)ZUx*1HMU4kQ4@D&TA;dZ04=dM?w zR__Sz!`l1K1glAsz}3TnYBfzbPSf;#T5Lzv9MeN{ZB|3fW6KKqV{cj4dG-o{K8L1f z8hpdMYsG&3PXpsEJE0*9u^H=!(`VakGg|L2m#(jmoU{4 zNDl;Nm$DjXYVhc$h^pn^X|4?~hMzTvmVyoRgNg0LFE$?fsZ)G6M5Q}LC92WXTiw$_ zZp_XjLXqz|W~4m8Ns+B@ccOIlf|#SEqvBO-y6jpc0T?=`Hf zubs9wz7JZf+rHfxsq^#xwe{NPTO`4h|2cg)=UWSMEYTGSY9t|3(Qks=$&u-K_V1NW zR{4&mGsW#%1g`@BK*41o%`%J_s2ooF_$XhdiV&!!E3w9;VO6`mVw6?=Yw zhOxF;AnU@^IS||3#}y?K@Ui+=Z;rd}`gPP5kl)7Z#<`6muruEzj!oB;cMwFJg0s!| z=aplZICiz6B(+teavb*SEtISx!OQg|sV}lS^yKEJ;h!ZZY_M(qzC{q{Jfq&$hPt22 zpX|gsRb(Ztwbtt1yEm>9L^@)5&G6<+jzQ}QqTndjd^TkrJG_7Pdo_(A@d?loNldP$ zGj$g7lcK<)`I~dbsf6l{zF!aA>ZO`*B^^(FSI#7F1f)->n46l1VzX%7(8W+T-DM!h2Y z0$&5~*!1?CbVvSWeDPZS$U@!=)p_;05!207efPTU6vYHf=iSxo9cw9%2R8iE60?o6 z0(7pG;>ZE&V?BG9kCAx-RDqGk(~!B^gaf$il8`RMAn5?i%-GL1LnI|{Juij>yfFs& zh%Bz|uz5hV4PW_I>oekPIBEsi;%n-us0&tfes#*Z(UH55(@$^A6Y4@>yIG8HaPZ?S za3V3#3k*fO0ZYZVOTHbJ*Mt&afAtw?uTh*qjhY&A8gQG@akrv)&7_tY#n#cv>RtiG6e#gA324^;*wb>$BDH z5XYGkV9-70Iqk=WrjRhy$FlXphn0@`ez{9P6Nx~K+lFyr=j|_RDP?&9*$r#denMqp3vF;8jSZB#_yhX+I5an?&q=*(b9ROlr<40o6+l@q%0R`yv1I2 z+HR!pH^dwe`s?MpH;1ECr%@sRG#?$T0fZ9Oy&A$FWwdxzsLovS_R-wQ|K1MDT&w0E zOq=tQx|c7-XnBizr!geVNG=Fuz1@`5gNKSW!?{vS=*BOezF5^ON=jfo*tee&+zpSs z0Uf6y$vk{Yaq*%N)X!^e0cvD&nRv_>B|Heup!7S^TIm5%oEeo5b90nk{B)JclLk|m zp1+|!5{4~a6U{f`Gx_Eufo-db+xC5rvI90*L<*9FA--ix4lQ8 z9|2;e!Vj(3{@oQbAh(4Sb0b7`mGgV3NRbTxTAMU}6q~rf|%gu^*^A(~&s!v}CP3 z6~%F56Chl#blhnBB!o+{v*FHOG=AkY7^fU5R$4QA0uhsjo-65nRcykFvLG@B*|6Yw zHEFbE;iHfDp}YavYW6u|nZHcLR&oD>D)z&~$V_D<{8LVw<}G%DJiI21m%?9%Scfvr zkZPA#oi+`Mm3S|iosIvqPt(@)bwst%X{;LtBaRZ(l5*zS`#l`nwpC~1<89CMC|ZKa zBYl+Kd&XOQ|I3z@`^vv?$I&=ih7VrmI78G6L33{5>^O+ue3>Bjz(__A8dR2jB#nwM z^@vyg-Ufb`dfLm8+!g~pITJ8fNpjk`Bu$L%LFq+*Dy>_f4}F|59(OSV?4@o60%bT? zoB-YeP*+@(?$xIo&Mc_vebt)P9sV+o|MgBx3I?q$i@Up0?<4-{MGw7gzjk`9`=KNh zL@|uX%<{ccMZgujr9XY?gAqwpr`e>w1w#oW0ICfLj>4G%wnl$ z(8+3}q5!Fl^|ET2;IowtdkAdlkTb=K;~YiOc- z4aKgeRrj~(%|WMl1sq4s5%?e}gCDc9BG>wRvhiL$wKw_O3o1ui!a!Z6^`$3xhUU1- z-4)=>I8v58KKU4il;GP7fAJ{(L=#PdFAN{>eFUW144(}|sM@Q*r;#{NXpam!KEzBj z>pJ@6PzqvrpO;lYY861E@N{uSa`iSO zSP61-=mO~-)Y`jxN8sjn#iN7a{?kQC7wi#QN1IFy>-nCOTmSSF-*trUH{v8>?S9CG zCmfAQ(*UD^T9C+HMfr=MJ^@B~$>C$JpDz?FOfCMpoYmtMwP+pn)cPw2eND{_=?8O@ zRFWnFQOxszuCty&6SzXB=5Kd8=o{D7k9QmH{dXqOFZkOL4{H^zhMG@Jxo|Xad+C@( zf6Ig~4)s!_HWA?B;kfy{`b`?(wNyQ}#pdi#7qkEb%gC94mubttCwo17At9~Fz}NY( zfMb$1+dIg)p6lJM`C3!v>NDJ1;Ga;~T%TzPJYCd^wXE?aMuT!MFdE#^J&gF| zMEQ6$y0MNqgLo}eiD$Q>ru$2t&8BlwP0ihXLZ#>a=%QS%<4>LN1|>d~7RA4$OuX4S zba(@$Z;)0+&FRi*2XZ4q=8kc`{_T#LqH8lt&GHf>C|eLOR^O!x6O)VAG3bT&An0wX z8TgqM8kaL(a(ysyB0Bdx-dxYoQfY{77QPND{`a{)ybt2vxESEJDHicma$X)ZQ)O>O zdZ07eRXrSu5{$*}s9}xamOw=PgE?(~328HIWI*46&GUsEOb8 zF*PT#g&Vx#Bf^~W)#A26g7Or2kCVI6uZ?4 zDp$N-Y}mkS9LbJ(e9__JVYE?+<+JU3O!Qnh^6t^|N~Cbejp8m5HN2!@L_Cc87gi+rFN5zj zPk6`D&coGj1l;Sxp>~J-l|$;v(vbJ@%HkvA;YT;6b`z)Aoy^6_-VQx73p10o$Q?S9 zsQwV>(Z<=&DWm{~0YmcaX~wP)?85_!eXJLz>axI&frtY~aZx_UIFa%{&yJSJ6RsC- zm_Lfc2(`K<@tdFh2ACxmTjwB|#(UU7mawSKD$AI_sP)qk*B=!x|50(QjnQy6Rh>lY`0J_NNFSXW*T!=r zJXcohcd2!<-aFhv=c3)ys7Al_*$dcjUqC-U4+vD#X_wN3-P`;ltIj&*J7zfKq58s# zAxGf_a*Q>_6-OPc9>6YO4lgcEIZc<$sTQ<`y3|ts3Goo^!@G|a^sL_EzmzgeHZ=|# zV!#=3jE{0bw`IU=;Jht;YsM*B;)J!rJ`?5of5^fU{yuomYWmUI+4LpSHTv}nH&Y9b_hqL^tCHQLgQh%dG{P_~~&4^p+*GIQ2`YYemzEPzd zLl2|ls%Z^@lb2?(2t=4$I-#AYGisG}q+!C6iuw zIt68{ypGZP)fuuCkMGE6m-Vc76Hg?v2j{osdlWcTpgK23gFsXS`MxG%C)c57!v~cT z6YMLhH^MZrMc4Ep8WC79K&YPFj>S+1zc_a35Zc-w-T7yZZrDxHE`z%^?{sG#Uj*PD z%^EN7THK$97F!2pygFvf9*J5CS`oq z?Lz@)ZU=L}fGzKFMbN*%;Y@i%=ECn&rvEQ|{-i?b^`k4!(SRT(~?#a?$371o%v(R{^Pm&hCb0GwM`0&Zzbd4XeLu*LP#WBS#DLx`u+7wgi* zvp0!Pq%c=SWw8?ti|VSwES!Wul1eTf|H3R$gMTOd_IVRf7Nqz2n1gWm4;sg(Y8)oq zROvI;w|i5iiTJkSK4!QBIAj%XF4#s38a9}PXO|& z^&HhG8(5|yv;p2h=Haf$p<$xfhk}ptYSwWA1;l9R!L}n>WW+~>{h7htaw_m!+YqqT zlZFEK)-R+vA$?8T66o5rU=5r}@tn+B@e572#^6XgndX6XLo+ijMvNb}&t`l5erkjB zoK4UEMwRcq%{ib!E$+j7B0ta4x?yNYrs>E}xos6>No={S@Dt)*#u{DpABKGrw*@_Tj%{Vpz!#w|A)D0h5NB-ao+8 zW&Smib{z_eYC%qi0@bbjM*8 zrz1y_d6%EZgEAcWp1q>zbaHtINMPY#X!3g_NGNJ+0=}3?=5pI<57?~%{yMg)!iAt; z;+E@`qMLn&>mm=xGZPhS6`;C`yVw-z#B7Y)oX!Q)hLvI zuEnac#YrL$P-TrpNO6W-65U9=3zLMA#mXH-8aSu}@HyFt`pZl{S%C7@u=m}N zCgGV=h&i7Aa#dNxj)Mx~PP77nDR!PIgrF6bA94_S9RD(Pxi6jhiM;$cnX96iX_}qv zL}l~AT9;y6p~3!_RfWd?g!eg`oc9b4D1&c&UkHPS2ww^+ki9OJl;7Yt813$S0vrJb zpE_^%U?54Q3UH|=5-XFmRdcb68v;NKb3z&-EJpdM1l?|q*8|}9sFcxpl<3@GYkAwW zKddS)7PCfzFLh2zw;qzus;hg>W4)=Tp2ea(s7L(A{Xtv7pu78haDxZ;<^1wbC33IE z4FEB)307jF`@;}&)mT?>O0sqJ`%Z9xl7Trvb5s*`JzbfZtz-56Q_&oRCdX*%6*n{# zDeqps4Oyh~7r{0^Jg6}LEns8!#T!VIlq;#3i0chMlL*qM&PRUQ^G_(lI4{fARIyWd zm72=qBio|yQ>#02nc<@sVHt7|=2FL} zTwG8QZTiTxjBhM?R&R&6TrlG0IpRSu99{9r1hpZ|wX>mm@x0uvQS6dGe}dRKQhjqv zVWea^J2~fBTOK24IkN}tNnWFW(mh7AT(&t@5Z`}pbmcehJu5u>5(>$MAv1g4UStME zcanQms1^svNBtYwr^DA=jvFtgtp4keJaTlpUB{B`8|ux>RHcsy1#qNAZa;AvIfy|U zbs87jxKL1W3kbKY8g9QkwgI@P>KJ?r@13tu z=tKY-=-w*)9F$i@>tnlV@Wgx)u6agZ&^%(B$9&_qg&^a&`GDC45YiW} zf(4W|w@chI2=ZlaC{`J!0&-|`$*HFss98i65{bi$kak(cj}4)n|y@rRg$=LNceJiC5Am74fJi-1&$>eSITS^tl z&KSIQ;xmF<`o%>8xA%ZW-xV`y4SEnvJ+?Clo!ZHH!PgvE^320l}5|dS7Xyp%4p2 zf>Yoaf!^n^u`6vCbdP}~xvf^?dQC@w-^xIm@~9$nG{Pm?sv1^RnfKCX1tipk9449! zm;<%5CbOi3i8mHv5qd$2Ip+2JmN7JP83gpEf|FhlX_<3b4>PM3z2#>yH<(;`0kxWIv!?yUzF;ic_lqx`T#G`tx z10w`%rFNtg4{gRuvjb?-ECv;}R<*^JA-Fcno9dTe9kj-is5}3P8Z_FbH#}h&C|1Cu zqQQ_+7~5oD(_hwF2~|C!Zj@#@%d?wa47tLT|jE)>axU9!;z%qaPsC0f@ZzP9z& zse9u`!&35dYc1f93f>*f!K@#=E-p5cHqUP#!(v=n-I`5w&Nc5rp9jVI6u})?2(FWKI=aNdxu_(FcQ`mCTK*R z$t76|r`&ei^(bp;)6UG7F2ASLHng|3t&i-M^~|BRtjA`G|0!XFxbXBXS3Emb!KP5% zLERiL@<}dMHTh)RH1WX0bh`^1=V2NV_Q0Zur^7lcW%@ZIKeI=>s4( zswUrFu8_-0P0Q=^<_wLSB-+i`vr?Oj0vD1n1_f0v59jv7TH8H}b4m4y6`IaguT@=5 zTdm8@#u7C%m`3xa`qEzq1ZK|S;US~7XS${Fk0P&K8iazUa(!7!FNXA34XG(ENj;=q z|7WVJh0kT}uVzEe+J5y+>M>J=^W(NDYqPOkBkk5PEdx*HEE4sGZzuW)aISroc~b3J zTvHtz^V6c(`enS@g76OTSM4YqDcDCk$GGKZw|;{?3oLvOnDRwea_>sNvdOArwE5D9 z_W&03xq%|x!F~MfBf^gBV7<)=etm*Zq?kF4N%hJ@T~~s~LX&Q~DE--Wp5qdP^A6>1 zB>v#(LaErsbJV7*&yjCDg(FK7wox*8+&}YGrA^%0td|RB2$@7S%QrEnJr6DP8x3Oi4a&Ggb9oLp}qsBS$)H>H~jUEtv;nXv zqGFlnAn!%lTz}{LLx!oMG<+0YOjbJI`}&u^STFj!B6W==d{$+P{Y7QdX}>fprX_6r z4-24P&Uvbw_d)?2`tq$Y%jECGjF)sW|Mtw>0bYMmjZy1`Dc$6=ons1{EcGhR{;ieD z7n;X08M<`5;bdpXRNS*K!WAFoiUzE=6K2&WFu0n=wXXO9KBxjssq)oAeN}4c@z0It zoc=?egDuJ~X~ps>TAxNtYAjV5_2YT=zA_F2()G3CzyCk z==F3X%fW0a$p)^;dSPq{YA|XBI5gw?fORD~3}qnUM;o1pM3W{B#T2}y{~{RvtKk|* zmf&l0P;i$0K~^??rq}x}OL>-G5Y-AP2h9W4Hp{zutemtNDGJg4Hk0ux5ytO*ulGZYF0`XdzPp8 z);C1@0}Yf|q6#x$45C-uFjQCWQYWlrx2*xKc5y9A8z66C>GzVzakw+nB&sGuovikr zGXuNlN&SAYNIBY5K}cCBSkJlbq7n|xnW7Jd<0rufv-ly4Fb>baFiS24W@QgK4?=5V ztbO0;VP|_oMN=#IULon%K$zP*=zxEwC2y*ZULj!>m?SxYGRHch{7vXVq53&o{~7FH zxA12hfow+7{)Te>myf+Pf9gd`-BRErJ<^8_aV2iy%S^;9Mq(--D5jbM&ePv5TqA z=Bep9G{#f=;4uO5yECp)+Gxi;CAwSAv-u^Z^y`G`-=EVLc-lm>lCJFv~&og!K$vS0987aHF2hh%B zrGxD<#ICfWE*S10m#80u9I=2)XsK ztV#`e|caQ*3JhIFXmri>YipH zGoj)n7hD71wq0kBGXCxM6okuWPzk6J{{TLcg`r)P+5U#%gJy6O&k_Gb8iU?Z*>+7z zgCaxM2qmMivo~~0zp&=VJyvqU@eyO45thd^eO(S|beD4^?(s75xid?t#O@`h-4rwF z1}^n&c8)_hd-!wjIs6-W^5cnTv*m9=%hPkz@Vu|Q_X#v|wn5qs1~zATe%$tK1F#{e zcgJm>4NIna(S=c}SDf4yyzhc1oKwLM?xV-@0*ER>AbLKV$fpQRtAQ-f(#A|BuVx18 zDpkn)L7faAxoVs#RT0+SN}P?~qEYJ!)LJW5rvJ(n+u&F`DMQ*{GEvHi!@lf?7q)%e zce}U&I*>7{TC+qhI~pmTJ(jqKF+*dfnkFjtQQA+&mft5+%zj&v z8!cxvwr>gaYUeDS;nxFM+cT>!7z-w5gn40|yWVZpr>W4PxL$15W{NFSGNVWF7-niy z$I=K!;_`Yr@Q%{A{rua02KLa|TcS{6*qXePL|~-WOBbUtwM}yA*AxAeAUg`4`mXf5 zMR$Ts`riGj9Tqsxm78dJ4%Vun=1#63`w1&pma%`>x#aX@@;fe}-)Sr6E9|YWqb_^t zk!mF}Er>UguwzVTd0bk9&rLDanQ-UUE`Z)(jlD}Txv9oLj%#to58vWa`n(Qx{P;WN^xx#BDY<4 zLO>1fagcWvOBv&-SIgN;!<`L^0kdkyIWjadcSK6l5oEaUlKzlM(skujQ8PG@x`)Wr z&Pqrl3>8XrCy2)QRhMxyN}#kY_P#ZB?3Tum_n(PFJsoT)AsEriH_aVQirOM>iDYi% z3e63MKhU_QrycP5q|s-lepQ&Tper2#k~k@?;yXM>w{d+>WTy? zniNbi^xBZ_LGX#YJX7k0hdrqK18}|?6leajv6bVM74N59N4YKH+PC^Ar~?znAZa7% zmac>+Z(HbB#W}wyJV4Y!_u44(!KcL%zBJ))wT{#pmpgES&csi&KQ%aLAh@dxCtDQ} z@<&dSg80&s7hgK|-DI0{_YtTm59Myk7LiiKiM7{O@A#hi5k#3;O+%->zJQvSi*AC% zI}#QN@`DYVBxvPxflomBe3LFi*(LF#)|0>0$#~j0@x3{EEKddhE>9aE6zZJ|u_D!< z)*)Z$6gjhI=xjos8dErt!t;h^1ZCv@t@Y9`-J6UzU(MB~rF0mo7HsmdLczot;w=N8 z_UH>i3Kdvcm6Pj%`taiX(hL81k|6cHFDdGHftnbB_A@ET(&PjRLb8eQgr1tO({**x z3k^P!aH3SMzLv8LaY1XkDcyUn^tkHry8(%*Z+9UL35d(T{kZu~6#hRSQ%hVbf8#nc zf6ND$#3=eW)&}Z<<;~SCQ$x^1!D`^I9s{Mn23Y)n$^`EwD!J2{PwrA z{aR$wA$DgaW4uuxot(ZoiZYeftdU~Xx_VYf%S3fRlJ@ZL^ix?ieA`^!p#EVJwS?>n ze!wDWY7iyBRmkE}&$96<)rcDWy!rwrY~5M;I9rgA&}w2Tk(wIa>Zl8I=AUfH&^*XK zgnZL))P6aWL&xJA|4kpEUnLb+$s%a~p5Z=GT(E7lqy0mzPs;gmT*GJ3M`OBps_~+t ztN#S+>XC0H(1Vhf?L0&Gvh&#TJc`dNopChqe}0Nosf{=Wx&x$MR%UC7hAw@41J(%2 z?+4k1cXHQO@Y0U0;?>LkQX$+kXPLj4TpqK$SY%A1dtOyL%UWR#yv27`?YjhLoaPOV zv>Sm7n}S^V~F5Bd&KLO-Arvx~tFIf|jI2nJsYbM%IgBlfZBFYYH(S;3;O^hKFr1 z$Vl{ai;%0AcSTcU1{!{+LRFEhh8V#^yKhE&ZG}zm=SV;LY zEZvo2RDnq|PWme}j~g>gZJb0q+`NR7W{>u!HswYGzz)PMxHhu(b?r8RJpF+y%cFT4 zkQ7lSIyR#E3ab{y8Eg!|izw@Fx#{#?gnE{fiE-f7Y)hXif}QD&v?J_PYajo!UCYHk zOOapU%+pGpA{TKq(kmc~ql@RhXF`OySZD9f7BN-rmTG<4#G@LiX!qLQk7S4qkZKFt zzjN>4^9;3&R|UyeD*ffxTBQldN~60-8&_dih}^!!*ypcssBbs&#Dbj`AS#2h2%5nP z8Kx_V+GCRe7FG#p@+Xxmn7I8vf$N1fQq5qhB=040tTjhUGLq?q+VjGSw(G z&^u{!j(j^Eg=Ubyt(Y_$8c-6;Uno(c#sP;g(=&^8 za8hi3;zcYweLga`>nr>EZSE*_f?9X2RBzw5&=tPHBkiFDR10?{-fv_x=4kuAZYF(T(jn2GEHdHz7ialRM* zZU9)7`AMt^;`PmRk#=QxrLBT`HgQ9paGu>=Vrt^w zVNU&WU#nfIdodmBnVO_cJ`MKXsc%yHjvpj}psB)_L-2Swy(AZErPB9nU&K``-U->) zza=;VJkgigTPQBOLY_M^f6H@Ctz4F$Ev)=NR3xBw>=(GD9v=`S)I0vTDsM;JHtq`k zbW2*Etex1`gB-nFaNACRm}fleAN=Xna;{GETn#Z{Cv=uK?xwB(dVz!R;=2&=77Nm< zGrl~Gi^F@$C_hT!x+(WclOEE(Q&=1RKwqoCUAUC35~5zlj0 z0cOyi8yjr!p-$7)Cu|#42uMj4BhB=?c@^)-^K7xof{Z)s z(YhETXNzJ!H%r94q4tvr?k6y&=Yp&AFRVi2od%v&B ze!1B_5N;_jfF}}f$2CHYO(T%}=9ARA(uS}sHmd<}1ur1P{TJ;7`RWKV+ROV$%Bj|I za=kZT*r(k?PMV6cfd+^+59`)9lu;WMmri8@u6xU8t>OjhA<3LK>Tzgk`+X66D!%%tiXg)jyt|+WnA}fsiYWc4Zl%ekbq8Jr}~{A2Ton9&C4>= zh6iOZHV*#0H?~(w&q31~&fkx< z1={hScXXu?*_}Q${`UH+&kScW7*7yaf~8(x7PlGotFG#ojadH}BW`B33N#Ve;cK)3 z-H(co9}6{BteKMb+qJt@#YeRzk7m3tyk`P5i;MVzAbwky($B4aUJ(NysQe5&PD@v4 zd7Dg5)s95Y&a#5+Rn|wD7V$JtyX^%^362uVluWl`<^U=iXS09Q@mfUJZ;D z+Hqq(oVciGpFSZJU|vJsdg_u)j(c~IE9en-t%3{bBx$1QLlW`?PZ8a4yNncvR`q>Tm~ujoX#39DXe#X#eU1Jf zMcsidxramKGWl_+LSbvytO}nGrcy%Y{9#RYNtN_SBsjl+;$M%84n)&v-*8TW@>4?e zY3)fPsHZkRg3D7>`NkdWz(s_^D zUECWk*-8`S)v4(29lm#P#L;32u$`F!TOBDRR72iKs9sgL7P>O!@&Z_G{Sp}u+Bap# zP;F{A_iDyT&yjUm^aiN3>TA^Zaq1}O4PknJ(6ri?&vUL09mkpp z4S}n1zEFiN^tt?c`r^>B`p0XtZ(hw`qc7q8!umoxm@K*()HC(5eK)&aVxLnFHl6cJ z0b7cvb7|7FqQBHvPQQH(=Kqhb?~cd1ZU0A?LdmA=y+=Z1WMpr$cQP-ljI6AzP-Zq| zhl~i3*&rj5y`r*`J)$!D9UrCpzMt3c`&ZBFelFMb`JCr@9Op6K$NT-mX(%aF<8%2_ zTvu(XY9{=Z09*OOR_S#~>-J?WJt4z9>r{2djzR4ta|)U9d$v3^>^W!?+-!0RrOqG> zRG%_NHhG0DA({v?UV=D?5w}_~>wJpg!Rm(FPLw>EZGYbrt@z8Z&Ubmo-G`P*%Zua${2+?;V zeTbzB2NN#slwrfS?A=dKOItFu6SaLuqe(MtYL%#aorWTMDiNyr^J%~~C{i{);!23F z_^euTZu#4wzlB`Chk_jQO#!?xsUDo~c-2M^*&hlu;Z&D=Gidr6rP-w)(3h5pOF!_L zj%-Y$Xqu9gnXM=|U>1wxYQfX7s$p&3TToKkWqt87SOWJi>PK5TqQ+Bpun+Z&=&Ap;Kc(NZr!_3DEbYJ!}yHzzcMmLJ8 zfcCq6Hj%t#N8)B4DGnx%juJ+;9?Lm+o}f4h#App}XdB?+4#3E-z`Cc*o2XTUTEQC* z0aa=tmg}tr74!2aDR@f^hIXfZ`MbTs7fu1b0r7!-L;;<*e(Ah`&D%3vBRP2>B0Bbw z!G8gwrYL4!-6nlS-F|a_54Qk?LTr{+55hnxZ8+aV9UF`>hc1GCfbkQP+i@H#=|WTB zOP+Hu-!(eXErN>ST7rSzsuS|{?jQ{`9(c;dyUX}3P-j>+?alIy6Mk2Q%Ayd678XC( z|8O9R+mst~Y0T)+0jx{9XTvnjwi#$6;F-*UaoF{UOrP3>Z#(2q-TQb#@`<^YAY z31Xj%bsrLQ;|#yz0jZA&_5qA=(6?$UUZUw!JitG5jseX8SnjVdfd z%k!0eCqShFZxb-ALwjHKo4;Pq=PrFR#>nu!L&N{PjJ6q)-8c65GN;_H9R%mO&N@j!j4>Rq{flGUfmT^cZ0` zSZ)$ZMwnSs^v(SSZ+*E;cOFK@qxQccWMxeoiRDW=1ND>Nc->%V*|=*M$emr-26;77 zj!OVFI`nTb>uxTONy)J*b{bFp)N|n9Qo#|Dlv(&L_C`EEm#$Fm0`7O{QgSXeTq8n{ zQh)a@5|ZKJlTZ@lBr43;yh5`*;ih4nnC1Hb)FOnasHc&kmmjqL-#;0g_DrhoqKRON zW2)#kq!hbZqD4r+Mrv)}-z4ztnc5Gbt3x@DON_w)3J{tDAk(|!^tj|UahU7$U9Juz zPhbT|N9YLb=*;co7YnfR+I6>|Q>CqKZR*&urEQ~N8P-C|Qedek3(zE^X$s=3&n zYH9~Gh+E)PyPq~ivtZ!}wMkFn=9w1q7*(~aJ`k_V zrK+M>j91}}nBeJ3;(7XM-&(C6XeDlSiEXqqbtB{ZRv)0@{|eD{E;YVp-zU5e#28~Q z{InD7_M76fHX6M{Pr75&qO!?vvAk4HxSgk%qQqQWHWo7<&uC}{3V=<|%Jd9&$-mTr z_2QRy4s%M~3;Fr+MR2Kg3JMbk#RjeUj8(sk^xR;5zJ2`-MvVZv*}5>CYVjRjr%hh@ z0klw4TEs6vuv#IS%Zsk;QG=@izkJ8-D~aVKVpM&*Nky33XSSjEAOIXI4;pt!G{mp^ zZ{^aBHt=S`Wpgtoof{opwDSd{PQNp)pfGMsg;YOHGN6g9G;u=OH0wT7w8%?#<%0O0 z+$(-t^$6GUGtR-SWS6Tf6l;FvNd`X_t$z%7tqhmb`3`)RR_4HFgh$4E&8Tz5J1+dC zd_f8h{eUHw5`Pg(tW8v!3I41ryS_w3euBoOQKK;CvZimPE~&yz>-VzjKmg{wQEQcp z>dW%J13_%Got@ni%k|Gud>4qV@dnGEcHM9Iya<~b-6)@<{X*g92M>MUdnSY$65n)u zhf+;WPb-(LG9Pr(&}8}fRbo76cF6N*t0>ssoBFkHu0Yc@sN|H~TH(91QX_GLt!ecJ zNxnFaRF)BVN_0e`$-5}=|GEa7?75J(fubv=7Q3x{{#P$;SHu_=6JG+ah{H1k!a2<; zATu~#SyjFSK&{cDXIuOBXmn*#140!8e6~D8`C7ce&Msp>$6}2r7Hx96H*M#0EPQkf zozi!G&tmOS53Cr=tE3fLWwEcq@CD5GK2u!2M@k_p!|-zl1XnXVzi&N~bn@SurW>E) zdOiz_gwOSMpa5YTSgCWW| zCGV&EKWcPc^?v8O)XcJ!!Igbb>Oj_^g{h%_ahBBgUWr}h5C;c3&jg?Bk~x-o9PNkd z${`Sau1`acJ6IE4$!t~dD`bz3#Nyz}J^lIs+_N2%?j?{=syPrn)? z_iml4f7o5Vvb?-JH)QN0gvZQSp~p)DBuCpLbQBnJNm7HOEEE&6WqHLK`7>={+}A}@ z#8zJKNI2)*KLJ;*3K%O-Mf_qTpKIx!J$5WA$cPAnyGX&EB8nivlS1XKj|DD`2^X}- zUfnKPI3;NKdaE>!Y)K>FXM#k!s$`{V;`r`tNLn=BcOZIjcCKH(U@T!+#_V53QR4nC zeHj0JwcHE3s`75%mYOM%wdbbK9juEIy7K+4MibKKb|-f(<@$NKM%_R2jg`hbi~T-c z`+1PZh%39q}wQzOOlT*Aa&PNXJ^|526m4V~B2ySoZ12B=)`+-H059 z*azFh*BIAjmVq{*+Pgn}(#k5e{~g?(X6rY9_Bd2%>7A>yi>4InJlO4a@pseJov5^q zB1^(EVDwbjS4`10jxM?7|MKR?mLT~Z<0lrnK@T9L){p~?v& za#;cm2Li2fK@#xN83FITcNhlx#2Yrvg+q)Ec5A=zlvHcF=}}^1**iMEW%g$qcyMb& z$-H9P=_9b#J06SvP9vCkoSpY`?pH?r{yg${)9(QxM&Hfm#V6O6+HsMn^;nqZG`|ub zL~lO3VQH<%V(={ZX{>85G>~RSu&!@xKKwOd^kXB%gr3NI_sjLQJYpFhQNw57gGTQ4 z#1lsdz8__Go??9<@ek(|CGKhwLQx_8sOkiAfhh%Hip)AFjUb zYnUgfHKUA&_Gpz>HQexJ3guRf?uE9zUpc}8$Vt4Z)Z}vIz{MiOQHO8uX#5B~fPz55 z2-`y7KfY%Yq1mNjZd1X6Q_a0i=}{IYRT`S+R&-_NmF{CbmN{*G{9trB0@dsWE?c{% zwNSnkpwuWITS~2M(s+2uX1vBJVp-#Ip|#~1O(mR}2Z809T@pce@MR0-P>S1%a4zE3 z;w~OTp?L;EUf1o}dOS?)(d;)w<9*4#{)6{a!13o|nq;Qe@k|>a0+sT9X%-^K!+miB zV&WTwQiXDPcm8CGM`7T=<-&^$S!-(`sH1tDec3=xPIa$c;gTi7w>HfvX;Vg&sWT$y zThbaQ0=L>d>M^XKB`_wrC4ms5|M;;iv$$~6lmkRyB`hrLRP0zqB(WW$*%(*Yab?4( zeV*g!%}VB3{z%0W^-kgW-Y>ShW#Bz;IxH5kkk zJDr{M;DyQSH2Q(ak;PUt2zsQk`%bL_#UsD#E9SxQz&S?In^HyOzWpX#6>vgaqP-&_ z28>jJ^Ke7+>U{9AY`uwaHhdn1!u)KC!prffuN(sdysH936BCXzx0Q-{g1#*dr-MSl z`1QRH^`62ISeK@9amw)cnAh8;YUN^uZwulGE$dSWq3@5@-pCCtd-ViJ)6vgRvGGjjJXcJB zZFMV}N;UO-{+#hSLiGDx{deyo$+(snPxubxZ03bnBG1|SQp?YwQHJMnc&^?Q+BGi} zc9Ta!S|Xk?_BhNn&TWs?25>RvO)wBSu5UM)&{PYXCHN+z>-f6IDIsO|Q?Z8}zyr?q z;QH7Cx?B_dPSC5!`ht3@ayU*Fx+`2(-w=Q!bb^k!RyVxSmF;Hb*}@0rh2E5uEm-1XTW0*QMP>4+Lc zn@&z_KUpU=(B$)LO>vf<3yvdC`dhzk>qr;!-)6uFLaGCDc`<*C$4h@l*lCQki2M9y z`g^E8_5tcgJ*f2h0{wC``Oj*Y=eB-D8X0t1oXPhyLYFG%ysM_@NOzAO0%A=kDMGfk z43Wp~0fubV1WzV?(+JT@cL_T~Fi^MQC$L#`KZ*V^tQN5YFm}!Oi}|QN?g8ra%SC78hfkoxWYd}}I98J@&fAaC|e zsu^O$Ss$w0s)*z$Rdqc^%$V~pJ6%RATa6MG#Ykemm1Ji#Bx+$2q2DW%oaTBc?p=8n zqJFYZ%s5i?B8VUUL6P}Nwh)`n(c~5(J!6&tn`r-;rXSP=a{7`$sr<6;7A;>L>SS1ldU|2iZ3X+r{9GlRPoB#^)v8pyATJGg>Is zVNM3`ty^0w5{$~we7xgrbXHa&@ftlGG)zW0DGaP^NML1hclG5@Q%C=Tqr(60^g!a&v6`X4>{+){TR_uO%Jj`XpW@}EFGxtH6}a)0noYbbX$=qUQrcgcG{y-6JChXI&GR@ z^_lFXg2^miCAfN6q!Z5v|32bBL{B$FA9>96K!$#YPQ@-=i+z;7%ZMb2{`A0MB(f{2EVh4e0b1=pFF;`AuZ$CPK!9tP(` ztaADB;JXq(Xs0MM4B+(-3X)^+cCgd>0EdZk$R6pX5GT4cT4JP@!=LBqfPMNt%m&q2A z<>g)(Qw=dv77IhSBKtw5jE5%;|6&;_B_TREiCp@w(MIm~?`ukdQQkXNE=EU&Q;l^= zhy#6IhDRpLSI}lNjn~d zY?#~0jvybPWq2PWG9qEbCJHl}T) zQk-aub!&Qh;luX!&Hksh8vRiJ^TLA?BWVa6=>Blmm5I7-*&o0!NP$vWv)Ldf=!xV? zKsFiIBBG3xEw09+~C)JXevTkMKzS!$-&>SQv0;~?5vn_pT{(gf}$nhTQ5+(Ac9bl9}eQ{ zp0gJmQ%0X$4Za#lB?t((X?^A&yMvH1SnK%0{xTw*f z+nMW5_twpxMx6;hb*F*YB0gjILAQGSnc(-k%D!r#ooy{2O>Iv}MU_jTh)c*$2#X}| zb#aVke`X+|XMX$`ne#C(?lZAye z2F}xTivzMJQI3cwFFnYqd4YRQ>Ga`=f^tN&jyRT`2_<%&h5ThG(F^*N#*-7{O zbCL$(>rEsCTwkjM@}J4H{T;UP|M4?-&FERAvZRoR!5uR`L{qRZWPWtx|8yF5mKe_w&`Nlm zD&bpWZ)bPMfO3>UlLnKua&Z0gS4X1j)AbP1*#I5;Xt8*8H_{m5eI6$-MgJ7p!TKJj zc&FdKg-C@-3{}hozxL-3wZe55LCDGa@y5Uf3e@+u`5Y>H6zV(_Cdexmy&@D2Q@Jw% zzrDu9clpBnhFn(@iOGupxR;kb@`oQxk(Gr@;y%e5UNt0e$ zcjH2nNu#BFed`y%LTca6+?EPLY|%4k4Er8jSFW?6CdA0I$^BDAC~RJChTAIkd`3#I8M#A0K3WjS-JpBm^X%5< zT(?bcmUIoJ0oB(JR1=c8Sk43moi;fcsH>ezcUwRcqNL7he7&{YZY__M$abeLf0LK(!_Tj zlVPsz>h3UaTq|vNqa#{-K6wcgrKv}#T@CDB$mKk%sCd7%IwfhvVHGUJkF3wtPqIIH zPK1l8IQ?;et<*|Y&*xAG&v%XEs3imzS0w|Pac1HI$C*NOnPM8#S1v%e;4P#EnB}4F zo+Q=5Qf0Vcn{}*&m!~rfo1qJ3^WnJ%|9wRw!Y>&ZyZvVvlo%+}IqKeusBNtoxn9$_E`>fkcOi}u#`u+Q>*k3l;AMHv?6 zYBApnnlr3Q#McvWw$+%GQY-sqTNcgAd_Gw|D46WfHx-;iHOmM1P7yse*$BEkWBAB*n*RY5(&g#zv z2MX5)8@(30K)0V(pyx$UtJerZO_spHkX*oNQ_1_5Nnq4TN0bF|OuHhVZOBUAOqk(q zYoVrFbzk6mmD;09aeMA@ZAxcttvM{8FsnwB@&5SnW%Btm8R-`wO7Y>-#z?*j1=ZF2 zJaq5t+YC7>LKJM3a9f$+>~3u!jVWlC;9Q+Qc9(!r>UiL5mTa86P>QR1_H4WX_|eah z+|eZMxNnV>PfkGox^g0Yp{SnxMHm5{GaSf1EspJi)^SNAy9Fp6G=yqXqVS|(7svvo zm(;e@S+Bo~pmAY1xwVqslBU+W*?$)E-fJDe2zh*P9nyV6;WN%6)C^e2c`CIa3>5W zf{Jn4kJ$iMznDQEPKF+t3~v|)ikKCyT*4<&?gOB&?W@RT$s;{-k;iC-(X~UX&~7=^ z;JG`;H2WhzwWqg9dfoWJf}+`DJ2`f4)jh6w#4hrN(VXL5a#B)Kw1mAggR1Qoe^{jW zc{?#wA7n{M76Ep%`Uw#b=ujFCkxCa=RPetL({_J=bH8kxIEY)LQN=iixObDGEA8ZH z`9>8xYsC;~6cx56NIpVsnI=iqLxIiHj^X6hi_6#3u!HU*Z#@x|rV3Q^MX%IsK{-S3 zNrh$dx$k!=_&ncqB(QmwY!mZvP17iUBVou=LW=!PP$?MKY9eo)!Q-H~F!?mX;+<7C zB^P)^0a5V}G&akWIfX+Ydmu2)lKp_pw~n*Rpj$ByEsaQR1E|k^a;c zWTp*rRl<fC_VmU()1pfxB*mY^iB#xEJPc>@8Xtd{zJJRJ=?)~Jb&MHDzu9yH< zdTqy0)(i9(osYYd?4hTeAe9bZciNY=%3P*Q#K81v zU(|pA52}j3fNoW6Xi&{}#C<#M0aso9ReKeca=G$wZriVJ-k1wZ!>*rIJr^b$>#M6e zRqh^Y+h=b{g@lr1`vJ z#f_{4X{xo!=?A4sp~h#oo^O1y{zB&Wyv?tjGfwk?GFOaJ-xaaj4Nn@EOLgcX(&?>P zMj!NaZf{4O)=d=Q%G9Cn{W>T%A-syJVlPn2VcqmO=xnrAIcxXg?LNvQ`P4>PahS*0 zl*3?E{+7`U8}(ywo{UnsK;Dw7Cf*YMN#LdrV_LwN3dPdpiI{C-%OiM;Abqs%4fQfBRx$Oe)) z&zdj?C$}ZqGi2=)$)O0dR7~sJkMPiN`<+S zX~6O9wO(B-*L=a(4c+IwCZ+Azm{3eIg}71BWyJDKt#rV_bzWO@r{{@D2Q+r_5~MC_&6nB}cHQbt()D@6wti65 z)|k*}A?+KxNDud^4!EIf?#${R2?D+cU;KQBNp$6@RY$zeDu)U+jxh3~@FA$y5C#Sk z{I;CC*@Y0`{FeQP!ITlP_`EDhEO^zj5~;jUJsPZQqfcS z2&@1CfHbi?aqq|Ge0tEa6Ee_HJAA633=#|4)Xmcc-VsRL1vQVV6JedYYP=52(9Ze@ ziVVU4nNU=y5nHK!b&683aLlrn_ULc#64h>xIdqp8K7~@qwYv>ficn3xj@*MJv%#-s zIyX>N@7A+|Pk;SBjgTEg1Np*r=m#ABvL*&r+KKCWc9^1RtZhg`qt#ylkDD4Z^rya} zf3kDkEIA++-jGHg!v`<_clD$+At}nrtK}68LeR(Z;qlJ}T_(ldKs!B*H|Fl|cly23 zP)-Xmn)DUHUiMwcPksyim0m59&;^N=+G%Y~f#Re6K)xK>{g7imHFwp0-27{Q)#lg! z&Z^xNNE|K#Nv+$UJms-Jn|JtO5yTeqlnkwL8=#wF1Gu1t@8bw`BJ9*zES}%Hi~%=f zR%7F#ycGsdegxs2WY|XIr#AQSAB(!qDE5zxoLT+AQA&t13)uH~I&9|aQT44L-TD0G z@Y6i9RVgdR& zOW)^_&JJAKr|FNL!c{%+Sh?He3qd|DWLr*fYaN7g>|Lh&8S9OxV*57#=ypjXQ5VTR z=kzH1&xyz(ws_H8D4|h5O^>t+zh~#?V<&h}SDiFzL!d8a{y(f$J_41DFk7a(c94Cq z`|lr<;>WQ&*_|U7wX~gz6ajMIR}o|JBdO7I0=CXKvh^*k?BdNYx3~~C*g239=RJp? zcKY87+k=F(QXx`0SfXo2C(OAxM7oO}J)o>s+s#82DV(cJmxM`@~3T8qYdj< z`U7xP56bYgsgB+qIW&29z`e+2#?2Q~-&%Vy2dW`YopN4oa;ow{AMIae$qqoWw)R5Y zAVjue59DR4cGCE-9k<;W3=tIuDB;loZ08J;LQeP7vBrg>9feC9M4N8~-i_dy0wBv~ zpipa}h+63AnoQ6!%<4)eoVfb@C6^~)|Osiey(+n^94M{PCHy_*uxl=)qgsv(b0AY-)>SD`P z?z*vKhYkiFmQW0HF0O(pzvVD9{hvA}w#?-#)6CbwV$u+u4{~o%-bvT+`+DUDxrX7< zn&ia>ZoZ|26z~171h9{f5SETXnx*F8z{S>i!nQNf8mHZ3JA&=OlYqLV%C5I(Z8I?0 zjuswI$^zmOq*#b;$DtM?)c}8O)bK2~Du?*YpMr(c0nmPQ0|Y`>hqQ|7-&@fHyW4c9 zmi{yr+XJs0!)MN!Jj!JRu0ixij^p>j%z_b~IV;3)9i)=d6llF)Pdb2fs?E|!g-{*e zzjrK9iX1*#IpT1(WD`(S-Oy{lV!X)*l@`)!+VFq_+uaqB!IP|cnh(+8WgJ3o;iQmm^2wX5oCZwENW$-W9nc!_;Y8K zZn2xAL5;S~q)gmpK9l2SKC9(f{ zNy;0wbc{gUV%!&o>Qg}vrTIVhef{KtsD=kr-sD=P>KO}FE(z>>@O$lA+ z%hVvuX5E=(Jv!8gd9*Xatw8R}6YMcGYQH)E?wQc9C0j`c<_WmE{{48~$m9L4Y|x!z zAWUlk5iv9Z$VfL2l0%y3A-qw4uN$l2K*me&GR20!q&$EYw4+X%kqkYO%8daU^KFCo z=Bat}yu3H(jqrt|b^K^GbI{LYpbd34+x%vQm(@OXQN&lf3FX%06`Q%9N zwjk~Sfl`g?Arvk0WwFp&`@LctY9B%5ObEme89%!<)u#@z$igkW@MLjlNDr@4T{bI^xMKSj=4-uk;UUaMdJro$I^GHK&{q$SqZ?oI%I|})T@=R4# zl~w-N0g``v2_b+#KEAkNIk|>hn&$go^_`{>C8+fBTeDoPDCx&X{u9|$cv2Z23})U4 zb*XSu^@o=}kh=r2(eqBt7nUnnM+eQGwRdt7k(W)LgrS|G4|f>P5C)C+;p7uXbD}_Te_J} z5YRdT7&l>as81Z{HPZZFc;X=Ug^J%&R>A9=*JCMrIr{4m)~3$Q*^KMdy*Go*O3v z?^^z2AM;4xhhB!BGYBaifg0y9xmzd4qcb#t|A%2pVcL_X$S=UXe*qrNRBff}-}_D< zD+hrc_qNgT#XZ0^_hxtu8P?1}fDvDJ@N-dM1h4qizaxb)=m`vlxqVu#1i$LrTipjY zk)3nxr?8g-nE$e33=}63j7+%a+yXz1%l=XXPfhBY9bD5Fe&MoZSTsTK6ZT&-&bibB zI&y+SLPX#AsZ8a0t{^r6_0;aS>B8@>AIL@e@C5661N*5{l|nwE5l7|Hz#m+i)p=wM zI+p|828y#=s|iQqknL=72vem-`5$aP9H(bghUiX67!=*8TeXiL9UczW7V-0~nU@E( zkrY(zPknT2d3+d7L4K38&bdq!^zUtV3OIxW1yca#^5|*K0Nx*K2pYku_0BV)OHWU~ z#+7`VUK0gzo)fs}ZCP)%vWr?xIF}hyFCehQs%wh&;IijHWJ!Ha{yyHH^^_{cX#nBz z*B2FaV>DAs5ICVqD3X~bD(CIWx4f}9%PQ-;@;XT zr|y_bKkX1AE1M@|I%kj82#v!Y+y3Xe#%0&W7by#Ekwh+QIX_2xdwwQ`Xu*5;?nwnp zv17fH{MB%ACib%9!)sODK9pf? zql+&c(U+?61pJ)M!QPKhdolb!7cOZc7<`FA#miG?&%fSU`A}bY#!eU|gM{Xsi6pa^ zD_9c3TYwYGW_!}tWj7sy_jK%&qr#F&=c8A6ODJnKgLb7_n^s&yk!U z0dpT4AHS$|Y3DM-kK?rNz0w!Xbzcpqu>pp&vKg0lnxnNXvgb(z~B_6oL|-#Pp1&d?Vg^J3$6d9<0{X zce&aIG}g(x3e?i^!oug;l%%9(A9&B5b!%q`PXRbJTTc$h$)ocKXa<>5xTXtAOL;N+7MyT}R3w5hj~!2e%3~Tbx-j9p+E`T1NA|~qOVLvX0mv@Zdvh)o zBwSN&Ot;B#-JKw0KZBeOlG$1FlFO0nJiH@c?$p&maGd82_njI*G2ViH;C_nABawg1 z7!zkE92`}b#ua;|MqFy&rHVPwKa(vStY@l~JUaJ~)_;X4T6;=vv@k2@BIiugtzNRQ zW|Kbo&k&`*qz25$9IVm!0&yb0_lA`K2o*sHk#aBWipsx#i5c2wNf-l+9>mf{MNhF7m2wPK835yW0>GfDwo|uqI!@teKH#GYrnfQk;{|a5mJtA&*wI9 zd&eHV9Q_H@#7<*TQHP+g@O+k>ASPBdQna6F%9hw3c_j`^rqz$ndUjG{KGRSmGq1Gj zP?wgIzei~e$GjWK$5)zv9Yk;2S1&`MrScbVGM^iL;kl!YOTsu|CIGU052P%z3ydAd zsyOyC+YNEBBEQu7?cPM37}Lpg;Y|OZ3pRl7u$l7P5h4&@lX~+I3R9(nNtXvt^2^%& zE=BUiw{yKq4@0JN-~J`%c!PTv)H8{@ylw3$ud z*S-hCQ%m0yrY37lj^*C?y^2B9B)zom`**2?%RaA5Ty(yq7A(aKmZz5AB~)rc+N|iw z>c)#(n?;YF00nWxIu*pMt#@A#_*)M#+SIuSvhs-h`)bPpbSluSY}e|nrCG>*v5 z8*Q$Vam@y(3>bE$5tEOj+g*8%Rt1i;7UX%6ef>g?kK6(Vcp7bsGeL=Ud#{SXADBhi zB!5Jd#<}@&S2qnlc|P%<-zY+Q{HDoP%`&2WSAk@;h5@>c75)p#$P@*_aVi>;wj+u) zXw^JrkNK}3yajpfdPN>H!I5E8u2!6;Fu5L72ZV`Y{`1@}sN$<%{@$+eJ{Ag)gQRiO zrCle{4EaQIKXBZ)VDZDKo#@gAfT~w;Uaf9dcBk+MzZwX>JuCX#&ZNR{kjQQVB5N-IK;&`3)k`(pHHo4} z)fUYMEl;k#dK-pM)%l@0V+u!!;|qk^Id8>8_Ia7*_Ui*W_4i;8lVdbvJy%cTsFqjOv?2Zz!KS4Y7pc z5(gIRrM*kGLN{YIY`JN5wCNqy9?Dy^lB6>C4(OzGFCl`z#PdBiNOHN~A4I;tWN{fRUH65rZ zeqEJ1EdYpQ-`CPCK?NPPA*m>%2W+#VGe)N-zm<883JfZW5%(77wncE4@!CtKUvd_u z4gPZ~+9@$lH}n|AXiW(c;cyS=EI=}mU$jzG9#vuo1(yrVe)ifk(uN$?LLACc5ip)G zF>!0Ny8y0(gV;`z*hID4-HVh(6^t*EY#H8p{XU_4MAzqwzSi>%BN-@R29l^&*~O(I z=vi^ECon;yz7~JdKi@>YwOh`{U4*%pxu-3frYo=hS*%D#O>`?#Czmo z@3s6nUyAsc^Pk@}unC#U$el+LpCTS&nhY_r2K`nCKnsc0iK2gv3Jsea>-xxkG9bUL z4+vXDU#FQcP;eWxoZ;MS$M~Cjd9x8J7S7VhWGpAt=gJxtv8a(NMF^Su5UQm z*WSJiJ$X{`HtUg>!U(d2Y_N6Y9j{EmGsR^NMoaU%u_sOLPtb=G&`nBPKx@JV>M+=> zGW~yx0#g1E%~*alc1lX@$`$5VI)HNQwdcoLrCLVZzLNq0FJxJ6O$^75{Y^J!VgbTc zka%l3>S}=QEKyb<0n7-|P_SQbue9!R6|u6@Zp6L&JL~V$3*N+E1e^-p;a`g~(Yr7? z;l3vlfZ62}234yU?#^Xf#c{=ZGgp#T(?kQ zRxCkR=e=wE9RpKh0V2La>&a-jIld5NFwF>*d9{h_bOW!XBddCb9XX%b#JWPLhV9@T z1#Ts*$@%yeMy2=y$3xq^BZKq^sz!;>TI})93Q<@mg$yHT1NPQ)T#HAXL)GbkZv4#@ zw6C4@%FXcEaF~^|28wGSz3vAxPT5tZPk-Da8dt>AuR*ey<;^!j91E=k!uMYrxn*Vf zCcNA4%lj~QGR5eY;;?_7hN{=nGLFd=uCEjSBoYH*f#q_g7Y5r`Ofy!ijRJ*u>i1Jx z(~^zcZm9KG@@d=tbt9S&pl0*3ojsHNnpzY_LP<7`*N#G^@Oe_1^G8uQMvx8!g>qk# z{={n|#7_$3FqDRRQ6@TiWLdp$z=@qSB|rOj*I{`7GT@-H`5JcnN0>-4nGG+KtQmQn z4bJ9|C;Ge7c?dK{Ci&K9l85I2S5wVG*v*cmSSinV&Y}h5smG$;E5q=(bMe2EOJe#g z_EsukXF*ZrFtB(XWbVhl)qi8A11XQz>LxzD$O_`v-&kBuL5>7NUqq zGmqD_MeXp-varCz*w{(Yi^DCd_ROOCKr(B%#PAw`LYxAm3B%Wp#b&(6^`gKB6t1`S z?>zLiLQCDeu#gZ`h~~cI6)@wF27(uHd;HDd-c4$Jv+TB+S_}>4&h#&O+-IXWR@sY@ zEGx?bMap38#wy3M0$1h>BMmnO!h7&%SJuaH#voI%^XxQq247TZ6|n%*AU#HkZj~@> zn3O-6Q}+Atz?ZZ<1Us5DS6we#!xJ)*i5mW8@30O-vQ9cYCMtbH0t5dXmJo=vPQK}` zrRPF!>ln!cuXgSB<3V0HwYiKCORWL)^yuEzbb(7JR^np_rSFam7PIjm*!a1BKH!Ob z!1QCt*c~FKw_xp;lVmR7yuNG!p1}s7sI`~cf)lj=<_c0DkX95}cmd>OvWx5P$t397 zv_Zd9SAqhFEyT~CI{YL|U_h9BZ!S)>^G;!m{Sw31`!*0Db%)Nc4n9sceC}?aHm=?O zoS(mp!`XT6a^QM9;bCtmNRaqT|D%}E8Ye1RI{PK+ulIeBKU2dPB+j8acqEy6=8?Z6 zMe*&sZ)7}#?;%Ni>{+ap?`Ong&-YvF2+AS0n?toS;-Gr>ieO|BURliD-yw)13#R9- zw|CD9sKTr`=b~ah!qNe8b+{=~oNoVC0Zrx7uH$4w z>b|}GGWFL)H2e|IV0HPm*_1QGM3f=YPKaFjxgEY9_4BSr%b z(!UlofS{_GeL{>BuUn~v!2c#HAw4QLVW7Suux?@r_=HF$iwv9(96h{$Is+carboaO z5i#}X5t93`5+Egug~wb8=GPBk+&e6BG+4i}O@V3;#78e#0QjVpNhiA%M<`4t4PyJg z0jdG)!zZE+f_`@zk8#bJmzx5t^qLajecOVDXR{dxis>9@6cKa3Sabh(2=EE_`bQ71 zn={B$&zu1y{oxDJ4-mgl{@orWjB5!xL2FmzGUfaSzeQ0YSa~_i0IBu^sO;^R_qj)5 zZ^ak)KBExI%M5A|``drT|B7|Eg3&D-vt8W~Rlh}Q570frfcCNu61D1T>1FfE6_OR# zUzsupG5T762k&nc1kg|P1H~`DJ%pJRh8J->L~x*GpJ=lmU7Li3R8V?R+=65Nu{{X~ zpxg4lo5rc_672u%ja1f6co+slrU9ATOva2bQ*w>Zp3&>yyN96jm|g$R-GefagNutW zGCn5ZvsGv;*MIX`h|!o&-pDrq*Vq5Dmw-nCuA1IkN}Gx_Ufts7OB-by`w%jNKhyK0 z;13TWg~|?MXfwVLBd0hQh>y7qD_=M4G_DGT)7(t?5%6pE*Wvtkb*XIRYM7?Vjd@KW z#GbKPq2GnQax0DYu$_8a))Q>_$_&+9J_dY~ueR-XQ)thLO}HcT{wHYMV}GpvI&g9O zk{v$w^Z+6IZy|$f&G6eK9^<>RA0PhOv)zQM$OnLEPTl%=j1I>{-iTNB5OIFuaBaPi zP9p&!4pN=1uBk~&N+RzEq}?V|M#G!0^tcw77B>F;`gkr;-;5t&uF%%-2PmezxKNK( z9ZxcIAyQ=?YrPHl*~CVh=KXB}5?0l7(0O$oz1a-4ZKT>F2vy6%9}5}*Xh`P$H=(_^ ztTP04A3J8Or}qibhF^KUBKDId0+j-L0J-1fzkf7AVdnJ-8;MQ(0shwC+e_FmlVP4J z58<&JpA7JOh@Q`s6fGq|18n?9HcvOA`Z4T$AZyKMmLX3!YIR0tm3?NAF$L525 ze)EF3LJ^@zEi3dS#R^J|H`o^fG#PqSmf@IxB<`%;S;o8S!DT>ThIhQ z>^$rp>@*9%q4h0^!`SP8cudM@DCPQan{ zfwh*fFL5_6ny#MzwJG`QN^+yyu@k4OoHGF9wyF5Y`R}C#vuGhk*Y(6qQpvLm{PZ5~ zFWHL8sz9r9)NkiQcXIQdweb`}hk&Hr4914(j?h%AEQ>)>;cj5JaQZ-1ZM#IX>J_f# zdmNu~K#Rz*x{7Z(m~JoY2T+1kUcpZE9C>o}ke;JDuSj)&7hn&Sn z!v?PkLty1^Y5xfbnb~eDO4+w;>lyNrbD#`U#T)3Xp|8kn{Z#2(htryxi_aAW+17NIrcvnhnU5~` zM3e*F#s>u6G1REF+oqf=f_6!Hoh+MSLfok2+cv;A_OPJ&*Jq06Cp#W8PCvI6=1QLS za2ji1Q^u*}g-nAFE~P36NmE%#!K>4QLVW8D#>jl`5F_q09RGA1^1{F=TIuIW7y1EF z&Qs?YSL}gb$puIe#ez{ZK()+=*Pd<&f!~xm6MOUCqrTXOhcp3n@))}kgyUyo0`{)e z^A!s|&nrtv&&~<+Nw^)VNSNt8ms$WblSr&MG^jP4>E5R_2c?14Dh1{?lYJ|t36EjZ zfae8g_E%KqvkX4J1(gd80d+H24-}~%fa;jE=I|Cw?5f>xgE|z_ zaaL@>u6K2d3LLFHg+=(C?a!tDMu{>c?R21?j>2*(rKr1I7Un**&)?(muw;s{3QObi z;L<1Ne~D8jwm?X)-a;^V*W@_abF;X!iOeG`UPxo#eF9jgefTFJH{vWdxDVK5VzqEQI+EGmkYZrA9hl%MOP$yho%WXL}k9t z-fmcc*Xzkhzy_dLc~!V`S7d5Uh^C5hj3(XTTM#0lJ2iyv$klz*o)FDz^ttxNv?wac z+|8u1noiX@4(^h1hAu?EinsP77FRKIJM+LpAx|+33_2_&S!o@s7e8nD0!D9Sq6UGc z$?+EtKkMRsl5?&uvDn=#zD-5_tqIuOi;+cH^dR3-jGtS+?+yi|t!4xmaBi3P ze$&L6*_QM z3AO0f2mHh#^iM5_9x{*aAF3=cJ32sGI1OI9N=R&X>FIJ)3Bu=+x!pwK`S4)tQP=UU z6yTGon~7JsNr+Cw8}JvvrNy3#HO|Z7>@+F}E}Z4$!pv{H#;cU!_wBK{&>J{rr{y}A zH$q6%pO820t~O5{s0C?TEoRb-;ppJb)=q4oyTJNq%wu%F0DViyU51akbNc^cP!-qRG+_}$@wNSAHSSVo#p zF<6u2XZ_0a$JbV~Zbu>s{_(}wUajxGnF`xM1h-n2s)x;L9yxBea_t8oka$Z#6agw;~_fIY(0+HhN32h?P*SeEOkcch?C(rjDoOG0y|5Y7rk(_wvgk zCGfn&W2@+iMlfdz&zT&Xl`oRGny+NJ4sd#*-IaQmHxFkb7fNFevYrRbi%szd0FjQ^ z>5c8A{OyH3VQkFz-q$CCpIZNjXHhT968&!E9HU+vy5QQJOZf8sSzFo=qYS~ntvs0R zgULo7D>|6$PrPvXWw%RnTF>bOyZGLs8R0TlcXh*s7yXGVY{@FPVsfrJ@p9@xO6~*^ z3WmQXrl5#_slLNNiCof@OXcD1$o599UwSPBp}Ufxn^r>B&BxIj(Q`YYEAJ%v#@EN? zX-L>nW8xVSXnrw2AOLBXA}WGAeIBcmjblp@<}sQo)cpU#8Vf-o?PP@5GCbZ>%Z>ug zy~-!{1Sa`;Qp}>UWA(Obw^hA?2+K36o3#S?g!VfkFPc80i%>Kze+Vi;JXM5I`JX(v zQQ3M5-zO;l=61|T8#qBFy#xn>f5j}kQEt!`p*dcE=?xBYejd-RwXTU16{%y!Dc zL}gD8cd+%J`NH4PG_!`3F{@yV&WzPuT*v0z=^qFyRMos9=2@7TBB=irvBif4Q*_ob zL~+OA+zM`CdHgPVYGbWrX!K}ZbCk+D%$9M9$r_;t`gJw7pBkq+CxgueU1?hr0dxOhZP>$dadIMA?;!gfJ;ggvoBKWgkmXgDk@& zkE~IMvPD_5H}>_(77`lD7Eg!>N!gd*{l%2$cfId*J?}qne{{L#`fm5R&wcK5KIe1J zZ3nW}Q1x$|lDZB4i}|(AYT$ryBJ2PsK~4KQ_Q0koz5&0LIst8_N3H3Wc>%^$yGanB zqx^vbt>-?`&fQP~eF!X#VA3Cj9=)Z7{(C(CQZ%aGmg3WKWG2JAmS*O#vy94B|^XT-PF5CntHj?l;G)Na#_ z-QtSb%eBg3BS4N1EYx0aI?BidkZTOEQPF^4NdXKJFT0Q9?m=eF|BA*zU<%c@fg({_ zYS^0%s%t?v=6-6aS5WetH*gvU*Pf8Ok5CG_Ehq) zDCE6B5JUujkuMdYe;QqW{LL*t(7|Y0UYPk8T;U2PdXKaq5dLP|yiJ{!*v8ZX`~4Jm zK!kYE9){xqnH3LcyHJK|vuy7i+~DlJ0KVtH=Mt()_Wz3bU!&xm7)MQLBRB^s1_1N? zF3dZy4rKaaz$VTHH1S(A9|r)!p5iL0wiFNA9DvP6_x`Lw-oCU_NVcaG%{!l6Ix~?1 zyan#q2#u7-8PL&eY2MEd`FV-`G*P0{#_WjM^}OGu zstY+NdS}+vmB{y(itO3FjXD9XdU_!MLRg^S?J+1Lv`PC!VS@=l^zr|SPs8sBr=>8$ zuVYjcu)#hoF=w5Vq0r`P{R5UA@DhZDjHblS7GHbwSkf8@hD)4F0jJ7zeuy=3@vdRH ztC*q~T(;o%Y)Akg*#9fL0L9YI7{G4ZI3b`IH#+ncf%ZGh8md%QHVupbxPyCo=rq!W zWC2>Jc+|)N-fukx7%wq^`O>I&obDIE46J(qu^f8y*K$5x zso@gs?+}q4EN+&vS_B#J;gGKdVJZd6d_&}EUP^NQQK?N^QKyCu4m2uuk_0`Q0*lR6 z{m`^vsgObMfWB|5y}^=%2?~q{@$q8+n>&S{nnxJi-^yG}Kh_xgU<>B;07b7qf$JT} zZ7L`4!Um;%wi{7!upTGMhH>ytv9Er)bZIVN?;&f@MaJA7A{|5MeIz9WzbPwp2Lx|* zsL)K^R|F!ytv|_vmrYJMN@w4<&+TgcV*tBoBNn$#(9jC!8vWMpzS4h#<^45 z$(Bz?0fM@XFUBcpbHH67(@=`0lk=RH0F4k^OF%;_D4+aTxNbWUinuN%|8 zZOVI2vd}ibi;VTH(l#n`*koS;CpXxbn+~0X0Wcaa!d$0MFIRHc;3WQwvo{xfJGbEw zjNdAHc4kxCNjf5c+MD1H0Iguk>j-H8W$z=5m+qj&5KLTW+jDe;SuoF{M@kQDP5~qZ z3{-K%Yi84d)oBHM6J^oRuTV#=$@z5Sl0kZ##;D(OIt9(Cr)@{F()=P!^dQUm2bFkO zigM^FfDE58+fHtGS%uU7+8)t7@!+15KU%0DAt036a2z-0yb#DnOKL;7GnZON_;zdo zfzXS-tAPDfd!!Nc19Fkq_FrG%zFH%#x8#ZG{J@(lNu>nYz2GNo#`L5+tTFQ5Wdmy2 z-&QYri!PccEp3*AIE|VrIsz%`4kj`D0s5X(3r6l*ziW_T5hSNNpHYvOxzo1=rKZ6_ zveW@U5tg|}hS>e+w(^}^?uVH&r7kangL*Clm%`6#L>R!5=wR5Z0Opx{Kki9pGrAjZ z;kc5=hD;0qM~F>Mss-wo_IYpgd7aYc%4rixEjXq!TzqzHMCj6$({1uA4u#k1gTfA8 zRad(*hGpM0Ngo1z`x@W!p7GnY^Odq|2O@%x+TYBVpm?X&byfjVF%AO<3?&0Rzf+d$^Kva&M8FzB26+#4yr&hM0t zms_wktxG^=LezQvlMf1&zc6@hun0@vX2jhS$+35U$s*wH1?hj?D&5!Rm ziHsLTx%P!wwb0}o9@>Sit~tFC@`d%p>o=tUL0vyJoE{$c$n3$*wvD3;NA>E%)?1(O zXnV1wd%TB*l5k91KvkY7u=Mu#f0aqGlNUGj4@t8JzsX)@cnb=YEI}e`PIW}WjBBI2 z@;EwJ|L|~?k*R6wMPC|P7`#E1XSvAV-@l?YdJL7NotBq&G3g{$B=^i1|K!vQf2(ss zJ%fWAnu@cBiVWI(oSjd~`m9%^@mHR_|EA+)3ukUa1A%2wSw!J{FpU^&$$c4b)tE2+ zoKY2e_%T{kg{w4jTs;E?m4C*5-y`-2qgw2R%X3RV-`;u4Fm51xrGtPoTh zZZnxiS_ShIJ`#hyTP*RYF5>+#rSB1;;Vu>1ILWQV(`|{WHH_|_0>u5Fq?GF%Fhc$%1yH(UhK*A2w;dk%eZR*2SXBf^8NfY{F7~OHxikQPFludbg zc|$m>J5kpz57K5!l-a}kgK610Is1wvv;?TbhXz0r6~Yd0X)Sd`uUL`kd*9+Teh-lW zi2(yYcCsh%w=8I3|K_?RZBj}~idR=7AgH)`q^}_^SE99&TtO`n7yjnWn-jG(R53D0 z>;VuyzYz}C?AG7Y^BSaZA2S#1riBSWBUrNVcRHoNZ+oP^=pbKa(=@@J0CXiZ@-ie6` z9g6-j#1CyC^5E8w)jo-1LYPT`%9m7$KzCpvO{?YmhwT1FFi`%q5fj*<4Gc%YZx3R= z?i4BMf4=T09X|iNg+pOs;ibUd-;%BA?Zt)Vk;!y^G^BlW2X{%f%()5T-Kg&%weHR} zfp3kh-?EZc_AymGLLv2V@9rv1gw#V;R<@_V-&kSp5y!6~!x`(`+)tR4MZW*~?OXeT zyTCWDtWIz^Tu zOs{tcm6QSLDx`d3qM{?>9IUZrlNbCEzm^A*lZ3WN;;;&Oj~dP=v!hgQ{Ao!wG+<~o z6a>&G?X={-cFqasQ(v^>-Ngcas%*fO=qO+G8^ZZ*8^zP^Mgl&Cm8YlY(pbE;jm=6z z6&!K74BXfGHgB0_TWZQY;tC3hxz0!uM2S$w!VLFwUMGdY$Y6DU1e4|8ZNp zFi;fr-!s629*P93TcZbYg^N1BXBq3>T7pjA5eL>l-AqqwYwKCP3$ci}gS4dH3~6>o z#cerrnvoKT%R-*thR&Ok;^X5ToSdAzL{diJ8YJ|463z?7r$?%An@Kn{%NB=GqUvgh zmN}6q4{1+ZqC%n^;Gjn;MM#kXk>fI0k*X|LQ0V`4XsBj*DzJo0=g#)ZYmcv4UiK&| zE`9_G24m}H!rHIE*ZJBBN#N?jhYR7=04x-B(l|sl3!At7I1Vo0Fa*y3isffZXXpHd zPRu`+GQ1!GCQ1CKe0*q0xDEB^80vm!Kw4Z<6BTqDZI1d1Feg?cO?EzUJc$Iy&mIm1 zSz(d#8-M?mJ}KbyYa-n&!3f*ec}~&7=au&Hs>MX*!Ze6HWp`xSCxxy`HTrPuuzrl z>Yj@{^Q%jM_tjTy=tZ=%wzmGD6po^WZ7?#4V(s@6!JKkbTLoLK0e7kYWqI}Qg^*MO z*#+>rGteB~EWJIKTCYeyE@lT)hw&jO$wv$f4W)(pz6Crd7G^Su=kD*J_X+J^2n$`U(eqHsqN9`c$23Qa*p) zyJfhL(+y1hA1a|;x=-^S@{2z}izPgBbZ{8itL#7k%7!ifkoF;WbpyB%Q8OxLpqGq~ zC8`f()e`{vIqo;dq1N&dz$zne-CSLT52c)_UOnZxwoK@AX<)?UUv`urg8jRNH#<|G zu4?J?6VZd+wmcTmcmm<4pUc|PSmF|1^~$pfyf_P4KSzGAGRJJZ!jFuZk5$WH0-@N%Y_2nR)I!eD`N*4U!j z)lMlk7!mCHkooE?s12$Jo9$~ad#{TVP{^zZiZU9W>COK5_>^;}9d4@G^jVh#Lfhb_ zTGkCm)vR<2h0Y0^QVn~YkZH!4Gt!RzAyNIkcln%2WYz##yK1^`)Uf~l)HFHLl{Y8A zRxLR+tSTkvO;2Cnie_TBni1!k?Tc?*eZY2!tc2ZI9DQV_Q8H=zT+TwGWvo_=xHT`La9!6Q>Fb1?vxs}w8y)ba zv$ONHc5c~8oz<_;98fD!jo2$~nd|Znyw_O=q8{Bz+{6SLl5ohWiA=EDhCa%K|mvFvUaJv#4>yyK#xaXNA`WC6_tuNwu!#okI| z9XZA*K%ab_PuNrRGF7)rP-TpJFERglbXE>&Ce>JXKHHQ)>t?SKsg+|o5rfN#wC8PY zG3}_GnVu%zP=98eH4vTURA50Qu3I9pHiNjFve#iQxQtyv&d2pl4jWZ!O&C1Vo2(pA z!wHQ}xSF30af#~dVt{25S>rvjqXm{GrW?PbWt_TWXtHoWbK>+auX1s76K`BkOVzCk zm}rjb{QR{U2O(*7snstkH9B(x%l}_lX1<@~p#nP6gdoC(d*e6o1Gg$0< z7W41d_^RA1C;~^i9T|bJvnj5t(%y2(0R(uE{xJqprNY zxiLR7@Hd+YFFZ3J_HuA6IG!^MnJ=Aq)p(`RHf7k(C#Kn!LoZe3adD %s`, jsonStr, "/temp-proposal.json"), - ).CombinedOutput() + cmd := tr.target.ExecCommand( + "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/temp-proposal.json")) + bz, err = cmd.CombinedOutput() + if verbose { + log.Println("submitConsumerAdditionProposal cmd: ", cmd.String()) + } + if err != nil { log.Fatal(err, "\n", string(bz)) } // CONSUMER ADDITION PROPOSAL - cmd := tr.target.ExecCommand( + cmd = tr.target.ExecCommand( tr.testConfig.chainConfigs[action.Chain].BinaryName, "tx", "gov", "submit-legacy-proposal", "consumer-addition", "/temp-proposal.json", `--from`, `validator`+fmt.Sprint(action.From), @@ -390,6 +404,83 @@ func (tr Chain) submitConsumerRemovalProposal( tr.waitBlocks(ChainID("provi"), 2, 20*time.Second) } +type SubmitConsumerModificationProposalAction struct { + Chain ChainID + From ValidatorID + Deposit uint + ConsumerChain ChainID + TopN uint32 + ValidatorsPowerCap uint32 + ValidatorSetCap uint32 + Allowlist []string + Denylist []string +} + +func (tr Chain) submitConsumerModificationProposal( + action SubmitConsumerModificationProposalAction, + verbose bool, +) { + prop := client.ConsumerModificationProposalJSON{ + Title: "Propose the modification of the PSS parameters of a chain", + Summary: "summary of a modification proposal", + ChainId: string(tr.testConfig.chainConfigs[action.ConsumerChain].ChainId), + Deposit: fmt.Sprint(action.Deposit) + `stake`, + TopN: action.TopN, + ValidatorsPowerCap: action.ValidatorsPowerCap, + ValidatorSetCap: action.ValidatorSetCap, + Allowlist: action.Allowlist, + Denylist: action.Denylist, + } + + bz, err := json.Marshal(prop) + if err != nil { + log.Fatal(err) + } + + jsonStr := string(bz) + if strings.Contains(jsonStr, "'") { + log.Fatal("prop json contains single quote") + } + + //#nosec G204 -- bypass unsafe quoting warning (no production code) + bz, err = tr.target.ExecCommand( + "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/temp-proposal.json"), + ).CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + // CONSUMER MODIFICATION PROPOSAL + cmd := tr.target.ExecCommand( + tr.testConfig.chainConfigs[action.Chain].BinaryName, + "tx", "gov", "submit-legacy-proposal", "consumer-modification", "/temp-proposal.json", + `--from`, `validator`+fmt.Sprint(action.From), + `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), + `--home`, tr.getValidatorHome(action.Chain, action.From), + `--gas`, `900000`, + `--node`, tr.getValidatorNode(action.Chain, action.From), + `--keyring-backend`, `test`, + `-y`, + ) + if verbose { + log.Println("submitConsumerModificationProposal cmd: ", cmd.String()) + log.Println("submitConsumerModificationProposal json: ", jsonStr) + } + + bz, err = cmd.CombinedOutput() + + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + if verbose { + log.Println("submitConsumerModificationProposal output: ", string(bz)) + } + + // wait for inclusion in a block -> '--broadcast-mode block' is deprecated + tr.waitBlocks(ChainID("provi"), 2, 10*time.Second) +} + type SubmitEnableTransfersProposalAction struct { Chain ChainID From ValidatorID @@ -401,7 +492,7 @@ func (tr Chain) submitEnableTransfersProposalAction( action SubmitEnableTransfersProposalAction, verbose bool, ) { - // gov signed addres got by checking the gov module acc address in the test container + // gov signed address got by checking the gov module acc address in the test container // interchain-security-cdd q auth module-account gov --node tcp://7.7.9.253:26658 template := ` { @@ -1439,7 +1530,6 @@ func (tr Chain) delegateTokens( "tx", "staking", "delegate", validatorAddress, fmt.Sprint(action.Amount)+`stake`, - `--from`, `validator`+fmt.Sprint(action.From), `--chain-id`, string(tr.testConfig.chainConfigs[action.Chain].ChainId), `--home`, tr.getValidatorHome(action.Chain, action.From), @@ -2234,6 +2324,109 @@ func (tr Chain) startConsumerEvidenceDetector( tr.waitBlocks("provi", 10, 2*time.Minute) } +type OptInAction struct { + Chain ChainID + Validator ValidatorID +} + +func (tr Chain) optIn(action OptInAction, target ExecutionTarget, verbose bool) { + // Note: to get error response reported back from this command '--gas auto' needs to be set. + gas := "auto" + // Unfortunately, --gas auto does not work with CometMock. so when using CometMock, just use --gas 9000000 then + if tr.testConfig.useCometmock { + gas = "9000000" + } + + // Use: "opt-in [consumer-chain-id] [consumer-pubkey]", + optIn := fmt.Sprintf( + `%s tx provider opt-in %s --from validator%s --chain-id %s --home %s --node %s --gas %s --keyring-backend test -y -o json`, + tr.testConfig.chainConfigs[ChainID("provi")].BinaryName, + string(tr.testConfig.chainConfigs[action.Chain].ChainId), + action.Validator, + tr.testConfig.chainConfigs[ChainID("provi")].ChainId, + tr.getValidatorHome(ChainID("provi"), action.Validator), + tr.getValidatorNode(ChainID("provi"), action.Validator), + gas, + ) + + cmd := target.ExecCommand( + "/bin/bash", "-c", + optIn, + ) + + if verbose { + fmt.Println("optIn cmd:", cmd.String()) + } + + bz, err := cmd.CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + if !tr.testConfig.useCometmock { // error report only works with --gas auto, which does not work with CometMock, so ignore + if err != nil && verbose { + fmt.Printf("got error during opt in | err: %s | output: %s \n", err, string(bz)) + } + } + + // wait for inclusion in a block -> '--broadcast-mode block' is deprecated + tr.waitBlocks(ChainID("provi"), 2, 30*time.Second) +} + +type OptOutAction struct { + Chain ChainID + Validator ValidatorID + ExpectError bool +} + +func (tr Chain) optOut(action OptOutAction, target ExecutionTarget, verbose bool) { + // Note: to get error response reported back from this command '--gas auto' needs to be set. + gas := "auto" + // Unfortunately, --gas auto does not work with CometMock. so when using CometMock, just use --gas 9000000 then + if tr.testConfig.useCometmock { + gas = "9000000" + } + + // Use: "opt-out [consumer-chain-id]", + optIn := fmt.Sprintf( + `%s tx provider opt-out %s --from validator%s --chain-id %s --home %s --node %s --gas %s --keyring-backend test -y -o json`, + tr.testConfig.chainConfigs[ChainID("provi")].BinaryName, + string(tr.testConfig.chainConfigs[action.Chain].ChainId), + action.Validator, + tr.testConfig.chainConfigs[ChainID("provi")].ChainId, + tr.getValidatorHome(ChainID("provi"), action.Validator), + tr.getValidatorNode(ChainID("provi"), action.Validator), + gas, + ) + + cmd := target.ExecCommand( + "/bin/bash", "-c", + optIn, + ) + + if verbose { + fmt.Println("optOut cmd:", cmd.String()) + } + + bz, err := cmd.CombinedOutput() + if action.ExpectError { + if err != nil { + if verbose { + fmt.Printf("got expected error during opt out | err: %s | output: %s \n", err, string(bz)) + } + } else { + log.Fatal("expected error during opt-out but got none") + } + } else { + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + } + + // wait for inclusion in a block -> '--broadcast-mode block' is deprecated + tr.waitBlocks(ChainID("provi"), 2, 30*time.Second) +} + // WaitTime waits for the given duration. // To make sure that the new timestamp is visible on-chain, it also waits until at least one block has been // produced on each chain after waiting. diff --git a/tests/e2e/builder.go b/tests/e2e/builder.go index 26eb5c34f6..e9e0f00d5a 100644 --- a/tests/e2e/builder.go +++ b/tests/e2e/builder.go @@ -82,7 +82,6 @@ func generateImageName(version string, cfg TargetConfig) (string, error) { tagName = "local" // this refers to build from local workspace } else { // use git hash of rev as docker image tag - // cmd := exec.Command("git", "rev-parse", "--verify", "--short", version) cmd := exec.Command("git", "log", "--pretty=format:%h", "-n", "1", version) out, err := cmd.CombinedOutput() if err != nil { diff --git a/tests/e2e/config.go b/tests/e2e/config.go index 7f6062b65c..bbfe7a4d0b 100644 --- a/tests/e2e/config.go +++ b/tests/e2e/config.go @@ -91,6 +91,7 @@ const ( MulticonsumerTestCfg TestConfigType = "multi-consumer" ConsumerMisbehaviourTestCfg TestConfigType = "consumer-misbehaviour" CompatibilityTestCfg TestConfigType = "compatibility" + SmallMaxValidatorsTestCfg TestConfigType = "small-max-validators" ) type TestConfig struct { @@ -177,6 +178,8 @@ func GetTestConfig(cfgType TestConfigType, providerVersion, consumerVersion stri testCfg = ConsumerMisbehaviourTestConfig() case CompatibilityTestCfg: testCfg = CompatibilityTestConfig(pv, cv) + case SmallMaxValidatorsTestCfg: + testCfg = SmallMaxValidatorsTestConfig() default: panic(fmt.Sprintf("Invalid test config: %s", cfgType)) } @@ -554,6 +557,22 @@ func DemocracyTestConfig(allowReward bool) TestConfig { return tr } +func SmallMaxValidatorsTestConfig() TestConfig { + cfg := DefaultTestConfig() + + // set the MaxValidators to 2 + proviConfig := cfg.chainConfigs[ChainID("provi")] + proviConfig.GenesisChanges += "| .app_state.staking.params.max_validators = 2" + cfg.chainConfigs[ChainID("provi")] = proviConfig + + carolConfig := cfg.validatorConfigs["carol"] + // make carol use her own key + carolConfig.UseConsumerKey = false + cfg.validatorConfigs["carol"] = carolConfig + + return cfg +} + func MultiConsumerTestConfig() TestConfig { tr := TestConfig{ name: string(MulticonsumerTestCfg), diff --git a/tests/e2e/main.go b/tests/e2e/main.go index 24b3f1ec78..cf8fe70d89 100644 --- a/tests/e2e/main.go +++ b/tests/e2e/main.go @@ -156,6 +156,54 @@ var stepChoices = map[string]StepChoice{ description: `Minimal set of test steps to perform compatibility tests`, testConfig: CompatibilityTestCfg, }, + "partial-set-security-opt-in": { + name: "partial-set-security-opt-in", + steps: stepsOptInChain(), + description: "test partial set security for an Opt-In chain", + testConfig: DefaultTestCfg, + }, + "partial-set-security-top-n": { + name: "partial-set-security-top-n", + steps: stepsTopNChain(), + description: "test partial set security for a Top-N chain", + testConfig: DefaultTestCfg, + }, + "partial-set-security-validator-set-cap": { + name: "partial-set-security-validator-set-cap", + steps: stepsValidatorSetCappedChain(), + description: "test partial set security for an Opt-In chain that is validator-set capped", + testConfig: DefaultTestCfg, + }, + "partial-set-security-validators-power-cap": { + name: "partial-set-security-validators-power-cap", + steps: stepsValidatorsPowerCappedChain(), + description: "test partial set security for an Opt-In chain that has its validators' power capped", + testConfig: DefaultTestCfg, + }, + "partial-set-security-validators-allowlisted": { + name: "partial-set-security-validators-allowlisted", + steps: stepsValidatorsAllowlistedChain(), + description: "test partial set security for an Opt-In chain that has some validators allowlisted", + testConfig: DefaultTestCfg, + }, + "partial-set-security-validators-denylisted": { + name: "partial-set-security-validators-denylisted", + steps: stepsValidatorsDenylistedChain(), + description: "test partial set security for an Opt-In chain that has a validator denylisted", + testConfig: DefaultTestCfg, + }, + "partial-set-security-modification-proposal": { + name: "partial-set-security-modification-proposal", + steps: stepsModifyChain(), + description: "test partial set security parameters can be changed through a modification proposal", + testConfig: DefaultTestCfg, + }, + "active-set-changes": { + name: "active-set-changes", + steps: stepsActiveSetChanges(), + description: "This is a regression test related to the issue discussed here: https://forum.cosmos.network/t/cosmos-hub-v17-1-chain-halt-post-mortem/13899. The test ensures that the protocol works as expected when MaxValidators is smaller than the number of potential validators.", + testConfig: SmallMaxValidatorsTestCfg, + }, } func getTestCaseUsageString() string { @@ -241,7 +289,11 @@ func getTestCases(selectedPredefinedTests, selectedTestFiles TestSet, providerVe "changeover", "happy-path", "democracy-reward", "democracy", "slash-throttle", "consumer-double-sign", "consumer-misbehaviour", - "consumer-double-downtime", + "consumer-double-downtime", "partial-set-security-opt-in", "partial-set-security-top-n", + "partial-set-security-validator-set-cap", "partial-set-security-validators-power-cap", + "partial-set-security-validators-allowlisted", "partial-set-security-validators-denylisted", + "partial-set-security-modification-proposal", + "active-set-changes", } if includeMultiConsumer != nil && *includeMultiConsumer { selectedPredefinedTests = append(selectedPredefinedTests, "multiconsumer") diff --git a/tests/e2e/state.go b/tests/e2e/state.go index 86882ddc56..1c1be7e95a 100644 --- a/tests/e2e/state.go +++ b/tests/e2e/state.go @@ -19,18 +19,19 @@ import ( // type aliases type ( - ChainState = e2e.ChainState - Proposal = e2e.Proposal - Rewards = e2e.Rewards - TextProposal = e2e.TextProposal - UpgradeProposal = e2e.UpgradeProposal - ConsumerAdditionProposal = e2e.ConsumerAdditionProposal - ConsumerRemovalProposal = e2e.ConsumerRemovalProposal - IBCTransferParams = e2e.IBCTransferParams - IBCTransferParamsProposal = e2e.IBCTransferParamsProposal - Param = e2e.Param - ParamsProposal = e2e.ParamsProposal - TargetDriver = e2e.TargetDriver + ChainState = e2e.ChainState + Proposal = e2e.Proposal + Rewards = e2e.Rewards + TextProposal = e2e.TextProposal + UpgradeProposal = e2e.UpgradeProposal + ConsumerAdditionProposal = e2e.ConsumerAdditionProposal + ConsumerRemovalProposal = e2e.ConsumerRemovalProposal + ConsumerModificationProposal = e2e.ConsumerModificationProposal + IBCTransferParams = e2e.IBCTransferParams + IBCTransferParamsProposal = e2e.IBCTransferParamsProposal + Param = e2e.Param + ParamsProposal = e2e.ParamsProposal + TargetDriver = e2e.TargetDriver ) type State map[ChainID]ChainState @@ -41,7 +42,6 @@ type Chain struct { } func (tr Chain) GetChainState(chain ChainID, modelState ChainState) ChainState { - chainState := ChainState{} if modelState.ValBalances != nil { @@ -108,6 +108,14 @@ func (tr Chain) GetChainState(chain ChainID, modelState ChainState) ChainState { chainState.ClientsFrozenHeights = &chainClientsFrozenHeights } + if modelState.HasToValidate != nil { + hasToValidate := map[ValidatorID][]ChainID{} + for validatorId := range *modelState.HasToValidate { + hasToValidate[validatorId] = tr.target.GetHasToValidate(validatorId) + } + chainState.HasToValidate = &hasToValidate + } + if modelState.ConsumerPendingPacketQueueSize != nil { pendingPacketQueueSize := tr.target.GetPendingPacketQueueSize(chain) chainState.ConsumerPendingPacketQueueSize = &pendingPacketQueueSize @@ -479,6 +487,31 @@ func (tr Commands) GetProposal(chain ChainID, proposal uint) Proposal { Title: title, Params: params, } + + case "/interchain_security.ccv.provider.v1.ConsumerModificationProposal": + chainId := rawContent.Get("chain_id").String() + + var chain ChainID + for i, conf := range tr.chainConfigs { + if string(conf.ChainId) == chainId { + chain = i + break + } + } + + return ConsumerModificationProposal{ + Deposit: uint(deposit), + Status: status, + Chain: chain, + } + case "/cosmos.params.v1beta1.ParameterChangeProposal": + return ParamsProposal{ + Deposit: uint(deposit), + Status: status, + Subspace: gjson.Get(string(bz), `messages.0.content.changes.0.subspace`).String(), + Key: gjson.Get(string(bz), `messages.0.content.changes.0.key`).String(), + Value: gjson.Get(string(bz), `messages.0.content.changes.0.value`).String(), + } } log.Fatal("received unknown proposal type: ", propType, "proposal JSON:", string(bz)) @@ -807,6 +840,29 @@ func (tr Commands) GetClientFrozenHeight(chain ChainID, clientID string) (uint64 return uint64(revHeight), uint64(revNumber) } +func (tr Commands) GetHasToValidate( + validatorId ValidatorID, +) []ChainID { + binaryName := tr.chainConfigs[ChainID("provi")].BinaryName + bz, err := tr.target.ExecCommand(binaryName, + "query", "provider", "has-to-validate", + tr.validatorConfigs[validatorId].ValconsAddress, + `--node`, tr.GetQueryNode(ChainID("provi")), + `-o`, `json`, + ).CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + arr := gjson.Get(string(bz), "consumer_chain_ids").Array() + chains := []ChainID{} + for _, c := range arr { + chains = append(chains, ChainID(c.String())) + } + + return chains +} + func (tr Commands) GetTrustedHeight( chain ChainID, clientID string, diff --git a/tests/e2e/steps_active_set_changes.go b/tests/e2e/steps_active_set_changes.go new file mode 100644 index 0000000000..1fc06a73b6 --- /dev/null +++ b/tests/e2e/steps_active_set_changes.go @@ -0,0 +1,143 @@ +package main + +import ( + "strconv" + + gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" +) + +// stepsActiveSetChanges starts a top N provider chain and causes a change in the active set +func stepsActiveSetChanges() []Step { + s := []Step{ + // === setup provider chain, consumer chain with top N = 100, and start IBC connections === + { + Action: StartChainAction{ + Chain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 700000000, Allocation: 10000000000}, + }, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, // MaxValidators is set to 2, so alice is not part of the validator set + ValidatorID("bob"): 200, + ValidatorID("carol"): 700, + }, + }, + }, + }, + { + Action: SubmitConsumerAdditionProposalAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + Deposit: 10000001, + ConsumerChain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + TopN: 100, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), + }, + }, + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: VoteGovProposalAction{ + Chain: ChainID("provi"), + From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob"), ValidatorID("carol")}, + Vote: []string{"yes", "yes", "yes"}, + PropNumber: 1, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), + }, + }, + }, + }, + }, + { + // we start all the validators but only "alice" and "bob" have opted in and hence + // only "alice" and "bob" are validating blocks + Action: StartConsumerChainAction{ + ConsumerChain: ChainID("consu"), + ProviderChain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 700000000, Allocation: 10000000000}, + }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", + }, + State: State{}, + }, + { + Action: AddIbcConnectionAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ClientA: 0, + ClientB: 0, + }, + State: State{}, + }, + { + Action: AddIbcChannelAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ConnectionA: 0, + PortA: "consumer", + PortB: "provider", + Order: "ordered", + }, + State: State{}, + }, + // === setup ends, ready for the actual test === + // bob incurs downtime on the provider and gets jailed + { + Action: DowntimeSlashAction{ + Chain: ChainID("provi"), + Validator: ValidatorID("bob"), + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, // alice goes into the active set + ValidatorID("bob"): 0, + ValidatorID("carol"): 700, + }, + }, + }, + }, + } + + return s +} diff --git a/tests/e2e/steps_compatibility.go b/tests/e2e/steps_compatibility.go index 3eaf1eae9c..a51a34fed3 100644 --- a/tests/e2e/steps_compatibility.go +++ b/tests/e2e/steps_compatibility.go @@ -44,6 +44,7 @@ func compstepsStartConsumerChain(consumerName string, proposalIndex, chainIndex ConsumerChain: ChainID(consumerName), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + TopN: 100, }, State: State{ ChainID("provi"): ChainState{ @@ -88,18 +89,6 @@ func compstepsStartConsumerChain(consumerName string, proposalIndex, chainIndex }, }, }, - { - // op should fail - key already assigned by the same validator - Action: AssignConsumerPubKeyAction{ - Chain: ChainID(consumerName), - Validator: ValidatorID("carol"), - ConsumerPubkey: getDefaultValidators()[ValidatorID("carol")].ConsumerValPubKey, - ReconfigureNode: false, - ExpectError: true, - ExpectedError: "a validator has assigned the consumer key already: consumer key is already in use by a validator", - }, - State: State{}, - }, { // op should fail - key already assigned by another validator Action: AssignConsumerPubKeyAction{ diff --git a/tests/e2e/steps_consumer_misbehaviour.go b/tests/e2e/steps_consumer_misbehaviour.go index 8eb7a72973..56e093e668 100644 --- a/tests/e2e/steps_consumer_misbehaviour.go +++ b/tests/e2e/steps_consumer_misbehaviour.go @@ -39,6 +39,7 @@ func stepsStartChainsWithSoftOptOut(consumerName string) []Step { ConsumerChain: ChainID(consumerName), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + TopN: 100, }, State: State{ ChainID("provi"): ChainState{ @@ -52,7 +53,7 @@ func stepsStartChainsWithSoftOptOut(consumerName string) []Step { Chain: ChainID(consumerName), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, - Status: "PROPOSAL_STATUS_VOTING_PERIOD", + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), }, }, }, diff --git a/tests/e2e/steps_partial_set_security.go b/tests/e2e/steps_partial_set_security.go new file mode 100644 index 0000000000..9a0daa5acf --- /dev/null +++ b/tests/e2e/steps_partial_set_security.go @@ -0,0 +1,2443 @@ +package main + +import ( + "strconv" + + gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" +) + +// stepsOptInChain starts a provider chain and an Opt-In chain and opts in and out validators +func stepsOptInChain() []Step { + s := []Step{ + { + Action: StartChainAction{ + Chain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, + }, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + Action: SubmitConsumerAdditionProposalAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + Deposit: 10000001, + ConsumerChain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + TopN: 0, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), + }, + }, + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + // Οpt in "alice" and "bob" so the chain is not empty when it is about to start. Note, that "alice" and "bob" use + // the provider's public key (see `UseConsumerKey` is set to `false` in `getDefaultValidators`) and hence do not + // need a consumer-key assignment. + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("alice"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, // chain is not running yet + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("bob"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: VoteGovProposalAction{ + Chain: ChainID("provi"), + From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob")}, + Vote: []string{"yes", "yes"}, + PropNumber: 1, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), + }, + }, + }, + }, + }, + { + // we start all the validators but only "alice" and "bob" have opted in and hence + // only "alice" and "bob" are validating blocks + Action: StartConsumerChainAction{ + ConsumerChain: ChainID("consu"), + ProviderChain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, + }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + // carol has not yet opted in + ValidatorID("carol"): 0, + }, + }, + }, + }, + { + Action: AddIbcConnectionAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ClientA: 0, + ClientB: 0, + }, + State: State{}, + }, + { + Action: AddIbcChannelAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ConnectionA: 0, + PortA: "consumer", + PortB: "provider", + Order: "ordered", + }, + State: State{}, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + // "carol" has opted in, but the VSCPacket capturing the opt-in was not relayed yet + ValidatorID("carol"): 0, + }, + }, + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + { + // assign the consumer key "carol" is using on the consumer chain to be the one "carol" uses when opting in + Action: AssignConsumerPubKeyAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + // reconfigure the node -> validator was using provider key + // until this point -> key matches config.consumerValPubKey for "carol" + ConsumerPubkey: getDefaultValidators()[ValidatorID("carol")].ConsumerValPubKey, + ReconfigureNode: true, + }, + State: State{}, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + // carol has now opted in + ValidatorID("carol"): 300, + }, + }, + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + { + Action: OptOutAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("bob"), + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + // "bob" has not yet opted out from the consumer chain because the VSCPacket has not yet been relayed + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + // bob has now opted out + ValidatorID("bob"): 0, + ValidatorID("carol"): 300, + }, + }, + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + { + // re opt-in "bob" + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("bob"), + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + // "bob" has not yet been opted in to the consumer chain because the VSCPacket has not yet been relayed + ValidatorID("bob"): 0, + ValidatorID("carol"): 300, + }, + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {"consu"}, // but has to validate is true because bob opted in on the provider + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + // bob is in power on the consumer + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + // DowntimeSlash for alice on consumer + Action: DowntimeSlashAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("alice"), + }, + // powers are not affected yet on either chain + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + { + // relay the slash packet + Action: RelayPacketsAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + Port: "consumer", + Channel: 0, + }, + // alice's power is reduced on the provider + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, // alice is jailed on the provider and does not have to validate + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + { + // relay the VSCPacket that contains the slashed power for alice + Action: RelayPacketsAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + Port: "consumer", + Channel: 0, + }, + // alice's power is reduced on the provider + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, // alice is jailed on the provider and does not have to validate + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + // alice should definitely not be in power on the consumer + ValidatorID("alice"): 0, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + // unjail alice + Action: UnjailValidatorAction{ + Provider: ChainID("provi"), + Validator: ValidatorID("alice"), + }, + // alices power is restored on the provider + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, // alice is unjailed and hence has to validate again + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + // still 0 power on the consumer + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + // relay the VSCPacket that puts alice back into power on the consumer + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + // alice's power is restored on the consumer + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + // slash alice for downtime again + Action: DowntimeSlashAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("alice"), + }, + // alice's power is not yet reduced, the packet needs to be relayed + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + { + // relay the slash packet + Action: RelayPacketsAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + Port: "consumer", + Channel: 0, + }, + // alice's power is reduced on the provider + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, // alice is jailed on the provider and does not have to validate + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + { + // relay the VSCPacket that contains the slashed power for alice + Action: RelayPacketsAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + Port: "consumer", + Channel: 0, + }, + // alice's power is reduced on the consumer + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, // alice is jailed on the provider and does not have to validate + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + } + + return s +} + +// stepsTopNChain starts a provider chain and a Top-N chain and opts in and out validators +func stepsTopNChain() []Step { + s := []Step{ + { + // start a new chain where "alice", "bob", and "carol" have 20%, 30%, and 50% of + // the total voting power respectively + Action: StartChainAction{ + Chain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 300000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 500000000, Allocation: 10000000000}, + }, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 200, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + }, + }, + { + // propose a Top-N chain with N = 51% and hence both "carol" and "bob" have to validate + Action: SubmitConsumerAdditionProposalAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + Deposit: 10000001, + ConsumerChain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + TopN: 51, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), + }, + }, + }, + }, + }, + { + // change the consumer key "carol" is using on the consumer chain to be the one "carol" uses when opting in + Action: AssignConsumerPubKeyAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + // reconfigure the node -> validator was using provider key + // until this point -> key matches config.consumerValPubKey for "bob" + ConsumerPubkey: getDefaultValidators()[ValidatorID("carol")].ConsumerValPubKey, + ReconfigureNode: true, + }, + State: State{}, + }, + { + Action: VoteGovProposalAction{ + Chain: ChainID("provi"), + From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob")}, + Vote: []string{"yes", "yes"}, + PropNumber: 1, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), + }, + }, + }, + }, + }, + { + // we start all the validators but only "alice" and "bob" have opted in and hence + // only "alice" and "bob" are validating blocks + Action: StartConsumerChainAction{ + ConsumerChain: ChainID("consu"), + ProviderChain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 300000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 500000000, Allocation: 10000000000}, + }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + }, + }, + { + Action: AddIbcConnectionAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ClientA: 0, + ClientB: 0, + }, + State: State{}, + }, + { + Action: AddIbcChannelAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ConnectionA: 0, + PortA: "consumer", + PortB: "provider", + Order: "ordered", + }, + State: State{}, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("alice"), + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + // "alice" is not yet opted in because the VSCPacket has not yet been relayed + ValidatorID("alice"): 0, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + // "alice" is now opted in + ValidatorID("alice"): 200, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + }, + }, + { + Action: OptOutAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + ExpectError: true, + }, + State: State{}, + }, + { + Action: OptOutAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("bob"), + ExpectError: true, + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + { + // opting out "bob" or "carol" does not work because they belong to the Top N validators + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 200, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + { + Action: OptOutAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("alice"), + }, + State: State{}, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + // "alice" has now opted out + ValidatorID("alice"): 0, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, // alice has opted out and the epoch is over, so definitely does not have to validate anymore + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + // opt alice back in + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("alice"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, // alice has to validate again + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + // "alice" has now opted in + ValidatorID("alice"): 200, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + { + // DowntimeSlash for alice on consumer + Action: DowntimeSlashAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("alice"), + }, + // powers are not affected yet on either chain + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 200, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 200, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + }, + }, + { + // relay the slash packet + Action: RelayPacketsAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + Port: "consumer", + Channel: 0, + }, + // alice's power is reduced on the provider + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + }, + }, + { + // relay the VSCPacket that contains the slashed power for alice + Action: RelayPacketsAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + Port: "consumer", + Channel: 0, + }, + // alice's power is reduced on the provider + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + // alice should definitely not be in power on the consumer + ValidatorID("alice"): 0, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + }, + }, + { + // unjail alice + Action: UnjailValidatorAction{ + Provider: ChainID("provi"), + Validator: ValidatorID("alice"), + }, + // alices power is restored on the provider + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 200, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + // still 0 power on the consumer + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + }, + }, + { + // relay the VSCPacket that puts alice back into power on the consumer + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + // alice's power is restored on the consumer + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 200, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + }, + }, + { + // slash alice for downtime again + Action: DowntimeSlashAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("alice"), + }, + // alice's power is not yet reduced, the packet needs to be relayed + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 200, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 200, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + }, + }, + { + // relay the slash packet + Action: RelayPacketsAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + Port: "consumer", + Channel: 0, + }, + // alice's power is reduced on the provider + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + }, + }, + { + // relay the VSCPacket that contains the slashed power for alice + Action: RelayPacketsAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + Port: "consumer", + Channel: 0, + }, + // alice's power is reduced on the consumer + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 300, + ValidatorID("carol"): 500, + }, + }, + }, + }, + } + + return s +} + +// stepsValidatorSetCappedChain starts a provider chain and an Opt-In chain that is validator-set capped +func stepsValidatorSetCappedChain() []Step { + s := []Step{ + { + Action: StartChainAction{ + Chain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, + }, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + Action: SubmitConsumerAdditionProposalAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + Deposit: 10000001, + ConsumerChain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + TopN: 0, + // we can have at most 2 validators validating the consumer chain + ValidatorSetCap: 2, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), + }, + }, + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + // Οpt in "alice", "bob", and "carol." Note, that "alice" and "bob" use the provider's public key + // (see `UseConsumerKey` is set to `false` in `getDefaultValidators`) and hence do not need a consumer-key assignment. + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("alice"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + // chain is not running yet and hence no one has to validate + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("bob"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + // assign the consumer key "carol" is using on the consumer chain to be the one "carol" uses when opting in + Action: AssignConsumerPubKeyAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + // reconfigure the node -> validator was using provider key + // until this point -> key matches config.consumerValPubKey for "carol" + ConsumerPubkey: getDefaultValidators()[ValidatorID("carol")].ConsumerValPubKey, + ReconfigureNode: true, + }, + State: State{}, + }, + { + Action: VoteGovProposalAction{ + Chain: ChainID("provi"), + From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob")}, + Vote: []string{"yes", "yes"}, + PropNumber: 1, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), + }, + }, + }, + }, + }, + { + Action: StartConsumerChainAction{ + ConsumerChain: ChainID("consu"), + ProviderChain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, + }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + // alice does not validate because the consumer chain is validator-set capped to 2 validators and + // bob and carol have more power than alice + ValidatorID("alice"): 0, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + Action: AddIbcConnectionAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ClientA: 0, + ClientB: 0, + }, + State: State{}, + }, + { + Action: AddIbcChannelAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ConnectionA: 0, + PortA: "consumer", + PortB: "provider", + Order: "ordered", + }, + State: State{}, + }, + { + Action: OptOutAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 200, + // "carol" has opted out, but the VSCPacket capturing the opt-out was not relayed yet + ValidatorID("carol"): 300, + }, + }, + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {}, // "carol" does not have to validate anymore because it opted out + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + // "alice" is now validating the consumer chain as well because the chain is capped to 2 validators + // and "carol" just opted out + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + // "carol" has now opted out + ValidatorID("carol"): 0, + }, + }, + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + } + + return s +} + +// stepsValidatorsPowerCappedChain starts a provider chain and an Opt-In chain that is validators-power capped +func stepsValidatorsPowerCappedChain() []Step { + s := []Step{ + { + Action: StartChainAction{ + Chain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, + }, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + Action: SubmitConsumerAdditionProposalAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + Deposit: 10000001, + ConsumerChain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + TopN: 0, + // Set the power cap to 34%. No validator can have more than 34% of the voting power on the consumer chain + ValidatorsPowerCap: 34, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), + }, + }, + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + // Οpt in "alice", "bob", and "carol." Note, that "alice" and "bob" use the provider's public key + // (see `UseConsumerKey` is set to `false` in `getDefaultValidators`) and hence do not need a consumer-key assignment. + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("alice"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, // chain is not running yet + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("bob"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + // assign the consumer key "carol" is using on the consumer chain to be the one "carol" uses when opting in + Action: AssignConsumerPubKeyAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + // reconfigure the node -> validator was using provider key + // until this point -> key matches config.consumerValPubKey for "carol" + ConsumerPubkey: getDefaultValidators()[ValidatorID("carol")].ConsumerValPubKey, + ReconfigureNode: true, + }, + State: State{}, + }, + { + Action: VoteGovProposalAction{ + Chain: ChainID("provi"), + From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob")}, + Vote: []string{"yes", "yes"}, + PropNumber: 1, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), + }, + }, + }, + }, + }, + { + Action: StartConsumerChainAction{ + ConsumerChain: ChainID("consu"), + ProviderChain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, + }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + // the powers of the validators on the consumer chain are different from the provider chain + // because the consumer chain is power capped. Note that the total power is 600 (= 192 + 204 + 204) + // and 204 / 600.0 = 0.34 <= 34% that is the power cap. + ValidatorID("alice"): 192, + ValidatorID("bob"): 204, + ValidatorID("carol"): 204, + }, + }, + }, + }, + { + Action: AddIbcConnectionAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ClientA: 0, + ClientB: 0, + }, + State: State{}, + }, + { + Action: AddIbcChannelAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ConnectionA: 0, + PortA: "consumer", + PortB: "provider", + Order: "ordered", + }, + State: State{}, + }, + { + Action: OptOutAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 192, + ValidatorID("bob"): 204, + ValidatorID("carol"): 204, + }, + }, + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {}, // "carol" does not have to validate anymore because it opted out + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + // "carol" has opted out, and we only have 2 validators left validating. Power capping only operates + // in a best-effort basis and with 2 validators we cannot guarantee that no validator has more + // than 34% of the voting power. In this case, both validators get the same voting power (50% = 102 / 204). + ValidatorID("alice"): 102, + ValidatorID("bob"): 102, + ValidatorID("carol"): 0, + }, + }, + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + } + + return s +} + +// stepsValidatorsAllowlistedChain starts a provider chain and an Opt-In chain with an allowlist +func stepsValidatorsAllowlistedChain() []Step { + s := []Step{ + { + Action: StartChainAction{ + Chain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, + }, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + Action: SubmitConsumerAdditionProposalAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + Deposit: 10000001, + ConsumerChain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + TopN: 0, + // only "alice" and "bob" are allowlisted (see `getDefaultValidators` in `tests/e2e/config.go`) + Allowlist: []string{"cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq", + "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39"}, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), + }, + }, + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + // Οpt in "alice", "bob", and "carol." Note, that "alice" and "bob" use the provider's public key + // (see `UseConsumerKey` is set to `false` in `getDefaultValidators`) and hence do not need a consumer-key assignment. + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("alice"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, // chain is not running yet + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("bob"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + // assign the consumer key "carol" is using on the consumer chain to be the one "carol" uses when opting in + Action: AssignConsumerPubKeyAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + // reconfigure the node -> validator was using provider key + // until this point -> key matches config.consumerValPubKey for "carol" + ConsumerPubkey: getDefaultValidators()[ValidatorID("carol")].ConsumerValPubKey, + ReconfigureNode: true, + }, + State: State{}, + }, + { + Action: VoteGovProposalAction{ + Chain: ChainID("provi"), + From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob")}, + Vote: []string{"yes", "yes"}, + PropNumber: 1, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), + }, + }, + }, + }, + }, + { + Action: StartConsumerChainAction{ + ConsumerChain: ChainID("consu"), + ProviderChain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, + }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + // "carol" is not allowlisted and hence does not validate the consumer chain + ValidatorID("carol"): 0, + }, + }, + }, + }, + { + Action: AddIbcConnectionAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ClientA: 0, + ClientB: 0, + }, + State: State{}, + }, + { + Action: AddIbcChannelAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ConnectionA: 0, + PortA: "consumer", + PortB: "provider", + Order: "ordered", + }, + State: State{}, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 0, + }, + }, + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + } + + return s +} + +// stepsValidatorsDenylistedChain starts a provider chain and an Opt-In chain with a denylist +func stepsValidatorsDenylistedChain() []Step { + s := []Step{ + { + Action: StartChainAction{ + Chain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, + }, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + Action: SubmitConsumerAdditionProposalAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + Deposit: 10000001, + ConsumerChain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + TopN: 0, + // only "bob" is denylisted (see `getDefaultValidators` in `tests/e2e/config.go`) + Denylist: []string{"cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39"}, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), + }, + }, + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + // Οpt in "alice", "bob", and "carol." Note, that "alice" and "bob" use the provider's public key + // (see `UseConsumerKey` is set to `false` in `getDefaultValidators`) and hence do not need a consumer-key assignment. + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("alice"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, // chain is not running yet + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("bob"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + // assign the consumer key "carol" is using on the consumer chain to be the one "carol" uses when opting in + Action: AssignConsumerPubKeyAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + // reconfigure the node -> validator was using provider key + // until this point -> key matches config.consumerValPubKey for "carol" + ConsumerPubkey: getDefaultValidators()[ValidatorID("carol")].ConsumerValPubKey, + ReconfigureNode: true, + }, + State: State{}, + }, + { + Action: VoteGovProposalAction{ + Chain: ChainID("provi"), + From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob")}, + Vote: []string{"yes", "yes"}, + PropNumber: 1, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), + }, + }, + }, + }, + }, + { + Action: StartConsumerChainAction{ + ConsumerChain: ChainID("consu"), + ProviderChain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, + }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + // "bob" is denylisted and hence does not valiate the consumer chain + ValidatorID("bob"): 0, + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + Action: AddIbcConnectionAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ClientA: 0, + ClientB: 0, + }, + State: State{}, + }, + { + Action: AddIbcChannelAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ConnectionA: 0, + PortA: "consumer", + PortB: "provider", + Order: "ordered", + }, + State: State{}, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 0, + ValidatorID("carol"): 300, + }, + }, + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + } + + return s +} + +// stepsModifyChain issues multiple `ConsumerModificationProposal`s on a consumer chain to assert that indeed +// partial-set security parameters can be changed. +func stepsModifyChain() []Step { + s := []Step{ + { + Action: StartChainAction{ + Chain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, + }, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + Action: SubmitConsumerAdditionProposalAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + Deposit: 10000001, + ConsumerChain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + TopN: 0, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), + }, + }, + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + // Οpt in "alice", "bob", and "carol." Note, that "alice" and "bob" use the provider's public key + // (see `UseConsumerKey` is set to `false` in `getDefaultValidators`) and hence do not need a consumer-key assignment. + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("alice"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, // chain is not running yet + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("bob"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + Action: OptInAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + }, + State: State{ + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {}, + ValidatorID("bob"): {}, + ValidatorID("carol"): {}, + }, + }, + }, + }, + { + // assign the consumer key "carol" is using on the consumer chain to be the one "carol" uses when opting in + Action: AssignConsumerPubKeyAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + // reconfigure the node -> validator was using provider key + // until this point -> key matches config.consumerValPubKey for "carol" + ConsumerPubkey: getDefaultValidators()[ValidatorID("carol")].ConsumerValPubKey, + ReconfigureNode: true, + }, + State: State{}, + }, + { + Action: VoteGovProposalAction{ + Chain: ChainID("provi"), + From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob"), ValidatorID("carol")}, + Vote: []string{"yes", "yes", "yes"}, + PropNumber: 1, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), + }, + }, + }, + }, + }, + { + Action: StartConsumerChainAction{ + ConsumerChain: ChainID("consu"), + ProviderChain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 100000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, + {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, + }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + { + Action: AddIbcConnectionAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ClientA: 0, + ClientB: 0, + }, + State: State{}, + }, + { + Action: AddIbcChannelAction{ + ChainA: ChainID("consu"), + ChainB: ChainID("provi"), + ConnectionA: 0, + PortA: "consumer", + PortB: "provider", + Order: "ordered", + }, + State: State{}, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + ChainID("provi"): ChainState{ + HasToValidate: &map[ValidatorID][]ChainID{ + ValidatorID("alice"): {"consu"}, + ValidatorID("bob"): {"consu"}, + ValidatorID("carol"): {"consu"}, + }, + }, + }, + }, + + // In what follows, we have 5 cases of `ConsumerModificationProposal`s that test the following: + // 1. set `ValidatorsPowerCap` to 40% + // 2. set the `ValidatorSetCap` to a maximum of 2 validators + // 3. set an allowlist with 2 validators + // 4. set a denylist with 1 validator + // 5. modify the chain from Opt In to Top 100% + + // 1. set `ValidatorsPowerCap` to 40% + { + Action: SubmitConsumerModificationProposalAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + Deposit: 10000001, + ConsumerChain: ChainID("consu"), + ValidatorsPowerCap: 40, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 2: ConsumerModificationProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), + }, + }, + }, + }, + }, + { + Action: VoteGovProposalAction{ + Chain: ChainID("provi"), + From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob"), ValidatorID("carol")}, + Vote: []string{"yes", "yes", "yes"}, + PropNumber: 2, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 2: ConsumerModificationProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), + }, + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + ChainID("consu"): ChainState{ + // `ValidatorsPowerCap` is set to 40% + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 130, // ~22% of the total voting power + ValidatorID("bob"): 230, // ~38% of the total voting power + ValidatorID("carol"): 240, // 40% of the total voting power + }, + }, + }, + }, + + // 2. set the `ValidatorSetCap` to a maximum of 2 validators + { + Action: SubmitConsumerModificationProposalAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + Deposit: 10000001, + ConsumerChain: ChainID("consu"), + ValidatorSetCap: 2, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 3: ConsumerModificationProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), + }, + }, + }, + }, + }, + { + Action: VoteGovProposalAction{ + Chain: ChainID("provi"), + From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob"), ValidatorID("carol")}, + Vote: []string{"yes", "yes", "yes"}, + PropNumber: 3, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 3: ConsumerModificationProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), + }, + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + ChainID("consu"): ChainState{ + // we can have a maximum of 2 validators due to `ValidatorSetCap`, hence only the 2 validators ("bob" and "carol") + // with the highest voting power validate + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + + // 3. set an allowlist with 2 validators + { + Action: SubmitConsumerModificationProposalAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + Deposit: 10000001, + ConsumerChain: ChainID("consu"), + // only "alice" and "carol" are allowlisted (see `getDefaultValidators` in `tests/e2e/config.go`) + Allowlist: []string{"cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq", + "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6"}, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 4: ConsumerModificationProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), + }, + }, + }, + }, + }, + { + Action: VoteGovProposalAction{ + Chain: ChainID("provi"), + From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob"), ValidatorID("carol")}, + Vote: []string{"yes", "yes", "yes"}, + PropNumber: 4, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 4: ConsumerModificationProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), + }, + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 0, // "bob" is not allowlisted + ValidatorID("carol"): 300, + }, + }, + }, + }, + + // 4. set a denylist with 1 validator + { + Action: SubmitConsumerModificationProposalAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + Deposit: 10000001, + ConsumerChain: ChainID("consu"), + // only "alice" is denylisted (see `getDefaultValidators` in `tests/e2e/config.go`) + Denylist: []string{"cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq"}, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 5: ConsumerModificationProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), + }, + }, + }, + }, + }, + { + Action: VoteGovProposalAction{ + Chain: ChainID("provi"), + From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob"), ValidatorID("carol")}, + Vote: []string{"yes", "yes", "yes"}, + PropNumber: 5, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 5: ConsumerModificationProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), + }, + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID("consu"), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 100, + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + ChainID("consu"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, // "alice" is denylisted + ValidatorID("bob"): 200, + ValidatorID("carol"): 300, + }, + }, + }, + }, + + // 5. modify the chain from Opt In to Top 100% + { + Action: SubmitConsumerModificationProposalAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + Deposit: 10000001, + ConsumerChain: ChainID("consu"), + TopN: 100, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 6: ConsumerModificationProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD)), + }, + }, + }, + }, + }, + { + Action: VoteGovProposalAction{ + Chain: ChainID("provi"), + From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob"), ValidatorID("carol")}, + Vote: []string{"yes", "yes", "yes"}, + PropNumber: 6, + }, + State: State{ + ChainID("provi"): ChainState{ + Proposals: &map[uint]Proposal{ + 6: ConsumerModificationProposal{ + Deposit: 10000001, + Chain: ChainID("consu"), + Status: strconv.Itoa(int(gov.ProposalStatus_PROPOSAL_STATUS_PASSED)), + }, + }, + }, + }, + }, + { + Action: OptOutAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("alice"), + ExpectError: true, // because this chain is now Top 100%, no validator can opt out + }, + State: State{}, + }, + { + Action: OptOutAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("bob"), + ExpectError: true, // because this chain is now Top 100%, no validator can opt out + }, + State: State{}, + }, + { + Action: OptOutAction{ + Chain: ChainID("consu"), + Validator: ValidatorID("carol"), + ExpectError: true, // because this chain is now Top 100%, no validator can opt out + }, + State: State{}, + }} + + return s +} diff --git a/tests/e2e/steps_sovereign_changeover.go b/tests/e2e/steps_sovereign_changeover.go index e3c6563204..68ed5c8505 100644 --- a/tests/e2e/steps_sovereign_changeover.go +++ b/tests/e2e/steps_sovereign_changeover.go @@ -53,6 +53,7 @@ func stepsChangeoverToConsumer(consumerName string) []Step { DistributionChannel: "channel-0", SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 111}, // 1 block after upgrade !important + TopN: 100, }, State: State{ ChainID("provi"): ChainState{ diff --git a/tests/e2e/steps_start_chains.go b/tests/e2e/steps_start_chains.go index 5e25981691..e358862590 100644 --- a/tests/e2e/steps_start_chains.go +++ b/tests/e2e/steps_start_chains.go @@ -41,6 +41,7 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint ConsumerChain: ChainID(consumerName), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + TopN: 100, }, State: State{ ChainID("provi"): ChainState{ @@ -85,16 +86,24 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint }, }, { - // op should fail - key already assigned by the same validator + // op should be a noop - key already assigned, but by the same validator Action: AssignConsumerPubKeyAction{ Chain: ChainID(consumerName), Validator: ValidatorID("carol"), ConsumerPubkey: getDefaultValidators()[ValidatorID("carol")].ConsumerValPubKey, ReconfigureNode: false, - ExpectError: true, - ExpectedError: "a validator has assigned the consumer key already: consumer key is already in use by a validator", + ExpectError: false, + }, + State: State{ + ChainID(consumerName): ChainState{ + AssignedKeys: &map[ValidatorID]string{ + ValidatorID("carol"): getDefaultValidators()[ValidatorID("carol")].ConsumerValconsAddressOnProvider, + }, + ProviderKeys: &map[ValidatorID]string{ + ValidatorID("carol"): getDefaultValidators()[ValidatorID("carol")].ValconsAddress, + }, + }, }, - State: State{}, }, { // op should fail - key already assigned by another validator diff --git a/tests/e2e/test_driver.go b/tests/e2e/test_driver.go index a4c2424ff5..9c59411ac7 100644 --- a/tests/e2e/test_driver.go +++ b/tests/e2e/test_driver.go @@ -145,6 +145,8 @@ func (td *DefaultDriver) runAction(action interface{}) error { target.submitConsumerRemovalProposal(action, td.verbose) case SubmitEnableTransfersProposalAction: target.submitEnableTransfersProposalAction(action, td.verbose) + case SubmitConsumerModificationProposalAction: + target.submitConsumerModificationProposal(action, td.verbose) case VoteGovProposalAction: target.voteGovProposal(action, td.verbose) case StartConsumerChainAction: @@ -201,6 +203,10 @@ func (td *DefaultDriver) runAction(action interface{}) error { target.startConsumerEvidenceDetector(action, td.verbose) case SubmitChangeRewardDenomsProposalAction: target.submitChangeRewardDenomsProposal(action, td.verbose) + case OptInAction: + target.optIn(action, td.target, td.verbose) + case OptOutAction: + target.optOut(action, td.target, td.verbose) default: log.Fatalf("unknown action in testRun %s: %#v", td.testCfg.name, action) } diff --git a/tests/e2e/testlib/types.go b/tests/e2e/testlib/types.go index dd600bb624..135f07a6a8 100644 --- a/tests/e2e/testlib/types.go +++ b/tests/e2e/testlib/types.go @@ -21,6 +21,7 @@ type ChainCommands interface { GetConsumerChains(chain ChainID) map[ChainID]bool GetConsumerAddress(consumerChain ChainID, validator ValidatorID) string GetClientFrozenHeight(chain ChainID, clientID string) (RevisionNumber, RevisionHeight uint64) + GetHasToValidate(validator ValidatorID) []ChainID GetIBCTransferParams(chain ChainID) IBCTransferParams GetProposal(chain ChainID, proposal uint) Proposal GetParam(chain ChainID, param Param) string @@ -168,6 +169,7 @@ type ChainState struct { ConsumerPendingPacketQueueSize *uint // Only relevant to consumer chains RegisteredConsumerRewardDenoms *[]string ClientsFrozenHeights *map[string]clienttypes.Height + HasToValidate *map[ValidatorID][]ChainID // only relevant to provider chain } // custom marshal and unmarshal functions for the chainstate that convert proposals to/from the auxiliary type with type info @@ -307,6 +309,14 @@ type ConsumerRemovalProposal struct { func (p ConsumerRemovalProposal) isProposal() {} +type ConsumerModificationProposal struct { + Deposit uint + Chain ChainID + Status string +} + +func (p ConsumerModificationProposal) isProposal() {} + type Rewards struct { IsRewarded map[ValidatorID]bool // if true it will calculate if the validator/delegator is rewarded between 2 successive blocks, diff --git a/tests/e2e/tracehandler_testdata/changeover.json b/tests/e2e/tracehandler_testdata/changeover.json index b7f3de992e..b115680878 100644 --- a/tests/e2e/tracehandler_testdata/changeover.json +++ b/tests/e2e/tracehandler_testdata/changeover.json @@ -28,6 +28,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -58,6 +59,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -104,6 +106,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -151,6 +154,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -193,6 +197,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -229,7 +234,8 @@ "InitialHeight": { "revision_height": 111 }, - "DistributionChannel": "channel-0" + "DistributionChannel": "channel-0", + "TopN": 100 }, "State": { "provi": { @@ -248,6 +254,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -298,6 +305,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -357,6 +365,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "sover": { @@ -376,6 +385,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -427,6 +437,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -457,6 +468,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "sover": { @@ -476,6 +488,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -506,6 +519,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -534,6 +548,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -564,6 +579,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "sover": { @@ -583,6 +599,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -613,6 +630,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } diff --git a/tests/e2e/tracehandler_testdata/consumer-double-sign.json b/tests/e2e/tracehandler_testdata/consumer-double-sign.json index cf113f3db9..7744bc5b03 100644 --- a/tests/e2e/tracehandler_testdata/consumer-double-sign.json +++ b/tests/e2e/tracehandler_testdata/consumer-double-sign.json @@ -41,6 +41,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -57,7 +58,8 @@ "InitialHeight": { "revision_height": 1 }, - "DistributionChannel": "" + "DistributionChannel": "", + "TopN": 100 }, "State": { "provi": { @@ -78,6 +80,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -123,6 +126,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -134,10 +138,31 @@ "Validator": "carol", "ConsumerPubkey": "{\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is=\"}", "ReconfigureNode": false, - "ExpectError": true, - "ExpectedError": "a validator has assigned the consumer key already: consumer key is already in use by a validator" + "ExpectError": false, + "ExpectedError": "" }, - "State": {} + "State": { + "consu": { + "ValBalances": null, + "ProposedConsumerChains": null, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": { + "carol": "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk" + }, + "ProviderKeys": { + "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" + }, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "HasToValidate": null, + "Proposals": null + } + } }, { "ActionType": "main.AssignConsumerPubKeyAction", @@ -168,6 +193,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -205,6 +231,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -264,6 +291,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -283,6 +311,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -334,6 +363,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -357,6 +387,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -384,6 +415,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -407,6 +439,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -437,6 +470,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -460,6 +494,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } diff --git a/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json b/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json index d2df468fb3..90f009fb7e 100644 --- a/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json +++ b/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json @@ -35,6 +35,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -51,7 +52,8 @@ "InitialHeight": { "revision_height": 1 }, - "DistributionChannel": "" + "DistributionChannel": "", + "TopN": 100 }, "State": { "provi": { @@ -70,6 +72,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -115,6 +118,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -150,6 +154,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -197,6 +202,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -215,6 +221,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -267,6 +274,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -285,6 +293,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -314,6 +323,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -355,6 +365,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -376,6 +387,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -405,6 +417,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -430,6 +443,7 @@ "revision_height": 1 } }, + "HasToValidate": null, "Proposals": null } } diff --git a/tests/e2e/tracehandler_testdata/democracy.json b/tests/e2e/tracehandler_testdata/democracy.json index 72b2b6c508..633e13ee08 100644 --- a/tests/e2e/tracehandler_testdata/democracy.json +++ b/tests/e2e/tracehandler_testdata/democracy.json @@ -41,6 +41,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -57,7 +58,8 @@ "InitialHeight": { "revision_height": 1 }, - "DistributionChannel": "" + "DistributionChannel": "", + "TopN": 100 }, "State": { "provi": { @@ -78,6 +80,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -123,6 +126,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -134,10 +138,31 @@ "Validator": "carol", "ConsumerPubkey": "{\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is=\"}", "ReconfigureNode": false, - "ExpectError": true, - "ExpectedError": "a validator has assigned the consumer key already: consumer key is already in use by a validator" + "ExpectError": false, + "ExpectedError": "" }, - "State": {} + "State": { + "democ": { + "ValBalances": null, + "ProposedConsumerChains": null, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": { + "carol": "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk" + }, + "ProviderKeys": { + "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" + }, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "HasToValidate": null, + "Proposals": null + } + } }, { "ActionType": "main.AssignConsumerPubKeyAction", @@ -168,6 +193,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -205,6 +231,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -264,6 +291,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -283,6 +311,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -350,6 +379,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -369,6 +399,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -398,6 +429,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -428,6 +460,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -457,6 +490,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -503,6 +537,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -544,6 +579,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -573,6 +609,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -621,6 +658,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -668,6 +706,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": [], "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -693,6 +732,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": [], "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -729,6 +769,7 @@ "ibc/3C3D7B3BE4ECC85A0E5B52A3AEC3B7DFC2AA9CA47C37821E57020D6807043BE9" ], "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -763,6 +804,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -791,6 +833,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -810,6 +853,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -840,6 +884,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -859,6 +904,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -889,6 +935,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -917,6 +964,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -936,6 +984,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -969,6 +1018,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } diff --git a/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json b/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json index 4a37cd6d0c..75487915de 100644 --- a/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json +++ b/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json @@ -41,6 +41,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -57,7 +58,8 @@ "InitialHeight": { "revision_height": 1 }, - "DistributionChannel": "" + "DistributionChannel": "", + "TopN": 100 }, "State": { "provi": { @@ -78,6 +80,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -123,6 +126,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -134,10 +138,31 @@ "Validator": "carol", "ConsumerPubkey": "{\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is=\"}", "ReconfigureNode": false, - "ExpectError": true, - "ExpectedError": "a validator has assigned the consumer key already: consumer key is already in use by a validator" + "ExpectError": false, + "ExpectedError": "" }, - "State": {} + "State": { + "democ": { + "ValBalances": null, + "ProposedConsumerChains": null, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": { + "carol": "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk" + }, + "ProviderKeys": { + "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" + }, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "HasToValidate": null, + "Proposals": null + } + } }, { "ActionType": "main.AssignConsumerPubKeyAction", @@ -168,6 +193,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -205,6 +231,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -264,6 +291,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -283,6 +311,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -350,6 +379,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -369,6 +399,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -398,6 +429,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -428,6 +460,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -457,6 +490,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -503,6 +537,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -544,6 +579,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -573,6 +609,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -621,6 +658,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -668,6 +706,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": [], "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -693,6 +732,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": [], "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -729,6 +769,7 @@ "ibc/3C3D7B3BE4ECC85A0E5B52A3AEC3B7DFC2AA9CA47C37821E57020D6807043BE9" ], "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -763,6 +804,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -791,6 +833,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -810,6 +853,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -840,6 +884,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -859,6 +904,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -889,6 +935,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -917,6 +964,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -936,6 +984,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -969,6 +1018,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } diff --git a/tests/e2e/tracehandler_testdata/happyPath.json b/tests/e2e/tracehandler_testdata/happyPath.json index aba049cb5d..e5f732eaf0 100644 --- a/tests/e2e/tracehandler_testdata/happyPath.json +++ b/tests/e2e/tracehandler_testdata/happyPath.json @@ -41,6 +41,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -57,7 +58,8 @@ "InitialHeight": { "revision_height": 1 }, - "DistributionChannel": "" + "DistributionChannel": "", + "TopN": 100 }, "State": { "provi": { @@ -78,6 +80,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -123,6 +126,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -134,10 +138,31 @@ "Validator": "carol", "ConsumerPubkey": "{\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is=\"}", "ReconfigureNode": false, - "ExpectError": true, - "ExpectedError": "a validator has assigned the consumer key already: consumer key is already in use by a validator" + "ExpectError": false, + "ExpectedError": "" }, - "State": {} + "State": { + "consu": { + "ValBalances": null, + "ProposedConsumerChains": null, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": { + "carol": "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk" + }, + "ProviderKeys": { + "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" + }, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "HasToValidate": null, + "Proposals": null + } + } }, { "ActionType": "main.AssignConsumerPubKeyAction", @@ -168,6 +193,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -205,6 +231,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -264,6 +291,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -283,6 +311,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -336,6 +365,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -355,6 +385,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -384,6 +415,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -414,6 +446,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -443,6 +476,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -481,6 +515,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -500,6 +535,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -536,6 +572,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -555,6 +592,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -585,6 +623,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -604,6 +643,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -634,6 +674,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -664,6 +705,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -683,6 +725,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -713,6 +756,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -743,6 +787,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -762,6 +807,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -792,6 +838,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -823,6 +870,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -842,6 +890,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -872,6 +921,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -900,6 +950,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -919,6 +970,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -949,6 +1001,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -968,6 +1021,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -999,6 +1053,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1018,6 +1073,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1048,6 +1104,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1076,6 +1133,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1095,6 +1153,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1124,6 +1183,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1143,6 +1203,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1173,6 +1234,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1201,6 +1263,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1220,6 +1283,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1250,6 +1314,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1278,6 +1343,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1297,6 +1363,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1327,6 +1394,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1355,6 +1423,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1374,6 +1443,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1404,6 +1474,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1432,6 +1503,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1451,6 +1523,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1481,6 +1554,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1500,6 +1574,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1536,6 +1611,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "2": { "RawProposal": { @@ -1584,6 +1660,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "2": { "RawProposal": { @@ -1625,6 +1702,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "3": { "RawProposal": { @@ -1671,6 +1749,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "3": { "RawProposal": { diff --git a/tests/e2e/tracehandler_testdata/multipleConsumers.json b/tests/e2e/tracehandler_testdata/multipleConsumers.json index ac6c6b6b96..504e742a60 100644 --- a/tests/e2e/tracehandler_testdata/multipleConsumers.json +++ b/tests/e2e/tracehandler_testdata/multipleConsumers.json @@ -41,6 +41,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -57,7 +58,8 @@ "InitialHeight": { "revision_height": 1 }, - "DistributionChannel": "" + "DistributionChannel": "", + "TopN": 100 }, "State": { "provi": { @@ -78,6 +80,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -123,6 +126,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -134,10 +138,31 @@ "Validator": "carol", "ConsumerPubkey": "{\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is=\"}", "ReconfigureNode": false, - "ExpectError": true, - "ExpectedError": "a validator has assigned the consumer key already: consumer key is already in use by a validator" + "ExpectError": false, + "ExpectedError": "" }, - "State": {} + "State": { + "consu": { + "ValBalances": null, + "ProposedConsumerChains": null, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": { + "carol": "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk" + }, + "ProviderKeys": { + "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" + }, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "HasToValidate": null, + "Proposals": null + } + } }, { "ActionType": "main.AssignConsumerPubKeyAction", @@ -168,6 +193,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -205,6 +231,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -264,6 +291,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -283,6 +311,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -322,7 +351,8 @@ "InitialHeight": { "revision_height": 1 }, - "DistributionChannel": "" + "DistributionChannel": "", + "TopN": 100 }, "State": { "provi": { @@ -343,6 +373,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "2": { "RawProposal": { @@ -388,6 +419,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -399,10 +431,31 @@ "Validator": "carol", "ConsumerPubkey": "{\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is=\"}", "ReconfigureNode": false, - "ExpectError": true, - "ExpectedError": "a validator has assigned the consumer key already: consumer key is already in use by a validator" + "ExpectError": false, + "ExpectedError": "" }, - "State": {} + "State": { + "densu": { + "ValBalances": null, + "ProposedConsumerChains": null, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": { + "carol": "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk" + }, + "ProviderKeys": { + "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" + }, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "HasToValidate": null, + "Proposals": null + } + } }, { "ActionType": "main.AssignConsumerPubKeyAction", @@ -433,6 +486,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -470,6 +524,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "2": { "RawProposal": { @@ -529,6 +584,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -548,6 +604,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -601,6 +658,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -620,6 +678,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -639,6 +698,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -669,6 +729,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -688,6 +749,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -707,6 +769,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -737,6 +800,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -756,6 +820,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -775,6 +840,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -805,6 +871,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -824,6 +891,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -843,6 +911,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -873,6 +942,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -892,6 +962,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -911,6 +982,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -941,6 +1013,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -960,6 +1033,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -979,6 +1053,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1010,6 +1085,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -1029,6 +1105,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1048,6 +1125,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1078,6 +1156,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -1097,6 +1176,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1116,6 +1196,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1146,6 +1227,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -1165,6 +1247,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1184,6 +1267,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1212,6 +1296,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -1231,6 +1316,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1250,6 +1336,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1280,6 +1367,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -1299,6 +1387,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1318,6 +1407,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1348,6 +1438,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -1367,6 +1458,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1397,6 +1489,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -1416,6 +1509,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1444,6 +1538,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -1463,6 +1558,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1482,6 +1578,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1512,6 +1609,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -1531,6 +1629,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1550,6 +1649,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1580,6 +1680,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -1599,6 +1700,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1618,6 +1720,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1646,6 +1749,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -1665,6 +1769,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1684,6 +1789,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1714,6 +1820,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -1733,6 +1840,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1752,6 +1860,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1782,6 +1891,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -1801,6 +1911,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1820,6 +1931,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1848,6 +1960,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -1867,6 +1980,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1886,6 +2000,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1916,6 +2031,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -1935,6 +2051,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1954,6 +2071,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1984,6 +2102,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -2003,6 +2122,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -2022,6 +2142,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -2050,6 +2171,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -2069,6 +2191,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -2088,6 +2211,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -2118,6 +2242,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -2137,6 +2262,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -2156,6 +2282,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -2186,6 +2313,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -2205,6 +2333,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -2224,6 +2353,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -2252,6 +2382,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -2271,6 +2402,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -2290,6 +2422,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -2320,6 +2453,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -2339,6 +2473,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -2358,6 +2493,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -2388,6 +2524,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -2407,6 +2544,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -2426,6 +2564,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -2456,6 +2595,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "densu": { @@ -2475,6 +2615,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } diff --git a/tests/e2e/tracehandler_testdata/shorthappy.json b/tests/e2e/tracehandler_testdata/shorthappy.json index 490d67e5c5..60c645e8c9 100644 --- a/tests/e2e/tracehandler_testdata/shorthappy.json +++ b/tests/e2e/tracehandler_testdata/shorthappy.json @@ -41,6 +41,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -57,7 +58,8 @@ "InitialHeight": { "revision_height": 1 }, - "DistributionChannel": "" + "DistributionChannel": "", + "TopN": 100 }, "State": { "provi": { @@ -78,6 +80,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -123,6 +126,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -134,10 +138,31 @@ "Validator": "carol", "ConsumerPubkey": "{\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is=\"}", "ReconfigureNode": false, - "ExpectError": true, - "ExpectedError": "a validator has assigned the consumer key already: consumer key is already in use by a validator" + "ExpectError": false, + "ExpectedError": "" }, - "State": {} + "State": { + "consu": { + "ValBalances": null, + "ProposedConsumerChains": null, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": { + "carol": "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk" + }, + "ProviderKeys": { + "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" + }, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "HasToValidate": null, + "Proposals": null + } + } }, { "ActionType": "main.AssignConsumerPubKeyAction", @@ -168,6 +193,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -205,6 +231,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -264,6 +291,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -283,6 +311,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -336,6 +365,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -355,6 +385,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -384,6 +415,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -414,6 +446,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -443,6 +476,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -473,6 +507,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -492,6 +527,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -522,6 +558,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -553,6 +590,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -572,6 +610,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -602,6 +641,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -630,6 +670,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -649,6 +690,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -678,6 +720,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -697,6 +740,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -727,6 +771,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -755,6 +800,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -774,6 +820,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -804,6 +851,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -832,6 +880,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -851,6 +900,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -881,6 +931,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -909,6 +960,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -928,6 +980,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -958,6 +1011,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -986,6 +1040,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1005,6 +1060,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1035,6 +1091,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -1054,6 +1111,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -1090,6 +1148,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "2": { "RawProposal": { @@ -1138,6 +1197,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "2": { "RawProposal": { @@ -1179,6 +1239,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "3": { "RawProposal": { @@ -1225,6 +1286,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "3": { "RawProposal": { diff --git a/tests/e2e/tracehandler_testdata/slashThrottle.json b/tests/e2e/tracehandler_testdata/slashThrottle.json index 9d35c04d85..e325113cc4 100644 --- a/tests/e2e/tracehandler_testdata/slashThrottle.json +++ b/tests/e2e/tracehandler_testdata/slashThrottle.json @@ -41,6 +41,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -57,7 +58,8 @@ "InitialHeight": { "revision_height": 1 }, - "DistributionChannel": "" + "DistributionChannel": "", + "TopN": 100 }, "State": { "provi": { @@ -78,6 +80,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -123,6 +126,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -134,10 +138,31 @@ "Validator": "carol", "ConsumerPubkey": "{\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is=\"}", "ReconfigureNode": false, - "ExpectError": true, - "ExpectedError": "a validator has assigned the consumer key already: consumer key is already in use by a validator" + "ExpectError": false, + "ExpectedError": "" }, - "State": {} + "State": { + "consu": { + "ValBalances": null, + "ProposedConsumerChains": null, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": { + "carol": "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk" + }, + "ProviderKeys": { + "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" + }, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "HasToValidate": null, + "Proposals": null + } + } }, { "ActionType": "main.AssignConsumerPubKeyAction", @@ -168,6 +193,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -205,6 +231,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "1": { "RawProposal": { @@ -264,6 +291,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -283,6 +311,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -336,6 +365,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -355,6 +385,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -384,6 +415,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -414,6 +446,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -443,6 +476,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -471,6 +505,7 @@ "ConsumerPendingPacketQueueSize": 1, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -490,6 +525,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -520,6 +556,7 @@ "ConsumerPendingPacketQueueSize": 0, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -539,6 +576,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -567,6 +605,7 @@ "ConsumerPendingPacketQueueSize": 1, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -586,6 +625,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -616,6 +656,7 @@ "ConsumerPendingPacketQueueSize": 1, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -635,6 +676,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -663,6 +705,7 @@ "ConsumerPendingPacketQueueSize": 1, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -682,6 +725,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -705,6 +749,7 @@ "ConsumerPendingPacketQueueSize": 1, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -724,6 +769,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -750,6 +796,7 @@ "ConsumerPendingPacketQueueSize": 0, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null }, "provi": { @@ -769,6 +816,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": null } } @@ -800,6 +848,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "2": { "RawProposal": { @@ -846,6 +895,7 @@ "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, "ClientsFrozenHeights": null, + "HasToValidate": null, "Proposals": { "2": { "RawProposal": { diff --git a/tests/e2e/v4/state.go b/tests/e2e/v4/state.go index 9ee3c7ec97..70ca8afe7c 100644 --- a/tests/e2e/v4/state.go +++ b/tests/e2e/v4/state.go @@ -649,6 +649,10 @@ func (tr Commands) GetIBCTransferParams(chain ChainID) IBCTransferParams { panic("'GetIBCTransferParams' is not implemented in this version") } +func (tr Commands) GetHasToValidate(validator ValidatorID) []ChainID { + panic("''GetHasToValidate' is not implemented in this version") +} + func uintPtr(i uint) *uint { return &i } diff --git a/tests/integration/distribution.go b/tests/integration/distribution.go index b54720a5a4..2e5f2f0bbb 100644 --- a/tests/integration/distribution.go +++ b/tests/integration/distribution.go @@ -3,16 +3,19 @@ package integration import ( "strings" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "cosmossdk.io/math" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - sdkdistrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" - icstestingutils "github.com/cosmos/interchain-security/v5/testutil/integration" consumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) @@ -43,6 +46,8 @@ func (s *CCVTestSuite) TestRewardsDistribution() { providerAccountKeeper := s.providerApp.GetTestAccountKeeper() consumerBankKeeper := s.consumerApp.GetTestBankKeeper() providerBankKeeper := s.providerApp.GetTestBankKeeper() + providerKeeper := s.providerApp.GetProviderKeeper() + providerDistributionKeeper := s.providerApp.GetTestDistributionKeeper() // send coins to the fee pool which is used for reward distribution consumerFeePoolAddr := consumerAccountKeeper.GetModuleAccount(s.consumerCtx(), authtypes.FeeCollectorName).GetAddress() @@ -50,6 +55,7 @@ func (s *CCVTestSuite) TestRewardsDistribution() { fees := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100))) err := consumerBankKeeper.SendCoinsFromAccountToModule(s.consumerCtx(), s.consumerChain.SenderAccount.GetAddress(), authtypes.FeeCollectorName, fees) s.Require().NoError(err) + feePoolTokens := consumerBankKeeper.GetAllBalances(s.consumerCtx(), consumerFeePoolAddr) s.Require().Equal(math.NewInt(100).Add(feePoolTokensOld.AmountOf(sdk.DefaultBondDenom)), feePoolTokens.AmountOf(sdk.DefaultBondDenom)) @@ -71,7 +77,6 @@ func (s *CCVTestSuite) TestRewardsDistribution() { s.Require().Equal(providerExpectedRewards.AmountOf(sdk.DefaultBondDenom), providerTokens.AmountOf(sdk.DefaultBondDenom)) // send the reward to provider chain after 2 blocks - s.consumerChain.NextBlock() providerTokens = consumerBankKeeper.GetAllBalances(s.consumerCtx(), providerRedistributeAddr) s.Require().Equal(0, len(providerTokens)) @@ -83,55 +88,99 @@ func (s *CCVTestSuite) TestRewardsDistribution() { rewardPool := providerAccountKeeper.GetModuleAccount(s.providerCtx(), providertypes.ConsumerRewardsPool).GetAddress() rewardCoins := providerBankKeeper.GetAllBalances(s.providerCtx(), rewardPool) - ibcCoinIndex := -1 - - for i, coin := range rewardCoins { + // Check that the reward pool contains a coin with an IBC denom + rewardsIBCdenom := "" + for _, coin := range rewardCoins { if strings.HasPrefix(coin.Denom, "ibc") { - ibcCoinIndex = i + rewardsIBCdenom = coin.Denom } } - - // Check that we found an ibc denom in the reward pool - s.Require().Greater(ibcCoinIndex, -1) - ibcDenom := rewardCoins[ibcCoinIndex].Denom + s.Require().NotZero(rewardsIBCdenom) // Check that the coins got into the ConsumerRewardsPool - s.Require().True(rewardCoins[ibcCoinIndex].Amount.Equal(providerExpectedRewards[0].Amount)) + providerExpRewardsAmount := providerExpectedRewards.AmountOf(sdk.DefaultBondDenom) + s.Require().Equal(rewardCoins.AmountOf(rewardsIBCdenom), providerExpRewardsAmount) // Advance a block and check that the coins are still in the ConsumerRewardsPool s.providerChain.NextBlock() rewardCoins = providerBankKeeper.GetAllBalances(s.providerCtx(), rewardPool) - s.Require().True(rewardCoins[ibcCoinIndex].Amount.Equal(providerExpectedRewards[0].Amount)) - - // Set the consumer reward denom. This would be done by a governance proposal in prod - s.providerApp.GetProviderKeeper().SetConsumerRewardDenom(s.providerCtx(), ibcDenom) - - s.providerChain.NextBlock() + s.Require().Equal(rewardCoins.AmountOf(rewardsIBCdenom), providerExpRewardsAmount) + + // Set the consumer reward denom. This would be done by a governance proposal in prod. + providerKeeper.SetConsumerRewardDenom(s.providerCtx(), rewardsIBCdenom) + + // Refill the consumer fee pool + err = consumerBankKeeper.SendCoinsFromAccountToModule( + s.consumerCtx(), + s.consumerChain.SenderAccount.GetAddress(), + authtypes.FeeCollectorName, + fees, + ) + s.Require().NoError(err) - // Check that the reward pool has no more coins because they were transferred to the fee collector - rewardCoins = providerBankKeeper.GetAllBalances(s.providerCtx(), rewardPool) - s.Require().Equal(0, len(rewardCoins)) - feeCollectorIbcCoin := providerBankKeeper.GetBalance(s.providerCtx(), authtypes.NewModuleAddress(authtypes.FeeCollectorName), ibcDenom) - s.Require().True(feeCollectorIbcCoin.Amount.Equal(providerExpectedRewards[0].Amount)) + // Pass two blocks + s.consumerChain.NextBlock() + s.consumerChain.NextBlock() - // Advance a block and check that the coins are transfered from fee collector to fee pool - s.providerChain.NextBlock() - feeCollectorIbcCoin = providerBankKeeper.GetBalance(s.providerCtx(), authtypes.NewModuleAddress(authtypes.FeeCollectorName), ibcDenom) - s.Require().Equal(math.ZeroInt(), feeCollectorIbcCoin.Amount) + // Save the consumer validators total outstanding rewards on the provider + consumerValsOutstandingRewardsFunc := func(ctx sdk.Context) sdk.DecCoins { + totalRewards := sdk.DecCoins{} + for _, v := range providerKeeper.GetConsumerValSet(ctx, s.consumerChain.ChainID) { + val, err := s.providerApp.GetTestStakingKeeper().GetValidatorByConsAddr(ctx, sdk.ConsAddress(v.ProviderConsAddr)) + s.Require().NoError(err) + valAddr, err := sdk.ValAddressFromBech32(val.GetOperator()) + s.Require().NoError(err) + valReward, _ := providerDistributionKeeper.GetValidatorOutstandingRewards(ctx, valAddr) + totalRewards = totalRewards.Add(valReward.Rewards...) + } + return totalRewards + } + consuValsRewards := consumerValsOutstandingRewardsFunc(s.providerCtx()) - // check that the fee pool has the expected amount of coins - testDistKeeper := s.providerApp.GetTestDistributionKeeper() - // try casting to the sdk distribution keeper - sdkDistKeeper, ok := testDistKeeper.(sdkdistrkeeper.Keeper) - s.Require().True(ok) - s.Require().NotEmpty(sdkDistKeeper) + // increase the block height so validators are eligible for consumer rewards (see `IsEligibleForConsumerRewards`) + numberOfBlocksToStartReceivingRewards := + providerKeeper.GetNumberOfEpochsToStartReceivingRewards(s.providerCtx()) * providerKeeper.GetBlocksPerEpoch(s.providerCtx()) - feePool, err := sdkDistKeeper.FeePool.Get(s.providerCtx()) - s.Require().NoError(err) - s.Require().NotEmpty(feePool) + for s.providerCtx().BlockHeight() <= numberOfBlocksToStartReceivingRewards { + s.providerChain.NextBlock() + } - communityCoins := feePool.GetCommunityPool() - s.Require().True(communityCoins[ibcCoinIndex].Amount.Equal(sdk.NewDecCoinFromCoin(providerExpectedRewards[0]).Amount)) + // Transfer rewards from consumer to provider and distribute rewards to + // validators and community pool by calling BeginBlockRD + relayAllCommittedPackets( + s, + s.consumerChain, + s.transferPath, + transfertypes.PortID, + s.transferPath.EndpointA.ChannelID, + 1, + ) + + // Consumer allocations are distributed between the validators and the community pool. + // The decimals resulting from the distribution are expected to remain in the consumer allocations. + rewardsAlloc := providerKeeper.GetConsumerRewardsAllocation(s.providerCtx(), s.consumerChain.ChainID) + remainingAlloc := rewardsAlloc.Rewards.AmountOf(rewardsIBCdenom) + s.Require().True(remainingAlloc.LTE(math.LegacyOneDec())) + + // Check that the reward pool still holds the coins from the first transfer + // which were never allocated since they were not whitelisted + // plus the remaining decimals from the second transfer. + rewardCoins = providerBankKeeper.GetAllBalances(s.providerCtx(), rewardPool) + s.Require().Equal( + math.LegacyNewDecFromInt(rewardCoins.AmountOf(rewardsIBCdenom)), + math.LegacyNewDecFromInt(providerExpRewardsAmount).Add(remainingAlloc), + ) + + // Check that the distribution module account balance is equal to the consumer rewards + consuValsRewardsReceived := consumerValsOutstandingRewardsFunc(s.providerCtx()).Sub(consuValsRewards) + distrAcct := providerDistributionKeeper.GetDistributionAccount(s.providerCtx()) + distrAcctBalance := providerBankKeeper.GetAllBalances(s.providerCtx(), distrAcct.GetAddress()) + + s.Require().Equal( + // ceil the total consumer rewards since the validators allocation use some rounding + consuValsRewardsReceived.AmountOf(rewardsIBCdenom).Ceil(), + math.LegacyNewDecFromInt(distrAcctBalance.AmountOf(rewardsIBCdenom)), + ) } // TestSendRewardsRetries tests that failed reward transmissions are retried every BlocksPerDistributionTransmission blocks @@ -472,6 +521,286 @@ func (s *CCVTestSuite) TestSendRewardsToProvider() { } } +// TestIBCTransferMiddleware tests the logic of the IBC transfer OnRecvPacket callback +func (s *CCVTestSuite) TestIBCTransferMiddleware() { + var ( + data transfertypes.FungibleTokenPacketData + packet channeltypes.Packet + getIBCDenom func(string, string) string + ) + + testCases := []struct { + name string + setup func(sdk.Context, *providerkeeper.Keeper, icstestingutils.TestBankKeeper) + rewardsAllocated bool + expErr bool + }{ + { + "invalid IBC packet", + func(sdk.Context, *providerkeeper.Keeper, icstestingutils.TestBankKeeper) { + packet = channeltypes.Packet{} + }, + false, + true, + }, + { + "IBC packet sender isn't a consumer chain", + func(ctx sdk.Context, keeper *providerkeeper.Keeper, bankKeeper icstestingutils.TestBankKeeper) { + // make the sender consumer chain impossible to identify + packet.DestinationChannel = "CorruptedChannelId" + }, + false, + false, + }, + { + "IBC Transfer recipient is not the consumer rewards pool address", + func(ctx sdk.Context, keeper *providerkeeper.Keeper, bankKeeper icstestingutils.TestBankKeeper) { + data.Receiver = "cosmos149lw9fktlqfed3zt8ah48r5czmsug5s7kw77u9" // random acct address + packet.Data = data.GetBytes() + }, + false, + false, + }, + { + "IBC Transfer coin denom isn't registered", + func(ctx sdk.Context, keeper *providerkeeper.Keeper, bankKeeper icstestingutils.TestBankKeeper) {}, + false, + false, + }, + { + "successful token transfer to empty pool", + func(ctx sdk.Context, keeper *providerkeeper.Keeper, bankKeeper icstestingutils.TestBankKeeper) { + keeper.SetConsumerRewardDenom( + s.providerCtx(), + getIBCDenom(packet.DestinationPort, packet.DestinationChannel), + ) + }, + true, + false, + }, + { + "successful token transfer to filled pool", + func(ctx sdk.Context, keeper *providerkeeper.Keeper, bankKeeper icstestingutils.TestBankKeeper) { + keeper.SetConsumerRewardDenom( + ctx, + getIBCDenom(packet.DestinationPort, packet.DestinationChannel), + ) + + // fill consumer reward pool + bankKeeper.SendCoinsFromAccountToModule( + ctx, + s.providerChain.SenderAccount.GetAddress(), + providertypes.ConsumerRewardsPool, + sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100_000))), + ) + // update consumer allocation + keeper.SetConsumerRewardsAllocation( + ctx, + s.consumerChain.ChainID, + providertypes.ConsumerRewardsAllocation{ + Rewards: sdk.NewDecCoins(sdk.NewDecCoin(sdk.DefaultBondDenom, math.NewInt(100_000))), + }, + ) + }, + true, + false, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + s.SetupTest() + s.SetupCCVChannel(s.path) + s.SetupTransferChannel() + + providerKeeper := s.providerApp.GetProviderKeeper() + bankKeeper := s.providerApp.GetTestBankKeeper() + amount := math.NewInt(100) + + data = transfertypes.NewFungibleTokenPacketData( // can be explicitly changed in setup + sdk.DefaultBondDenom, + amount.String(), + authtypes.NewModuleAddress(consumertypes.ConsumerToSendToProviderName).String(), + providerKeeper.GetConsumerRewardsPoolAddressStr(s.providerCtx()), + "", + ) + + packet = channeltypes.NewPacket( // can be explicitly changed in setup + data.GetBytes(), + uint64(1), + s.transferPath.EndpointA.ChannelConfig.PortID, + s.transferPath.EndpointA.ChannelID, + s.transferPath.EndpointB.ChannelConfig.PortID, + s.transferPath.EndpointB.ChannelID, + clienttypes.NewHeight(1, 100), + 0, + ) + + providerKeeper.SetConsumerRewardDenom(s.providerCtx(), + transfertypes.GetPrefixedDenom( + packet.DestinationPort, + packet.DestinationChannel, + sdk.DefaultBondDenom, + ), + ) + + getIBCDenom = func(dstPort, dstChannel string) string { + return transfertypes.ParseDenomTrace( + transfertypes.GetPrefixedDenom( + packet.DestinationPort, + packet.DestinationChannel, + sdk.DefaultBondDenom, + ), + ).IBCDenom() + } + + tc.setup(s.providerCtx(), &providerKeeper, bankKeeper) + + cbs, ok := s.providerChain.App.GetIBCKeeper().Router.GetRoute(transfertypes.ModuleName) + s.Require().True(ok) + + // save the IBC transfer rewards transferred + rewardsPoolBalance := bankKeeper.GetAllBalances(s.providerCtx(), sdk.MustAccAddressFromBech32(data.Receiver)) + + // save the consumer's rewards allocated + consumerRewardsAllocations := providerKeeper.GetConsumerRewardsAllocation(s.providerCtx(), s.consumerChain.ChainID) + + // execute middleware OnRecvPacket logic + ack := cbs.OnRecvPacket(s.providerCtx(), packet, sdk.AccAddress{}) + + // compute expected rewards with provider denom + expRewards := sdk.Coin{ + Amount: amount, + Denom: getIBCDenom(packet.DestinationPort, packet.DestinationChannel), + } + + // compute the balance and allocation difference + rewardsTransferred := bankKeeper.GetAllBalances(s.providerCtx(), sdk.MustAccAddressFromBech32(data.Receiver)). + Sub(rewardsPoolBalance...) + rewardsAllocated := providerKeeper.GetConsumerRewardsAllocation(s.providerCtx(), s.consumerChain.ChainID). + Rewards.Sub(consumerRewardsAllocations.Rewards) + + if !tc.expErr { + s.Require().True(ack.Success()) + // verify that the consumer rewards pool received the IBC coins + s.Require().Equal(rewardsTransferred, sdk.Coins{expRewards}) + + if tc.rewardsAllocated { + // check the data receiver address is set to the consumer rewards pool address + s.Require().Equal(data.GetReceiver(), providerKeeper.GetConsumerRewardsPoolAddressStr(s.providerCtx())) + + // verify that consumer rewards allocation is updated + s.Require().Equal(rewardsAllocated, sdk.NewDecCoinsFromCoins(expRewards)) + } else { + // verify that consumer rewards aren't allocated + s.Require().Empty(rewardsAllocated) + } + } else { + s.Require().False(ack.Success()) + } + }) + } +} + +// TestAllocateTokens is a happy-path test of the consumer rewards pool allocation +// to opted-in validators and the community pool +func (s *CCVTestSuite) TestAllocateTokens() { + // set up channel and delegate some tokens in order for validator set update to be sent to the consumer chain + s.SetupAllCCVChannels() + providerKeeper := s.providerApp.GetProviderKeeper() + bankKeeper := s.providerApp.GetTestBankKeeper() + distributionKeeper := s.providerApp.GetTestDistributionKeeper() + accountKeeper := s.providerApp.GetTestAccountKeeper() + + getDistrAcctBalFn := func(ctx sdk.Context) sdk.DecCoins { + bal := bankKeeper.GetAllBalances(ctx, accountKeeper.GetModuleAccount(ctx, distrtypes.ModuleName).GetAddress()) + return sdk.NewDecCoinsFromCoins(bal...) + } + + totalRewards := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100))} + + // increase the block height so validators are eligible for consumer rewards (see `IsEligibleForConsumerRewards`) + numberOfBlocksToStartReceivingRewards := providerKeeper.GetNumberOfEpochsToStartReceivingRewards( + s.providerCtx()) * providerKeeper.GetBlocksPerEpoch(s.providerCtx()) + providerCtx := s.providerCtx().WithBlockHeight(numberOfBlocksToStartReceivingRewards + s.providerCtx().BlockHeight()) + + // fund consumer rewards pool + bankKeeper.SendCoinsFromAccountToModule( + providerCtx, + s.providerChain.SenderAccount.GetAddress(), + providertypes.ConsumerRewardsPool, + totalRewards, + ) + + // Allocate rewards evenly between consumers + rewardsPerChain := totalRewards.QuoInt(math.NewInt(int64(len(s.consumerBundles)))) + for chainID := range s.consumerBundles { + // update consumer allocation + providerKeeper.SetConsumerRewardsAllocation( + providerCtx, + chainID, + providertypes.ConsumerRewardsAllocation{ + Rewards: sdk.NewDecCoinsFromCoins(rewardsPerChain...), + }, + ) + } + + // iterate over the validators and verify that no validator has outstanding rewards + totalValsRewards := sdk.DecCoins{} + for _, val := range s.providerChain.Vals.Validators { + valRewards, err := distributionKeeper.GetValidatorOutstandingRewards(providerCtx, sdk.ValAddress(val.Address)) + s.Require().NoError(err) + totalValsRewards = totalValsRewards.Add(valRewards.Rewards...) + } + + s.Require().True(totalValsRewards.IsZero()) + + // At this point the distribution module account + // only holds the community pool's tokens + // since there are no validators with outstanding rewards + lastCommPool := getDistrAcctBalFn(providerCtx) + + // execute BeginBlock to trigger the token allocation + providerKeeper.BeginBlockRD(providerCtx) + + valNum := len(s.providerChain.Vals.Validators) + consNum := len(s.consumerBundles) + + // compute the expected validators token allocation by subtracting the community tax + rewardsPerChainDec := sdk.NewDecCoinsFromCoins(rewardsPerChain...) + communityTax, err := distributionKeeper.GetCommunityTax(providerCtx) + s.Require().NoError(err) + + rewardsPerChainTrunc, _ := rewardsPerChainDec. + MulDecTruncate(math.LegacyOneDec().Sub(communityTax)).TruncateDecimal() + validatorsExpRewardsPerChain := sdk.NewDecCoinsFromCoins(rewardsPerChainTrunc...).QuoDec(math.LegacyNewDec(int64(valNum))) + // multiply by the number of consumers + validatorsExpRewards := validatorsExpRewardsPerChain.MulDec(math.LegacyNewDec(int64(consNum))) + + // verify the validator tokens allocation + // note that the validators have the same voting power to keep things simple + for _, val := range s.providerChain.Vals.Validators { + valRewards, err := distributionKeeper.GetValidatorOutstandingRewards(providerCtx, sdk.ValAddress(val.Address)) + s.Require().NoError(err) + + s.Require().Equal( + valRewards.Rewards, + validatorsExpRewards, + ) + } + + // check that the total expected rewards are transferred to the distribution module account + + // store the decimal remainders in the consumer reward allocations + allocRemainderPerChain := providerKeeper.GetConsumerRewardsAllocation(providerCtx, s.consumerChain.ChainID).Rewards + + // compute the total rewards distributed to the distribution module balance (validator outstanding rewards + community pool tax), + totalRewardsDistributed := sdk.NewDecCoinsFromCoins(totalRewards...).Sub(allocRemainderPerChain.MulDec(math.LegacyNewDec(int64(consNum)))) + + // compare the expected total rewards against the distribution module balance + s.Require().Equal(lastCommPool.Add(totalRewardsDistributed...), getDistrAcctBalFn(providerCtx)) +} + // getEscrowBalance gets the current balances in the escrow account holding the transferred tokens to the provider func (s *CCVTestSuite) getEscrowBalance() sdk.Coins { consumerBankKeeper := s.consumerApp.GetTestBankKeeper() @@ -503,3 +832,326 @@ func (s *CCVTestSuite) prepareRewardDist() { blocksToGo := bpdt - blocksSinceLastTrans s.coordinator.CommitNBlocks(s.consumerChain, uint64(blocksToGo)) } + +func (s *CCVTestSuite) TestAllocateTokensToConsumerValidators() { + providerKeeper := s.providerApp.GetProviderKeeper() + distributionKeeper := s.providerApp.GetTestDistributionKeeper() + bankKeeper := s.providerApp.GetTestBankKeeper() + + chainID := s.consumerChain.ChainID + + testCases := []struct { + name string + consuValLen int + tokens sdk.DecCoins + rate math.LegacyDec + expAllocated sdk.DecCoins + }{ + { + name: "tokens are empty", + tokens: sdk.DecCoins{}, + rate: math.LegacyZeroDec(), + expAllocated: nil, + }, + { + name: "consumer valset is empty - total voting power is zero", + tokens: sdk.DecCoins{sdk.NewDecCoin(sdk.DefaultBondDenom, math.NewInt(100_000))}, + rate: math.LegacyZeroDec(), + expAllocated: nil, + }, + { + name: "expect all tokens to be allocated to a single validator", + consuValLen: 1, + tokens: sdk.DecCoins{sdk.NewDecCoin(sdk.DefaultBondDenom, math.NewInt(999))}, + rate: math.LegacyNewDecWithPrec(5, 1), + expAllocated: sdk.DecCoins{sdk.NewDecCoin(sdk.DefaultBondDenom, math.NewInt(999))}, + }, + { + name: "expect tokens to be allocated evenly between validators", + consuValLen: 2, + tokens: sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, math.LegacyNewDecFromIntWithPrec(math.NewInt(999), 2))}, + rate: math.LegacyOneDec(), + expAllocated: sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, math.LegacyNewDecFromIntWithPrec(math.NewInt(999), 2))}, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + ctx, _ := s.providerCtx().CacheContext() + + // increase the block height so validators are eligible for consumer rewards (see `IsEligibleForConsumerRewards`) + ctx = ctx.WithBlockHeight(providerKeeper.GetNumberOfEpochsToStartReceivingRewards(ctx)*providerKeeper.GetBlocksPerEpoch(ctx) + + ctx.BlockHeight()) + + // change the consumer valset + consuVals := providerKeeper.GetConsumerValSet(ctx, chainID) + providerKeeper.DeleteConsumerValSet(ctx, chainID) + providerKeeper.SetConsumerValSet(ctx, chainID, consuVals[0:tc.consuValLen]) + consuVals = providerKeeper.GetConsumerValSet(ctx, chainID) + + // set the same consumer commission rate for all consumer validators + for _, v := range consuVals { + provAddr := providertypes.NewProviderConsAddress(sdk.ConsAddress(v.ProviderConsAddr)) + err := providerKeeper.SetConsumerCommissionRate( + ctx, + chainID, + provAddr, + tc.rate, + ) + s.Require().NoError(err) + } + + // allocate tokens + res := providerKeeper.AllocateTokensToConsumerValidators( + ctx, + chainID, + tc.tokens, + ) + + // check that the expected result is returned + s.Require().Equal(tc.expAllocated, res) + + if !tc.expAllocated.Empty() { + // rewards are expected to be allocated evenly between validators + rewardsPerVal := tc.expAllocated.QuoDec(math.LegacyNewDec(int64(len(consuVals)))) + + // check that the rewards are allocated to validators + for _, v := range consuVals { + valAddr := sdk.ValAddress(v.ProviderConsAddr) + rewards, err := s.providerApp.GetTestDistributionKeeper().GetValidatorOutstandingRewards( + ctx, + valAddr, + ) + s.Require().NoError(err) + s.Require().Equal(rewardsPerVal, rewards.Rewards) + + // send rewards to the distribution module + valRewardsTrunc, _ := rewards.Rewards.TruncateDecimal() + err = bankKeeper.SendCoinsFromAccountToModule( + ctx, + s.providerChain.SenderAccount.GetAddress(), + distrtypes.ModuleName, + valRewardsTrunc) + s.Require().NoError(err) + + // check that validators can withdraw their rewards + withdrawnCoins, err := distributionKeeper.WithdrawValidatorCommission( + ctx, + valAddr, + ) + s.Require().NoError(err) + + // check that the withdrawn coins is equal to the entire reward amount + // times the set consumer commission rate + commission := rewards.Rewards.MulDec(tc.rate) + c, _ := commission.TruncateDecimal() + s.Require().Equal(withdrawnCoins, c) + + // check that validators get rewards in their balance + s.Require().Equal(withdrawnCoins, bankKeeper.GetAllBalances(ctx, sdk.AccAddress(valAddr))) + } + } else { + for _, v := range consuVals { + valAddr := sdk.ValAddress(v.ProviderConsAddr) + rewards, err := s.providerApp.GetTestDistributionKeeper().GetValidatorOutstandingRewards( + ctx, + valAddr, + ) + s.Require().NoError(err) + s.Require().Zero(rewards.Rewards) + } + } + }) + } +} + +// TestAllocateTokensToConsumerValidatorsWithDifferentValidatorHeights tests `AllocateTokensToConsumerValidators` with +// consumer validators that have different heights. Specifically, test that validators that have been consumer validators +// for some time receive rewards, while validators that recently became consumer validators do not receive rewards. +func (s *CCVTestSuite) TestAllocateTokensToConsumerValidatorsWithDifferentValidatorHeights() { + // Note this test is an adaptation of a `TestAllocateTokensToConsumerValidators` testcase. + providerKeeper := s.providerApp.GetProviderKeeper() + distributionKeeper := s.providerApp.GetTestDistributionKeeper() + bankKeeper := s.providerApp.GetTestBankKeeper() + + chainID := s.consumerChain.ChainID + + tokens := sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, math.LegacyNewDecFromIntWithPrec(math.NewInt(999), 2))} + rate := math.LegacyOneDec() + expAllocated := sdk.DecCoins{sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, math.LegacyNewDecFromIntWithPrec(math.NewInt(999), 2))} + + ctx, _ := s.providerCtx().CacheContext() + // If the provider chain has not yet reached `GetNumberOfEpochsToStartReceivingRewards * GetBlocksPerEpoch` block height, + // then all validators receive rewards (see `IsEligibleForConsumerRewards`). In this test, we want to check whether + // validators receive rewards or not based on how long they have been consumer validators. Because of this, we increase the block height. + ctx = ctx.WithBlockHeight(providerKeeper.GetNumberOfEpochsToStartReceivingRewards(ctx)*providerKeeper.GetBlocksPerEpoch(ctx) + 1) + + // update the consumer validators + consuVals := providerKeeper.GetConsumerValSet(ctx, chainID) + // first 2 validators were consumer validators since block height 1 and hence get rewards + consuVals[0].JoinHeight = 1 + consuVals[1].JoinHeight = 1 + // last 2 validators were consumer validators since block height 2 and hence do not get rewards because they + // have not been consumer validators for `GetNumberOfEpochsToStartReceivingRewards * GetBlocksPerEpoch` blocks + consuVals[2].JoinHeight = 2 + consuVals[3].JoinHeight = 2 + providerKeeper.SetConsumerValSet(ctx, chainID, consuVals) + + providerKeeper.DeleteConsumerValSet(ctx, chainID) + providerKeeper.SetConsumerValSet(ctx, chainID, consuVals) + consuVals = providerKeeper.GetConsumerValSet(ctx, chainID) + + // set the same consumer commission rate for all consumer validators + for _, v := range consuVals { + provAddr := providertypes.NewProviderConsAddress(sdk.ConsAddress(v.ProviderConsAddr)) + err := providerKeeper.SetConsumerCommissionRate( + ctx, + chainID, + provAddr, + rate, + ) + s.Require().NoError(err) + } + + // allocate tokens + res := providerKeeper.AllocateTokensToConsumerValidators( + ctx, + chainID, + tokens, + ) + + // check that the expected result is returned + s.Require().Equal(expAllocated, res) + + // rewards are expected to be allocated evenly between validators 3 and 4 + rewardsPerVal := expAllocated.QuoDec(math.LegacyNewDec(int64(2))) + + // assert that the rewards are allocated to the first 2 validators + for _, v := range consuVals[0:2] { + valAddr := sdk.ValAddress(v.ProviderConsAddr) + rewards, err := s.providerApp.GetTestDistributionKeeper().GetValidatorOutstandingRewards( + ctx, + valAddr, + ) + s.Require().NoError(err) + s.Require().Equal(rewardsPerVal, rewards.Rewards) + + // send rewards to the distribution module + valRewardsTrunc, _ := rewards.Rewards.TruncateDecimal() + err = bankKeeper.SendCoinsFromAccountToModule( + ctx, + s.providerChain.SenderAccount.GetAddress(), + distrtypes.ModuleName, + valRewardsTrunc) + s.Require().NoError(err) + + // check that validators can withdraw their rewards + withdrawnCoins, err := distributionKeeper.WithdrawValidatorCommission( + ctx, + valAddr, + ) + s.Require().NoError(err) + + // check that the withdrawn coins is equal to the entire reward amount + // times the set consumer commission rate + commission := rewards.Rewards.MulDec(rate) + c, _ := commission.TruncateDecimal() + s.Require().Equal(withdrawnCoins, c) + + // check that validators get rewards in their balance + s.Require().Equal(withdrawnCoins, bankKeeper.GetAllBalances(ctx, sdk.AccAddress(valAddr))) + } + + // assert that no rewards are allocated to the last 2 validators because they have not been consumer validators + // for at least `GetNumberOfEpochsToStartReceivingRewards * GetBlocksPerEpoch` blocks + for _, v := range consuVals[2:4] { + valAddr := sdk.ValAddress(v.ProviderConsAddr) + rewards, err := s.providerApp.GetTestDistributionKeeper().GetValidatorOutstandingRewards( + ctx, + valAddr, + ) + s.Require().NoError(err) + s.Require().Zero(rewards.Rewards) + } +} + +// TestMultiConsumerRewardsDistribution tests the rewards distribution of multiple consumers chains +func (s *CCVTestSuite) TestMultiConsumerRewardsDistribution() { + s.SetupAllCCVChannels() + s.SetupAllTransferChannels() + + providerBankKeeper := s.providerApp.GetTestBankKeeper() + providerAccountKeeper := s.providerApp.GetTestAccountKeeper() + + // check that the reward provider pool is empty + rewardPool := providerAccountKeeper.GetModuleAccount(s.providerCtx(), providertypes.ConsumerRewardsPool).GetAddress() + rewardCoins := providerBankKeeper.GetAllBalances(s.providerCtx(), rewardPool) + s.Require().Empty(rewardCoins) + + // totalConsumerRewards := sdk.Coins{} + + // Iterate over the consumers and perform the reward distribution + // to the provider + for chainID := range s.consumerBundles { + bundle := s.consumerBundles[chainID] + consumerKeeper := bundle.App.GetConsumerKeeper() + bankKeeper := bundle.App.GetTestBankKeeper() + accountKeeper := bundle.App.GetTestAccountKeeper() + + // set the consumer reward denom and the block per distribution params + params := consumerKeeper.GetConsumerParams(bundle.GetCtx()) + params.RewardDenoms = []string{sdk.DefaultBondDenom} + // set the reward distribution to be performed during the next block + params.BlocksPerDistributionTransmission = int64(1) + consumerKeeper.SetParams(bundle.GetCtx(), params) + + // transfer the consumer reward pool to the provider + var rewardsPerConsumer sdk.Coin + + // check the consumer pool balance + // Note that for a democracy consumer chain the pool may already be filled + pool := bankKeeper.GetAllBalances( + bundle.GetCtx(), + accountKeeper.GetModuleAccount(bundle.GetCtx(), consumertypes.ConsumerToSendToProviderName).GetAddress(), + ) + if pool.Empty() { + // if pool is empty, fill it with some tokens + rewardsPerConsumer = sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100)) + err := bankKeeper.SendCoinsFromAccountToModule( + bundle.GetCtx(), + bundle.Chain.SenderAccount.GetAddress(), + consumertypes.ConsumerToSendToProviderName, + sdk.NewCoins(rewardsPerConsumer), + ) + s.Require().NoError(err) + } + + // perform the reward transfer + bundle.Chain.NextBlock() + + // construct the denom of the reward tokens for the provider + prefixedDenom := transfertypes.GetPrefixedDenom( + transfertypes.PortID, + bundle.TransferPath.EndpointB.ChannelID, + rewardsPerConsumer.Denom, + ) + provIBCDenom := transfertypes.ParseDenomTrace(prefixedDenom).IBCDenom() + + providerRewards := providerBankKeeper.GetBalance(s.providerCtx(), rewardPool, prefixedDenom) + + // relay IBC transfer packet from consumer to provider + // Note that relaying increases the pool rewards with the democracy consumers + relayAllCommittedPackets( + s, + bundle.Chain, + bundle.TransferPath, + transfertypes.PortID, + bundle.TransferPath.EndpointA.ChannelID, + 1, + ) + + // Check the provider received the rewards + providerRewardsDelta := providerBankKeeper.GetBalance(s.providerCtx(), rewardPool, prefixedDenom).Sub(providerRewards) + s.Require().True(providerRewardsDelta.Amount.GTE(pool.AmountOf(provIBCDenom))) + } +} diff --git a/tests/integration/key_assignment.go b/tests/integration/key_assignment.go index b600c46b19..8d8826daf9 100644 --- a/tests/integration/key_assignment.go +++ b/tests/integration/key_assignment.go @@ -79,7 +79,7 @@ func (s *CCVTestSuite) TestKeyAssignment() { }, false, 2, }, { - "double same-key assignment in same block", func(pk *providerkeeper.Keeper) error { + "double same-key assignment in same block by different vals", func(pk *providerkeeper.Keeper) error { // establish CCV channel s.SetupCCVChannel(s.path) @@ -90,8 +90,9 @@ func (s *CCVTestSuite) TestKeyAssignment() { return err } - // same key assignment - err = pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey) + // same key assignment, but different validator + validator2, _ := generateNewConsumerKey(s, 1) + err = pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator2, consumerKey) if err != nil { return err } @@ -100,6 +101,28 @@ func (s *CCVTestSuite) TestKeyAssignment() { return nil }, true, 2, }, + { + "double same-key assignment in same block by same val", func(pk *providerkeeper.Keeper) error { + // establish CCV channel + s.SetupCCVChannel(s.path) + + // key assignment + validator, consumerKey := generateNewConsumerKey(s, 0) + err := pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey) + if err != nil { + return err + } + + // same key assignment, but different validator + err = pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey) + if err != nil { + return err + } + s.nextEpoch() + + return nil + }, false, 2, + }, { "double key assignment in same block", func(pk *providerkeeper.Keeper) error { // establish CCV channel @@ -124,7 +147,7 @@ func (s *CCVTestSuite) TestKeyAssignment() { }, false, 2, }, { - "double same-key assignment in different blocks", func(pk *providerkeeper.Keeper) error { + "double same-key assignment in different blocks by different vals", func(pk *providerkeeper.Keeper) error { // establish CCV channel s.SetupCCVChannel(s.path) @@ -137,7 +160,8 @@ func (s *CCVTestSuite) TestKeyAssignment() { s.nextEpoch() // same key assignment - err = pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey) + validator2, _ := generateNewConsumerKey(s, 1) + err = pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator2, consumerKey) if err != nil { return err } @@ -146,6 +170,29 @@ func (s *CCVTestSuite) TestKeyAssignment() { return nil }, true, 2, }, + { + "double same-key assignment in different blocks by same val", func(pk *providerkeeper.Keeper) error { + // establish CCV channel + s.SetupCCVChannel(s.path) + + // key assignment + validator, consumerKey := generateNewConsumerKey(s, 0) + err := pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey) + if err != nil { + return err + } + s.nextEpoch() + + // same key assignment + err = pk.AssignConsumerKey(s.providerCtx(), s.consumerChain.ChainID, validator, consumerKey) + if err != nil { + return err + } + s.nextEpoch() + + return nil + }, false, 2, + }, { "double key assignment in different blocks", func(pk *providerkeeper.Keeper) error { // establish CCV channel diff --git a/tests/integration/provider_gov_hooks.go b/tests/integration/provider_gov_hooks.go index d1970c1b72..6c99f17c64 100644 --- a/tests/integration/provider_gov_hooks.go +++ b/tests/integration/provider_gov_hooks.go @@ -38,7 +38,8 @@ func (s *CCVTestSuite) TestAfterPropSubmissionAndVotingPeriodEnded() { providerKeeper.Hooks().AfterProposalSubmission(ctx, proposal.Id) // verify that the proposal ID is created - proposalIdOnProvider := providerKeeper.GetProposedConsumerChain(ctx, proposal.Id) + proposalIdOnProvider, ok := providerKeeper.GetProposedConsumerChain(ctx, proposal.Id) + s.Require().True(ok) s.Require().NotEmpty(proposalIdOnProvider) s.Require().Equal(content.ChainId, proposalIdOnProvider) diff --git a/tests/integration/setup.go b/tests/integration/setup.go index d8d3f3107b..eeb980200f 100644 --- a/tests/integration/setup.go +++ b/tests/integration/setup.go @@ -160,12 +160,16 @@ func (suite *CCVTestSuite) SetupTest() { providerKeeper.DeletePendingConsumerAdditionProps(suite.providerCtx(), ps...) // start consumer chains - numConsumers := 5 suite.consumerBundles = make(map[string]*icstestingutils.ConsumerBundle) - for i := 0; i < numConsumers; i++ { + for i := 0; i < icstestingutils.NumConsumers; i++ { bundle := suite.setupConsumerCallback(&suite.Suite, suite.coordinator, i) suite.consumerBundles[bundle.Chain.ChainID] = bundle suite.registerPacketSniffer(bundle.Chain) + + // check that TopN is correctly set for the consumer + topN, found := providerKeeper.GetTopN(suite.providerCtx(), bundle.Chain.ChainID) + suite.Require().True(found) + suite.Require().Equal(bundle.TopN, topN) } // initialize each consumer chain with it's corresponding genesis state @@ -249,7 +253,6 @@ func initConsumerChain( ) s.Require().True(found, "provider endpoint clientID not found") bundle.Path.EndpointB.ClientID = providerEndpointClientID - // Set consumer endpoint's clientID consumerKeeper := bundle.GetKeeper() consumerEndpointClientID, found := consumerKeeper.GetProviderClientID(bundle.GetCtx()) @@ -329,34 +332,70 @@ func (suite *CCVTestSuite) ExecuteCCVChannelHandshake(path *ibctesting.Path) { // TODO: Make SetupTransferChannel functional for multiple consumers by pattern matching SetupCCVChannel. // See: https://github.com/cosmos/interchain-security/issues/506 +// SetupTransferChannel setup the transfer channel of the first consumer chain among multiple func (suite *CCVTestSuite) SetupTransferChannel() { - // transfer path will use the same connection as ccv path + suite.setupTransferChannel( + suite.transferPath, + suite.path, + suite.consumerApp.GetConsumerKeeper().GetDistributionTransmissionChannel( + suite.consumerChain.GetContext(), + ), + ) +} - suite.transferPath.EndpointA.ClientID = suite.path.EndpointA.ClientID - suite.transferPath.EndpointA.ConnectionID = suite.path.EndpointA.ConnectionID - suite.transferPath.EndpointB.ClientID = suite.path.EndpointB.ClientID - suite.transferPath.EndpointB.ConnectionID = suite.path.EndpointB.ConnectionID +func (suite *CCVTestSuite) setupTransferChannel( + transferPath *ibctesting.Path, + ccvPath *ibctesting.Path, + channelID string, +) { + // transfer path will use the same connection as ccv path + transferPath.EndpointA.ClientID = ccvPath.EndpointA.ClientID + transferPath.EndpointA.ConnectionID = ccvPath.EndpointA.ConnectionID + transferPath.EndpointB.ClientID = ccvPath.EndpointB.ClientID + transferPath.EndpointB.ConnectionID = ccvPath.EndpointB.ConnectionID // CCV channel handshake will automatically initiate transfer channel handshake on ACK // so transfer channel will be on stage INIT when CompleteSetupCCVChannel returns. - suite.transferPath.EndpointA.ChannelID = suite.consumerApp.GetConsumerKeeper().GetDistributionTransmissionChannel( - suite.consumerChain.GetContext()) + transferPath.EndpointA.ChannelID = channelID // Complete TRY, ACK, CONFIRM for transfer path - err := suite.transferPath.EndpointB.ChanOpenTry() + err := transferPath.EndpointB.ChanOpenTry() suite.Require().NoError(err) - err = suite.transferPath.EndpointA.ChanOpenAck() + err = transferPath.EndpointA.ChanOpenAck() suite.Require().NoError(err) - err = suite.transferPath.EndpointB.ChanOpenConfirm() + err = transferPath.EndpointB.ChanOpenConfirm() suite.Require().NoError(err) // ensure counterparty is up to date - err = suite.transferPath.EndpointA.UpdateClient() + err = transferPath.EndpointA.UpdateClient() suite.Require().NoError(err) } +// SetupAllTransferChannel setup all consumer chains transfer channel +func (suite *CCVTestSuite) SetupAllTransferChannels() { + // setup the first consumer transfer channel + suite.SetupTransferChannel() + + // setup all the remaining consumers transfer channels + for chainID := range suite.consumerBundles { + // skip fist consumer + if chainID == suite.consumerChain.ChainID { + continue + } + + // get the bundle for the chain ID + bundle := suite.consumerBundles[chainID] + // setup the transfer channel + suite.setupTransferChannel( + bundle.TransferPath, + bundle.Path, + bundle.App.GetConsumerKeeper().GetDistributionTransmissionChannel(bundle.GetCtx()), + ) + } +} + func (s CCVTestSuite) validateEndpointsClientConfig(consumerBundle icstestingutils.ConsumerBundle) { //nolint:govet // this is a test so we can copy locks consumerKeeper := consumerBundle.GetKeeper() providerStakingKeeper := s.providerApp.GetTestStakingKeeper() diff --git a/tests/integration/slashing.go b/tests/integration/slashing.go index de5c7171e9..9f29c2806c 100644 --- a/tests/integration/slashing.go +++ b/tests/integration/slashing.go @@ -414,6 +414,15 @@ func (suite *CCVTestSuite) TestOnRecvSlashPacketErrors() { // Check expected behavior for handling SlashPackets for downtime infractions slashPacketData.Infraction = stakingtypes.Infraction_INFRACTION_DOWNTIME + // Expect packet to be handled if the validator didn't opt in + ackResult, err = providerKeeper.OnRecvSlashPacket(ctx, packet, *slashPacketData) + suite.Require().NoError(err, "no error expected") + suite.Require().Equal(ccv.SlashPacketHandledResult, ackResult, "expected successful ack") + + providerKeeper.SetConsumerValidator(ctx, firstBundle.Chain.ChainID, providertypes.ConsumerValidator{ + ProviderConsAddr: validAddress, + }) + // Expect the packet to bounce if the slash meter is negative providerKeeper.SetSlashMeter(ctx, math.NewInt(-1)) ackResult, err = providerKeeper.OnRecvSlashPacket(ctx, packet, *slashPacketData) diff --git a/tests/integration/unbonding.go b/tests/integration/unbonding.go index dedc3d6555..6f027c3616 100644 --- a/tests/integration/unbonding.go +++ b/tests/integration/unbonding.go @@ -4,7 +4,8 @@ import ( "time" "cosmossdk.io/math" - + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) @@ -467,3 +468,62 @@ func (s *CCVTestSuite) TestRedelegationProviderFirst() { // Check that ccv unbonding op has been deleted checkCCVUnbondingOp(s, s.providerCtx(), s.consumerChain.ChainID, valsetUpdateID, false) } + +// This test reproduces a fixed bug when an inactive validator enters back into the active set. +// It used to cause a panic in the provider module hook called by AfterUnbondingInitiated +// during the staking module EndBlock. +func (s *CCVTestSuite) TestTooManyLastValidators() { + sk := s.providerApp.GetTestStakingKeeper() + pk := s.providerApp.GetProviderKeeper() + + getLastValsFn := func(ctx sdk.Context) []stakingtypes.Validator { + lastVals, err := pk.GetLastBondedValidators(s.providerCtx()) + s.Require().NoError(err) + return lastVals + } + + // get current staking params + p, err := sk.GetParams(s.providerCtx()) + s.Require().NoError(err) + + // get validators, which are all active at the moment + vals, err := sk.GetAllValidators(s.providerCtx()) + s.Require().NoError(err) + + s.Require().Equal(len(vals), len(getLastValsFn(s.providerCtx()))) + + // jail a validator + val := vals[0] + consAddr, err := val.GetConsAddr() + s.Require().NoError(err) + sk.Jail(s.providerCtx(), consAddr) + + // save the current number of bonded vals + lastVals := getLastValsFn(s.providerCtx()) + + // pass one block to apply the validator set changes + // (calls ApplyAndReturnValidatorSetUpdates in the the staking module EndBlock) + s.providerChain.NextBlock() + + // verify that the number of bonded validators is decreased by one + s.Require().Equal(len(lastVals)-1, len(getLastValsFn(s.providerCtx()))) + + // update maximum validator to equal the number of bonded validators + p.MaxValidators = uint32(len(getLastValsFn(s.providerCtx()))) + sk.SetParams(s.providerCtx(), p) + + // pass one block to apply validator set changes + s.providerChain.NextBlock() + + // unjail validator + // Note that since validators are sorted in descending order, the unjailed validator + // enters the active set again since it's ranked first by voting power. + sk.Unjail(s.providerCtx(), consAddr) + + // pass another block to update the validator set + // which causes a panic due to a GetLastValidator call in + // ApplyAndReturnValidatorSetUpdates where the staking module has a inconsistent state + s.Require().NotPanics(s.providerChain.NextBlock) + s.Require().NotPanics(func() { sk.ApplyAndReturnValidatorSetUpdates(s.providerCtx()) }) + s.Require().NotPanics(func() { getLastValsFn(s.providerCtx()) }) +} diff --git a/tests/mbt/driver/core.go b/tests/mbt/driver/core.go index 62ed11671c..2cd618096f 100644 --- a/tests/mbt/driver/core.go +++ b/tests/mbt/driver/core.go @@ -3,12 +3,11 @@ package main import ( "fmt" "log" + gomath "math" "strings" "testing" "time" - gomath "math" - "cosmossdk.io/math" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" @@ -33,7 +32,6 @@ import ( consumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" consumertypes "github.com/cosmos/interchain-security/v5/x/ccv/consumer/types" providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" - providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" "github.com/cosmos/interchain-security/v5/x/ccv/types" ) @@ -222,11 +220,7 @@ func (s *Driver) getStateString() string { state.WriteString("\n") state.WriteString("Consumers Chains:\n") - consumerChains := s.providerKeeper().GetAllConsumerChains(s.providerCtx()) - chainIds := make([]string, len(consumerChains)) - for i, consumerChain := range consumerChains { - chainIds[i] = consumerChain.ChainId - } + chainIds := s.providerKeeper().GetAllRegisteredConsumerChainIDs(s.providerCtx()) state.WriteString(strings.Join(chainIds, ", ")) state.WriteString("\n\n") @@ -264,11 +258,11 @@ func (s *Driver) getChainStateString(chain ChainId) string { if !s.isProviderChain(chain) { // Check whether the chain is in the consumer chains on the provider - consumerChains := s.providerKeeper().GetAllConsumerChains(s.providerCtx()) + consumerChainIDs := s.providerKeeper().GetAllRegisteredConsumerChainIDs(s.providerCtx()) found := false - for _, consumerChain := range consumerChains { - if consumerChain.ChainId == string(chain) { + for _, consumerChainID := range consumerChainIDs { + if consumerChainID == string(chain) { found = true } } @@ -371,16 +365,16 @@ func (s *Driver) endAndBeginBlock(chain ChainId, timeAdvancement time.Duration) return header } -func (s *Driver) runningConsumers() []providertypes.Chain { - consumersOnProvider := s.providerKeeper().GetAllConsumerChains(s.providerCtx()) +func (s *Driver) runningConsumerChainIDs() []ChainId { + consumerIDsOnProvider := s.providerKeeper().GetAllRegisteredConsumerChainIDs(s.providerCtx()) - consumersWithIntactChannel := make([]providertypes.Chain, 0) - for _, consumer := range consumersOnProvider { - if s.path(ChainId(consumer.ChainId)).Path.EndpointA.GetChannel().State == channeltypes.CLOSED || - s.path(ChainId(consumer.ChainId)).Path.EndpointB.GetChannel().State == channeltypes.CLOSED { + consumersWithIntactChannel := make([]ChainId, 0) + for _, consumerChainID := range consumerIDsOnProvider { + if s.path(ChainId(consumerChainID)).Path.EndpointA.GetChannel().State == channeltypes.CLOSED || + s.path(ChainId(consumerChainID)).Path.EndpointB.GetChannel().State == channeltypes.CLOSED { continue } - consumersWithIntactChannel = append(consumersWithIntactChannel, consumer) + consumersWithIntactChannel = append(consumersWithIntactChannel, ChainId(consumerChainID)) } return consumersWithIntactChannel } @@ -448,8 +442,8 @@ func (s *Driver) RequestSlash( // DeliverAcks delivers, for each path, // all possible acks (up to math.MaxInt many per path). func (s *Driver) DeliverAcks() { - for _, chain := range s.runningConsumers() { - path := s.path(ChainId(chain.ChainId)) + for _, chainID := range s.runningConsumerChainIDs() { + path := s.path(chainID) path.DeliverAcks(path.Path.EndpointA.Chain.ChainID, gomath.MaxInt) path.DeliverAcks(path.Path.EndpointB.Chain.ChainID, gomath.MaxInt) } diff --git a/tests/mbt/driver/mbt_test.go b/tests/mbt/driver/mbt_test.go index 3e2cfe7901..70fded614a 100644 --- a/tests/mbt/driver/mbt_test.go +++ b/tests/mbt/driver/mbt_test.go @@ -306,21 +306,21 @@ func RunItfTrace(t *testing.T, path string) { // needs a header of height H+1 to accept the packet // so, we do two blocks, one with a very small increment, // and then another to increment the rest of the time - runningConsumersBefore := driver.runningConsumers() + runningConsumerChainIDsBefore := driver.runningConsumerChainIDs() driver.endAndBeginBlock("provider", 1*time.Nanosecond) - for _, consumer := range driver.runningConsumers() { - UpdateProviderClientOnConsumer(t, driver, consumer.ChainId) + for _, consumerChainID := range driver.runningConsumerChainIDs() { + UpdateProviderClientOnConsumer(t, driver, string(consumerChainID)) } driver.endAndBeginBlock("provider", time.Duration(timeAdvancement)*time.Second-1*time.Nanosecond) - runningConsumersAfter := driver.runningConsumers() + runningConsumerChainIDsAfter := driver.runningConsumerChainIDs() // the consumers that were running before but not after must have timed out - for _, consumer := range runningConsumersBefore { + for _, consumerChainID := range runningConsumerChainIDsBefore { found := false - for _, consumerAfter := range runningConsumersAfter { - if consumerAfter.ChainId == consumer.ChainId { + for _, consumerChainIDAfter := range runningConsumerChainIDsAfter { + if consumerChainIDAfter == consumerChainID { found = true break } @@ -334,8 +334,8 @@ func RunItfTrace(t *testing.T, path string) { // because setting up chains will modify timestamps // when the coordinator is starting chains lastTimestamps := make(map[ChainId]time.Time, len(consumers)) - for _, consumer := range driver.runningConsumers() { - lastTimestamps[ChainId(consumer.ChainId)] = driver.runningTime(ChainId(consumer.ChainId)) + for _, consumerChainID := range driver.runningConsumerChainIDs() { + lastTimestamps[consumerChainID] = driver.runningTime(consumerChainID) } driver.coordinator.CurrentTime = driver.runningTime("provider") @@ -366,12 +366,12 @@ func RunItfTrace(t *testing.T, path string) { // for all connected consumers, update the clients... // unless it was the last consumer to be started, in which case it already has the header // as we called driver.setupConsumer - for _, consumer := range driver.runningConsumers() { - if len(consumersToStart) > 0 && consumer.ChainId == consumersToStart[len(consumersToStart)-1].Value.(string) { + for _, consumerChainID := range driver.runningConsumerChainIDs() { + if len(consumersToStart) > 0 && string(consumerChainID) == consumersToStart[len(consumersToStart)-1].Value.(string) { continue } - UpdateProviderClientOnConsumer(t, driver, consumer.ChainId) + UpdateProviderClientOnConsumer(t, driver, string(consumerChainID)) } case "EndAndBeginBlockForConsumer": @@ -492,33 +492,33 @@ func RunItfTrace(t *testing.T, path string) { t.Logf("Comparing model state to actual state...") // compare the running consumers - modelRunningConsumers := RunningConsumers(currentModelState) + modelRunningConsumerChainIDs := RunningConsumers(currentModelState) - systemRunningConsumers := driver.runningConsumers() - actualRunningConsumers := make([]string, len(systemRunningConsumers)) - for i, chain := range systemRunningConsumers { - actualRunningConsumers[i] = chain.ChainId + systemRunningConsumerChainIDs := driver.runningConsumerChainIDs() + actualRunningConsumerChainIDs := make([]string, len(systemRunningConsumerChainIDs)) + for i, chainID := range systemRunningConsumerChainIDs { + actualRunningConsumerChainIDs[i] = string(chainID) } // sort the slices so that we can compare them - sort.Slice(modelRunningConsumers, func(i, j int) bool { - return modelRunningConsumers[i] < modelRunningConsumers[j] + sort.Slice(modelRunningConsumerChainIDs, func(i, j int) bool { + return modelRunningConsumerChainIDs[i] < modelRunningConsumerChainIDs[j] }) - sort.Slice(actualRunningConsumers, func(i, j int) bool { - return actualRunningConsumers[i] < actualRunningConsumers[j] + sort.Slice(actualRunningConsumerChainIDs, func(i, j int) bool { + return actualRunningConsumerChainIDs[i] < actualRunningConsumerChainIDs[j] }) - require.Equal(t, modelRunningConsumers, actualRunningConsumers, "Running consumers do not match") + require.Equal(t, modelRunningConsumerChainIDs, actualRunningConsumerChainIDs, "Running consumers do not match") // check validator sets - provider current validator set should be the one from the staking keeper - CompareValidatorSets(t, driver, currentModelState, actualRunningConsumers, realAddrsToModelConsAddrs) + CompareValidatorSets(t, driver, currentModelState, actualRunningConsumerChainIDs, realAddrsToModelConsAddrs) // check times - sanity check that the block times match the ones from the model - CompareTimes(driver, actualRunningConsumers, currentModelState, timeOffset) + CompareTimes(driver, actualRunningConsumerChainIDs, currentModelState, timeOffset) // check sent packets: we check that the package queues in the model and the system have the same length. - for _, consumer := range actualRunningConsumers { - ComparePacketQueues(t, driver, currentModelState, consumer, timeOffset) + for _, consumerChainID := range actualRunningConsumerChainIDs { + ComparePacketQueues(t, driver, currentModelState, consumerChainID, timeOffset) } // compare that the sent packets on the proider match the model CompareSentPacketsOnProvider(driver, currentModelState, timeOffset) @@ -528,8 +528,8 @@ func RunItfTrace(t *testing.T, path string) { CompareJailedValidators(driver, currentModelState, timeOffset, addressMap) // for all newly sent vsc packets, figure out which vsc id in the model they correspond to - for _, consumer := range actualRunningConsumers { - actualPackets := driver.packetQueue(PROVIDER, ChainId(consumer)) + for _, consumerChainID := range actualRunningConsumerChainIDs { + actualPackets := driver.packetQueue(PROVIDER, ChainId(consumerChainID)) actualNewPackets := make([]types.ValidatorSetChangePacketData, 0) for _, packet := range actualPackets { @@ -545,7 +545,7 @@ func RunItfTrace(t *testing.T, path string) { actualNewPackets = append(actualNewPackets, packetData) } - modelPackets := PacketQueue(currentModelState, PROVIDER, consumer) + modelPackets := PacketQueue(currentModelState, PROVIDER, consumerChainID) newModelVscIds := make([]uint64, 0) for _, packet := range modelPackets { modelVscId := uint64(packet.Value.(itf.MapExprType)["value"].Value.(itf.MapExprType)["id"].Value.(int64)) @@ -785,15 +785,15 @@ func CompareValSet(modelValSet map[string]itf.Expr, systemValSet map[string]int6 } func CompareSentPacketsOnProvider(driver *Driver, currentModelState map[string]itf.Expr, timeOffset time.Time) { - for _, consumer := range driver.runningConsumers() { - vscSendTimestamps := driver.providerKeeper().GetAllVscSendTimestamps(driver.providerCtx(), consumer.ChainId) + for _, consumerChainID := range driver.runningConsumerChainIDs() { + vscSendTimestamps := driver.providerKeeper().GetAllVscSendTimestamps(driver.providerCtx(), string(consumerChainID)) actualVscSendTimestamps := make([]time.Time, 0) for _, vscSendTimestamp := range vscSendTimestamps { actualVscSendTimestamps = append(actualVscSendTimestamps, vscSendTimestamp.Timestamp) } - modelVscSendTimestamps := VscSendTimestamps(currentModelState, consumer.ChainId) + modelVscSendTimestamps := VscSendTimestamps(currentModelState, string(consumerChainID)) for i, modelVscSendTimestamp := range modelVscSendTimestamps { actualTimeWithOffset := actualVscSendTimestamps[i].Unix() - timeOffset.Unix() @@ -802,7 +802,7 @@ func CompareSentPacketsOnProvider(driver *Driver, currentModelState map[string]i modelVscSendTimestamp, actualTimeWithOffset, "Vsc send timestamps do not match for consumer %v", - consumer.ChainId, + consumerChainID, ) } } @@ -860,9 +860,9 @@ func (s *Stats) EnterStats(driver *Driver) { // max number of in-flight packets inFlightPackets := 0 - for _, consumer := range driver.runningConsumers() { - inFlightPackets += len(driver.packetQueue(PROVIDER, ChainId(consumer.ChainId))) - inFlightPackets += len(driver.packetQueue(ChainId(consumer.ChainId), PROVIDER)) + for _, consumerChainID := range driver.runningConsumerChainIDs() { + inFlightPackets += len(driver.packetQueue(PROVIDER, consumerChainID)) + inFlightPackets += len(driver.packetQueue(consumerChainID, PROVIDER)) } if inFlightPackets > s.maxNumInFlightPackets { s.maxNumInFlightPackets = inFlightPackets diff --git a/tests/mbt/driver/setup.go b/tests/mbt/driver/setup.go index b56222cb87..81d39d5e70 100644 --- a/tests/mbt/driver/setup.go +++ b/tests/mbt/driver/setup.go @@ -12,6 +12,7 @@ import ( commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" ibctesting "github.com/cosmos/ibc-go/v8/testing" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" "github.com/stretchr/testify/require" "cosmossdk.io/math" @@ -376,7 +377,8 @@ func (s *Driver) ConfigureNewPath(consumerChain, providerChain *ibctesting.TestC stakingValidators = append(stakingValidators, v) } - nextValidators := s.providerKeeper().ComputeNextEpochConsumerValSet(s.providerCtx(), string(consumerChainId), stakingValidators) + considerAll := func(providerAddr providertypes.ProviderConsAddress) bool { return true } + nextValidators := s.providerKeeper().FilterValidators(s.providerCtx(), string(consumerChainId), stakingValidators, considerAll) s.providerKeeper().SetConsumerValSet(s.providerCtx(), string(consumerChainId), nextValidators) err = s.providerKeeper().SetConsumerGenesis( @@ -385,6 +387,9 @@ func (s *Driver) ConfigureNewPath(consumerChain, providerChain *ibctesting.TestC consumerGenesisForProvider) require.NoError(s.t, err, "Error setting consumer genesis on provider for chain %v", consumerChain.ChainID) + // set the top N percentage to 100 to simulate a full consumer + s.providerKeeper().SetTopN(providerChain.GetContext(), consumerChain.ChainID, 100) + // Client ID is set in InitGenesis and we treat it as a black box. So // must query it to use it with the endpoint. clientID, _ := s.consumerKeeper(consumerChainId).GetProviderClientID(s.ctx(consumerChainId)) diff --git a/tests/mbt/model/README.md b/tests/mbt/model/README.md index b8ce579440..f4add0e213 100644 --- a/tests/mbt/model/README.md +++ b/tests/mbt/model/README.md @@ -32,6 +32,8 @@ All the logic in EndBlock/BeginBlock happens here, like updating the validator s * `DeliverVscPacket(receiver: Chain)`: Delivers a pending VSCPacket from the provider to the consumer `receiver`. * `DeliverPacketToProvider(sender: Chain)`: Delivers a pending packet from the consumer `sender` to the provider. * `KeyAssignment(chain: Chain, validator: Node, consumerAddr: ConsumerAddr)` (only when running with `--step stepKeyAssignment`): Assigns the `consumerAddr` to the `validator` on the `chain`. Note that we use "key" and "consumerAddr" pretty much interchangeably, as the model makes no differentiation between private keys, public keys, addresses, etc, as it doesn't model the cryptography. +* `OptIn(chain: Chain, validator: Node)` (only when running with `--step stepBoundedDriftKeyAndPSS` on `ccv_boundeddrift.qnt`): The `validator` opts in on the `chain`. +* `OptOut(chain: Chain, validator: Node)` (only when running with `--step stepBoundedDriftKeyAndPSS` on `ccv_boundeddrift.qnt`): The `validator` opts out on the `chain`. ### State machines @@ -51,6 +53,12 @@ To run with key assignment, specify the step flag: `--step stepKeyAssignment`. KeyAssignment also needs some different invariants, see below. +#### Partial Set Security + +To run with Partial Set Security, specify the step flag `--step stepBoundedDriftKeyAndPSS`. +This runs both PSS and Key Assignment. +It also requires running with `ccv_boundeddrift.qnt`, see below. + #### ccv_boundeddrift.qnt This state machine layer is more restricted to generate more interesting traces: * It never allows consumer chains to drift more than `MaxDrift` time apart from each other. @@ -75,10 +83,8 @@ traces are not very useful for testing. To run unit tests, run ``` -quint test ccv_test.qnt -``` -and -``` +quint test ccv_test.qnt; +quint test ccv_pss_test.qnt; quint test ccv_model.qnt ``` @@ -132,4 +138,8 @@ The available sanity checks are: - CanSendVscMaturedPackets - CanReceiveMaturations - CanAssignConsumerKey (only with `--step stepKeyAssignment`) -- CanHaveConsumerAddresses (only with `--step stepKeyAssignment`) \ No newline at end of file +- CanHaveConsumerAddresses (only with `--step stepKeyAssignment`) +- CanOptIn (only with `--step stepBoundedDriftKeyAndPSS` on `ccv_boundeddrift.qnt`) +- CanOptOut (only with `--step stepBoundedDriftKeyAndPSS` on `ccv_boundeddrift.qnt`) +- CanFailOptOut (only with `--step stepBoundedDriftKeyAndPSS` on `ccv_boundeddrift.qnt`) +- CanHaveOptIn (only with `--step stepBoundedDriftKeyAndPSS` on `ccv_boundeddrift.qnt`) diff --git a/tests/mbt/model/ccv.qnt b/tests/mbt/model/ccv.qnt index 87ddc91ea2..80aed91ec2 100644 --- a/tests/mbt/model/ccv.qnt +++ b/tests/mbt/model/ccv.qnt @@ -908,14 +908,18 @@ module ccv { // (in general, the validator is a consumer address and could be an assigned one) val slashFactor = DowntimeSlashPercentage + + val curValPowerIsZero = currentState.providerState.chainState.currentValidatorPowers.get(providerVal) == 0 - val newProviderState = currentState.providerState - .jailUntil(providerVal, jailEndTime) + val newProviderState = if (not(curValPowerIsZero)) + currentState.providerState + .jailUntil(providerVal, jailEndTime) else + currentState.providerState // validators with zero power are not jailed // // slashing is currently not enabled in ICS // .slash(packet.validator, packet.valPower, slashFactor) // if the validator did not have voting power of 0 or was already jailed before, the validator set will change due to the slash - val valSetChanged = currentState.providerState.chainState.currentValidatorPowers.get(providerVal) != 0 + val valSetChanged = not(curValPowerIsZero) // add the consumer address to the list of acknowledged slashes // for the sender chain of this slash packet and indicate that we need to send a packet at endblock diff --git a/tests/mbt/model/ccv_model.qnt b/tests/mbt/model/ccv_model.qnt index e2b812e212..312f6a5bdb 100644 --- a/tests/mbt/model/ccv_model.qnt +++ b/tests/mbt/model/ccv_model.qnt @@ -216,11 +216,14 @@ module ccv_model { // stepCommon is the core functionality of steps that does not have anything to do with time. action stepCommon = any { - nondet node = oneOf(nonJailedNodes(currentState.providerState)) - // very restricted set of voting powers. exact values are not important, - // and this keeps the state space smaller. - nondet newVotingPower = oneOf(Set(-50, 50)) - VotingPowerChange(node, newVotingPower), + all { + currentState.providerState.validatorsWithPower().size() > 0, + nondet node = oneOf(currentState.providerState.validatorsWithPower()) + // very restricted set of voting powers. exact values are not important, + // and this keeps the state space smaller. + nondet newVotingPower = oneOf(Set(-50, 50)) + VotingPowerChange(node, newVotingPower), + }, // try to send a packet. we could filter by chains that can actually send, // but it's probably not much faster than just trying and failing. @@ -749,7 +752,8 @@ module ccv_model { action nondetKeyAssignment = all { runningConsumers.size() > 0, - nondet node = oneOf(nodes) + currentState.providerState.validatorsWithPower().size() > 0, + nondet node = oneOf(currentState.providerState.validatorsWithPower()) nondet consumerAddr = oneOf(consumerAddresses) nondet consumer = oneOf(runningConsumers) KeyAssignment(consumer, node, consumerAddr), diff --git a/tests/mbt/model/ccv_pss.qnt b/tests/mbt/model/ccv_pss.qnt new file mode 100644 index 0000000000..26aee28d56 --- /dev/null +++ b/tests/mbt/model/ccv_pss.qnt @@ -0,0 +1,157 @@ +// This module contains logic for PSS (Partial Set Security). +// PSS is a variant/extension of CCV that +// allows for only a subset of the validator set +// to secure a consumer chain. +// Not all logic related to PSS is inside this module, as some logic is +// too tightly coupled with the core CCV logic, +// which is instead found in ccv.qnt +module ccv_pss { + import ccv_types.* from "./ccv" + import extraSpells.* from "./libraries/extraSpells" + import ccv_utils.* from "./ccv_utils" + + // Given a base validator set, an N for a top N chain, and a set of validators that have opted in to the chain, + // returns the validator set that should be sent to the chain. + // Assumes that the value for N is valid. + pure def GetPSSValidatorSet(providerState: ProviderState, origValSet: ValidatorSet, consumer: Chain): ValidatorSet = { + pure val optedInVals = providerState.optedInVals.getOrElse(consumer, Set()) + GetPSSValidatorSet_helper(origValSet, optedInVals) + } + + pure def GetPSSValidatorSet_helper(origValSet: ValidatorSet, optedInVals: Set[Node]): ValidatorSet = { + origValSet.mapFilter(v => optedInVals.contains(v)) + } + + // Given a validator set and N, returns the top N% of validators by power. + // Note that in the edge case of multiple validators having the same power, + // this will always include all validators with the same power as the lowest top N validator. + pure def GetTopNVals(origValSet: ValidatorSet, N: int): Set[Node] = { + // == sort validators by power == + // define a comparator that compares validators by power + pure def powerCompare(a: Node, b: Node): Ordering = { + pure val powA = origValSet.get(a) + pure val powB = origValSet.get(b) + intCompare(powB, powA) + } + // get a sorted list of validators by power + pure val sortedVals = origValSet.keys().toSortedList(powerCompare) + + // == compute the threshold of how much power the top N have == + pure val totalPower = origValSet.mapValuesSum() + pure val topNPower = totalPower * N / 100 + + // == construct the validator set by going through the sorted vals == + pure val res = sortedVals.foldl( + // accumulator carries 4 values: + // * set of vals in top N (starts with empty set) + // * total power added so far (starts with 0) + // * whether we should add the next validator if it has the same power as the previous one, + // regardless of total power (starts with false) + // * the power of the last validator added (starts with 0) + (Set(), 0, false, 0), + (acc, validator) => + pure val curValSet = acc._1 + pure val accPower = acc._2 + pure val shouldAddSamePow = acc._3 + pure val lastPow = acc._4 + + pure val validatorPower = origValSet.get(validator) + if (validatorPower == lastPow and shouldAddSamePow) { + // we should add the validator because it has the same power as the previous one, + // and we add regardless of total power because we need to include all + // vals with the same power if we include one of them + pure val newAccPower = accPower + validatorPower + (curValSet.union(Set(validator)), newAccPower, true, validatorPower) + } else if (validatorPower > 0 and accPower < topNPower) { + // if we don't have enough power yet, add the validator to the set + pure val newAccPower = accPower + validatorPower + (curValSet.union(Set(validator)), newAccPower, true, validatorPower) + } else { + // if we have enough power and we also are done adding + // all validators with the same power as the lowest top N validator, + // don't add them + (curValSet, accPower, false, 0) + } + ) + res._1 + } + + // Opts a validator in for a consumer chain the provider. + // Possible before the consumer chain starts running, + // and will then be applied when the consumer chain starts running. + pure def OptIn(currentState: ProtocolState, consumer: Chain, validator: Node): Result = { + pure val optedInVals = currentState.providerState.optedInVals.get(consumer) + pure val newOptedInVals = optedInVals.union(Set(validator)) + Ok({ + ...currentState, + providerState: { + ...currentState.providerState, + optedInVals: currentState.providerState.optedInVals.put(consumer, newOptedInVals) + } + }) + } + + // Returns true if the given validator is in the top N for the given consumer chain, + // and false otherwise. + pure def IsTopN(currentState: ProtocolState, validator: Node, consumer: Chain): bool = { + val proviValSet = currentState.providerState.chainState.votingPowerHistory.head() + val N = currentState.providerState.topNByConsumer.get(consumer) + + val topNValSet = GetTopNVals(proviValSet, N) + + topNValSet.contains(validator) + } + + // Returns true if the given validator has opted in to the given consumer chain, + pure def IsOptedIn(currentState: ProtocolState, validator: Node, consumer: Chain): bool = { + currentState.providerState.optedInVals.getOrElse(consumer, Set()).contains(validator) + } + + // Opts a validator out. Safe to call before the consumer chain even runs. + // Will not stop the validator set from being forced to validate when in the top N. + // Validators that are in the top N will not be able to opt out, and + // an error will be returned. + // Similarly, if the validator is not opted in, an error will be returned. + pure def OptOut(currentState: ProtocolState, consumer: Chain, validator: Node): Result = { + if (currentState.IsTopN(validator, consumer)) { + Err("Cannot opt out a validator that is in the top N") + } else if (not(currentState.IsOptedIn(validator, consumer))) { + Err("Cannot opt out a validator that is not opted in") + } else { + pure val optedInVals = currentState.providerState.optedInVals.get(consumer) + pure val newOptedInVals = optedInVals.exclude(Set(validator)) + Ok({ + ...currentState, + providerState: { + ...currentState.providerState, + optedInVals: currentState.providerState.optedInVals.put(consumer, newOptedInVals) + } + }) + } + } + + // Runs the PSS logic that needs to run on endblock. + // Concretely, this will forcefully opt in all validators that are in the top N + // for each chain. + pure def endBlockPSS(providerState: ProviderState): ProviderState = { + val runningConsumers = providerState.getRunningConsumers() + runningConsumers.fold( + providerState, + (acc, consumer) => endBlockPSS_helper(acc, consumer) + ) + } + + // Runs the PSS logic for a single consumer. + // Should only be run for running chains. + pure def endBlockPSS_helper(providerState: ProviderState, consumer: Chain): ProviderState = { + val proviValSet = providerState.chainState.currentValidatorPowers + val topNVals = GetTopNVals(proviValSet, providerState.topNByConsumer.get(consumer)) + val prevOptedInVals = providerState.optedInVals.getOrElse(consumer, Set()) + // opt in all the top N validators, i.e. union the top N vals with the previous opted in vals + val newOptedInVals = providerState.optedInVals.put(consumer, prevOptedInVals.union(topNVals)) + { + ...providerState, + optedInVals: newOptedInVals + } + } +} \ No newline at end of file diff --git a/tests/mbt/model/ccv_pss_model.qnt b/tests/mbt/model/ccv_pss_model.qnt new file mode 100644 index 0000000000..9e60e241bc --- /dev/null +++ b/tests/mbt/model/ccv_pss_model.qnt @@ -0,0 +1,113 @@ +module ccv_pss_model { + import ccv_types.* from "./ccv" + import ccv_model.* from "./ccv_model" + import ccv_pss.* from "./ccv_pss" + import extraSpells.* from "./libraries/extraSpells" + + action StepOptIn(): bool = { + all { + runningConsumers.size() > 0, + nondet consumer = oneOf(runningConsumers) + nondet validator = oneOf(nodes) + OptIn_Deterministic(consumer, validator) + } + } + + action OptIn_Deterministic(consumer: Chain, validator: Node): bool = { + val res = OptIn(currentState, consumer, validator) + all { + currentState' = res.newState, + trace' = trace.append( + { + ...emptyAction, + kind: "OptIn", + consumerChain: consumer, + validator: validator + } + ), + params' = params, + } + } + + action StepOptOut(): bool = { + all { + runningConsumers.size() > 0, + nondet consumer = oneOf(runningConsumers) + nondet validator = oneOf(nodes) + OptOut_Deterministic(consumer, validator) + } + } + + action OptOut_Deterministic(consumer: Chain, validator: Node): bool = { + val res = OptOut(currentState, consumer, validator) + all { + // if we expect an error, this should be a noop + currentState' = if (res.error == "") res.newState else currentState, + trace' = trace.append( + { + ...emptyAction, + kind: "OptOut", + consumerChain: consumer, + validator: validator, + expectedError: res.error + } + ), + params' = params, + } + } + + // Different sets of possible values for the topN parameter. + val allFullConsumers: Set[int] = Set(100) + val allOptIn: Set[int] = Set(0) + // only choose a few values for top N here to not make the "edge cases" of 0 and 100 too unlikely + val variousPossibleTopN: Set[int] = Set(50, 70, 80, 90, 100) + + // INVARIANTS + + // For a consumer chain with a given top N value, + // the total VP on the consumer is at least N% of the total VP of some historical val set on the provider. + val AtLeastTopNPower: bool = + runningConsumers.forall(consumer => { + val topN = currentState.providerState.topNByConsumer.get(consumer) + val totalPowerConsu = currentState.consumerStates.get(consumer).chainState.currentValidatorPowers.mapValuesSum() + currentState.providerState.chainState.votingPowerHistory.toSet().exists( + valSet => { + val totalPowerProvi = valSet.mapValuesSum() + + totalPowerConsu >= totalPowerProvi * topN / 100 + } + ) + }) + + // SANITY CHECKS + + val CanOptIn = { + not( + trace[length(trace)-1].kind == "OptIn" + and + trace[length(trace)-1].expectedError == "" + ) + } + + val CanOptOut = { + not( + trace[length(trace)-1].kind == "OptOut" + and + trace[length(trace)-1].expectedError == "" + ) + } + + val CanFailOptOut = { + not( + trace[length(trace)-1].kind == "OptOut" + and + trace[length(trace)-1].expectedError != "" + ) + } + + val CanHaveOptIn = { + currentState.providerState.topNByConsumer.keys().exists(consumer => { + currentState.providerState.topNByConsumer.get(consumer) != 100 + }) + } +} \ No newline at end of file diff --git a/tests/mbt/model/ccv_pss_test.qnt b/tests/mbt/model/ccv_pss_test.qnt new file mode 100644 index 0000000000..61a5420150 --- /dev/null +++ b/tests/mbt/model/ccv_pss_test.qnt @@ -0,0 +1,61 @@ +// This module contains logic for PSS (Partial Set Security). +// PSS is a variant/extension of CCV that +// allows for only a subset of the validator set +// to secure a consumer chain. +// Not all logic related to PSS is inside this module, as some logic is +// too tightly coupled with the core CCV logic, +// which is instead found in ccv.qnt +module ccv_pss_test { + import ccv_types.* from "./ccv" + import extraSpells.* from "./libraries/extraSpells" + import ccv_utils.* from "./ccv_utils" + import ccv_pss.* from "./ccv_pss" + import ccv.* from "./ccv" + + run TopN1Test = + val valSet = + Map("d" -> 25, "c1" -> 15, "c" -> 15, "b2" -> 10, "b1" -> 10, "b" -> 10, "a2" -> 5, "a1" -> 5, "a" -> 5) + // total power: 5*3 + 10*3 + 15*2 + 25 = 100 + all + { + assert(GetTopNVals(valSet, 0) == Set()), + assert(GetTopNVals(valSet, 1) == Set("d")), + assert(GetTopNVals(valSet, 10) == Set("d")), + assert(GetTopNVals(valSet, 25) == Set("d")), + // if one validator with a power is included, all validators with that power need to be included + assert(GetTopNVals(valSet, 26) == Set("d", "c1", "c")), + assert(GetTopNVals(valSet, 45) == Set("d", "c1", "c")), + assert(GetTopNVals(valSet, 55) == Set("d", "c1", "c")), + assert(GetTopNVals(valSet, 56) == Set("d", "c1", "c", "b2", "b1", "b")), + assert(GetTopNVals(valSet, 85) == Set("d", "c1", "c", "b2", "b1", "b")), + assert(GetTopNVals(valSet, 86) == valSet.keys()), + assert(GetTopNVals(valSet, 95) == valSet.keys()), + assert(GetTopNVals(valSet, 100) == valSet.keys()), + } + + val providerState = GetEmptyProviderState().with( + "chainState", GetEmptyChainState().with( + "currentValidatorPowers", Map( + "a" -> 5, + "a1" -> 5, + "a2" -> 5, + "b" -> 10, + "b1" -> 10, + "b2" -> 10, + "c" -> 15, + "c1" -> 15, + "d" -> 25 + ) + ) + ).with( + "consumerStatus", Map( + "consumer1" -> "running" + ) + ).with( + "topNByConsumer", Map( + "consumer1" -> 80 + ) + ) + run TopN2Test = + true +} \ No newline at end of file diff --git a/tests/mbt/model/ccv_utils.qnt b/tests/mbt/model/ccv_utils.qnt index ffb22e0dda..6c0f18b44c 100644 --- a/tests/mbt/model/ccv_utils.qnt +++ b/tests/mbt/model/ccv_utils.qnt @@ -531,6 +531,11 @@ module ccv_utils { ) } + // Returns the set of all nodes that are neither jailed nor have 0 power on the provider. + pure def validatorsWithPower(providerState: ProviderState): Set[Node] = { + nonJailedNodes(providerState).filter(node => providerState.chainState.currentValidatorPowers.get(node) != 0) + } + pure def IsEmptyValSet(valSet: ValidatorSet): bool = { valSet.keys().filter( node => valSet.get(node) > 0 diff --git a/testutil/ibc_testing/generic_setup.go b/testutil/ibc_testing/generic_setup.go index 0df7174cbd..3aaae5702f 100644 --- a/testutil/ibc_testing/generic_setup.go +++ b/testutil/ibc_testing/generic_setup.go @@ -7,6 +7,7 @@ import ( clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" ibctesting "github.com/cosmos/ibc-go/v8/testing" + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -19,7 +20,6 @@ import ( testutil "github.com/cosmos/interchain-security/v5/testutil/integration" consumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) type ( @@ -31,10 +31,16 @@ type ( // and/or democracy consumer app.go implementation. You should not need to modify or replicate this file // to run integration tests against your app.go implementations! +const ( + // Default number of consumer chains + NumConsumers = 5 +) + var ( FirstConsumerChainID string provChainID string democConsumerChainID string + consumerTopNParams [NumConsumers]uint32 ) func init() { @@ -43,6 +49,9 @@ func init() { FirstConsumerChainID = ibctesting.GetChainID(2) provChainID = ibctesting.GetChainID(1) democConsumerChainID = ibctesting.GetChainID(5000) + // TopN parameter values per consumer chain initiated + // sorted in ascending order i.e. testchain2, testchain3, ..., testchain6 + consumerTopNParams = [NumConsumers]uint32{100, 100, 100, 100, 100} } // ConsumerBundle serves as a way to store useful in-mem consumer app chain state @@ -52,6 +61,7 @@ type ConsumerBundle struct { App testutil.ConsumerApp Path *ibctesting.Path TransferPath *ibctesting.Path + TopN uint32 } // GetCtx returns the context for the ConsumerBundle @@ -117,6 +127,9 @@ func AddConsumer[Tp testutil.ProviderApp, Tc testutil.ConsumerApp]( index int, appIniter ValSetAppIniter, ) *ConsumerBundle { + // check index isn't bigger that the number of consumers + s.Require().LessOrEqual(index, NumConsumers) + // consumer chain ID chainID := ibctesting.GetChainID(index + 2) @@ -125,30 +138,32 @@ func AddConsumer[Tp testutil.ProviderApp, Tc testutil.ConsumerApp]( providerApp := providerChain.App.(Tp) providerKeeper := providerApp.GetProviderKeeper() - prop := providertypes.ConsumerAdditionProposal{ - Title: fmt.Sprintf("start chain %s", chainID), - Description: "description", - ChainId: chainID, - InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 2}, - GenesisHash: []byte("gen_hash"), - BinaryHash: []byte("bin_hash"), - // NOTE: we cannot use the time.Now() because the coordinator chooses a hardcoded start time - // using time.Now() could set the spawn time to be too far in the past or too far in the future - SpawnTime: coordinator.CurrentTime, - UnbondingPeriod: ccvtypes.DefaultConsumerUnbondingPeriod, - CcvTimeoutPeriod: ccvtypes.DefaultCCVTimeoutPeriod, - TransferTimeoutPeriod: ccvtypes.DefaultTransferTimeoutPeriod, - ConsumerRedistributionFraction: ccvtypes.DefaultConsumerRedistributeFrac, - BlocksPerDistributionTransmission: ccvtypes.DefaultBlocksPerDistributionTransmission, - HistoricalEntries: ccvtypes.DefaultHistoricalEntries, - DistributionTransmissionChannel: "", - } + prop := testkeeper.GetTestConsumerAdditionProp() + prop.ChainId = chainID + prop.Top_N = consumerTopNParams[index] // isn't used in CreateConsumerClient - providerKeeper.SetPendingConsumerAdditionProp(providerChain.GetContext(), &prop) + // NOTE: we cannot use the time.Now() because the coordinator chooses a hardcoded start time + // using time.Now() could set the spawn time to be too far in the past or too far in the future + prop.SpawnTime = coordinator.CurrentTime + // NOTE: the initial height passed to CreateConsumerClient + // must be the height on the consumer when InitGenesis is called + prop.InitialHeight = clienttypes.Height{RevisionNumber: 0, RevisionHeight: 2} + + providerKeeper.SetPendingConsumerAdditionProp(providerChain.GetContext(), prop) props := providerKeeper.GetAllPendingConsumerAdditionProps(providerChain.GetContext()) s.Require().Len(props, 1, "unexpected len consumer addition proposals in AddConsumer") + // opt-in all validators + lastVals, err := providerApp.GetProviderKeeper().GetLastBondedValidators(providerChain.GetContext()) + s.Require().NoError(err) + + for _, v := range lastVals { + consAddr, _ := v.GetConsAddr() + providerKeeper.SetOptedIn(providerChain.GetContext(), chainID, providertypes.NewProviderConsAddress(consAddr)) + } + // commit the state on the provider chain + // and create the client and genesis of consumer coordinator.CommitBlock(providerChain) // get genesis state created by the provider @@ -188,5 +203,6 @@ func AddConsumer[Tp testutil.ProviderApp, Tc testutil.ConsumerApp]( return &ConsumerBundle{ Chain: testChain, App: consumerToReturn, + TopN: prop.Top_N, } } diff --git a/testutil/integration/debug_test.go b/testutil/integration/debug_test.go index af37fbb5a1..15036416e6 100644 --- a/testutil/integration/debug_test.go +++ b/testutil/integration/debug_test.go @@ -304,3 +304,27 @@ func TestAfterPropSubmissionAndVotingPeriodEnded(t *testing.T) { func TestGetConsumerAdditionLegacyPropFromProp(t *testing.T) { runCCVTestByName(t, "TestGetConsumerAdditionLegacyPropFromProp") } + +func TestIBCTransferMiddleware(t *testing.T) { + runCCVTestByName(t, "TestIBCTransferMiddleware") +} + +func TestAllocateTokens(t *testing.T) { + runCCVTestByName(t, "TestAllocateTokens") +} + +func TestTransferConsumerRewardsToDistributionModule(t *testing.T) { + runCCVTestByName(t, "TransferConsumerRewardsToDistributionModule") +} + +func TestAllocateTokensToValidator(t *testing.T) { + runCCVTestByName(t, "TestAllocateTokensToValidator") +} + +func TestMultiConsumerRewardsDistribution(t *testing.T) { + runCCVTestByName(t, "TestMultiConsumerRewardsDistribution") +} + +func TestTooManyLastValidators(t *testing.T) { + runCCVTestByName(t, "TestTooManyLastValidators") +} diff --git a/testutil/integration/interfaces.go b/testutil/integration/interfaces.go index b36befe20f..de9c3a6b0d 100644 --- a/testutil/integration/interfaces.go +++ b/testutil/integration/interfaces.go @@ -4,25 +4,27 @@ import ( "context" "time" + abci "github.com/cometbft/cometbft/abci/types" ibctesting "github.com/cosmos/ibc-go/v8/testing" "cosmossdk.io/core/comet" "cosmossdk.io/math" + govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" + evidencekeeper "cosmossdk.io/x/evidence/keeper" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" + mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" - - evidencekeeper "cosmossdk.io/x/evidence/keeper" - govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" - mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" consumerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/consumer/keeper" providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // The interface that any provider app must implement to be compatible with ccv integration tests. @@ -107,6 +109,9 @@ type TestStakingKeeper interface { GetUnbondingDelegation(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (ubd stakingtypes.UnbondingDelegation, err error) GetAllValidators(ctx context.Context) (validators []stakingtypes.Validator, err error) GetValidatorSet() stakingtypes.ValidatorSet + GetParams(ctx context.Context) (stakingtypes.Params, error) + SetParams(ctx context.Context, p stakingtypes.Params) error + ApplyAndReturnValidatorSetUpdates(ctx context.Context) (updates []abci.ValidatorUpdate, err error) } type TestBankKeeper interface { @@ -140,4 +145,17 @@ type TestDistributionKeeper interface { GetDistributionAccount(ctx context.Context) sdk.ModuleAccountI GetValidatorOutstandingRewards(ctx context.Context, val sdk.ValAddress) (rewards distributiontypes.ValidatorOutstandingRewards, err error) GetCommunityTax(ctx context.Context) (math.LegacyDec, error) + WithdrawValidatorCommission(ctx context.Context, valAddr sdk.ValAddress) (sdk.Coins, error) +} + +type TestMintKeeper interface { + GetParams(ctx sdk.Context) (params minttypes.Params) +} + +type TestGovKeeper interface { + GetParams(ctx sdk.Context) govv1.Params + SetParams(ctx sdk.Context, params govv1.Params) error + SubmitProposal(ctx sdk.Context, messages []sdk.Msg, metadata, title, summary string, proposer sdk.AccAddress) (govv1.Proposal, error) + AddDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress, depositAmount sdk.Coins) (bool, error) + AddVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress, options govv1.WeightedVoteOptions, metadata string) error } diff --git a/testutil/keeper/expectations.go b/testutil/keeper/expectations.go index f6734d64f6..49ffe51ace 100644 --- a/testutil/keeper/expectations.go +++ b/testutil/keeper/expectations.go @@ -54,11 +54,9 @@ func GetMocksForMakeConsumerGenesis(ctx sdk.Context, mocks *MockedKeepers, ) []*gomock.Call { return []*gomock.Call{ mocks.MockStakingKeeper.EXPECT().UnbondingTime(gomock.Any()).Return(unbondingTimeToInject, nil).Times(1), - mocks.MockClientKeeper.EXPECT().GetSelfConsensusState(gomock.Any(), clienttypes.GetSelfHeight(ctx)).Return(&ibctmtypes.ConsensusState{}, nil).Times(1), - - mocks.MockStakingKeeper.EXPECT().IterateLastValidatorPowers(gomock.Any(), gomock.Any()).Times(1), + // mocks.MockStakingKeeper.EXPECT().GetLastValidators(gomock.Any()).Times(1), } } @@ -219,3 +217,37 @@ func GetMocksForSlashValidator( Times(1), } } + +// SetupMocksForLastBondedValidatorsExpectation sets up the expectation for the `IterateLastValidatorPowers` `MaxValidators`, and `GetValidator` methods of the `mockStakingKeeper` object. +// These are needed in particular when calling `GetLastBondedValidators` from the provider keeper. +// Times is the number of times the expectation should be called. Provide -1 for `AnyTimes“. +func SetupMocksForLastBondedValidatorsExpectation(mockStakingKeeper *MockStakingKeeper, maxValidators uint32, vals []stakingtypes.Validator, powers []int64, times int) { + iteratorCall := mockStakingKeeper.EXPECT().IterateLastValidatorPowers(gomock.Any(), gomock.Any()).DoAndReturn( + func(ctx sdk.Context, cb func(sdk.ValAddress, int64) bool) error { + for i, val := range vals { + if stop := cb(sdk.ValAddress(val.OperatorAddress), powers[i]); stop { + break + } + } + return nil + }) + maxValidatorsCall := mockStakingKeeper.EXPECT().MaxValidators(gomock.Any()).Return(maxValidators, nil) + + if times == -1 { + iteratorCall.AnyTimes() + maxValidatorsCall.AnyTimes() + } else { + iteratorCall.Times(times) + maxValidatorsCall.Times(times) + } + + // set up mocks for GetValidator calls + for _, val := range vals { + getValCall := mockStakingKeeper.EXPECT().GetValidator(gomock.Any(), sdk.ValAddress(val.OperatorAddress)).Return(val, nil) + if times == -1 { + getValCall.AnyTimes() + } else { + getValCall.Times(times) + } + } +} diff --git a/testutil/keeper/mocks.go b/testutil/keeper/mocks.go index f0cb00b07f..7beb0c0bcd 100644 --- a/testutil/keeper/mocks.go +++ b/testutil/keeper/mocks.go @@ -107,19 +107,19 @@ func (mr *MockStakingKeeperMockRecorder) GetLastValidatorPower(ctx, operator int return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastValidatorPower", reflect.TypeOf((*MockStakingKeeper)(nil).GetLastValidatorPower), ctx, operator) } -// GetLastValidators mocks base method. -func (m *MockStakingKeeper) GetLastValidators(ctx context.Context) ([]types3.Validator, error) { +// GetRedelegationByUnbondingID mocks base method. +func (m *MockStakingKeeper) GetRedelegationByUnbondingID(ctx context.Context, id uint64) (types3.Redelegation, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLastValidators", ctx) - ret0, _ := ret[0].([]types3.Validator) + ret := m.ctrl.Call(m, "GetRedelegationByUnbondingID", ctx, id) + ret0, _ := ret[0].(types3.Redelegation) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetLastValidators indicates an expected call of GetLastValidators. -func (mr *MockStakingKeeperMockRecorder) GetLastValidators(ctx interface{}) *gomock.Call { +// GetRedelegationByUnbondingID indicates an expected call of GetRedelegationByUnbondingID. +func (mr *MockStakingKeeperMockRecorder) GetRedelegationByUnbondingID(ctx, id interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastValidators", reflect.TypeOf((*MockStakingKeeper)(nil).GetLastValidators), ctx) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRedelegationByUnbondingID", reflect.TypeOf((*MockStakingKeeper)(nil).GetRedelegationByUnbondingID), ctx, id) } // GetRedelegationsFromSrcValidator mocks base method. @@ -137,6 +137,21 @@ func (mr *MockStakingKeeperMockRecorder) GetRedelegationsFromSrcValidator(ctx, v return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRedelegationsFromSrcValidator", reflect.TypeOf((*MockStakingKeeper)(nil).GetRedelegationsFromSrcValidator), ctx, valAddr) } +// GetUnbondingDelegationByUnbondingID mocks base method. +func (m *MockStakingKeeper) GetUnbondingDelegationByUnbondingID(ctx context.Context, id uint64) (types3.UnbondingDelegation, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUnbondingDelegationByUnbondingID", ctx, id) + ret0, _ := ret[0].(types3.UnbondingDelegation) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetUnbondingDelegationByUnbondingID indicates an expected call of GetUnbondingDelegationByUnbondingID. +func (mr *MockStakingKeeperMockRecorder) GetUnbondingDelegationByUnbondingID(ctx, id interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUnbondingDelegationByUnbondingID", reflect.TypeOf((*MockStakingKeeper)(nil).GetUnbondingDelegationByUnbondingID), ctx, id) +} + // GetUnbondingDelegationsFromValidator mocks base method. func (m *MockStakingKeeper) GetUnbondingDelegationsFromValidator(ctx context.Context, valAddr types1.ValAddress) ([]types3.UnbondingDelegation, error) { m.ctrl.T.Helper() @@ -197,6 +212,21 @@ func (mr *MockStakingKeeperMockRecorder) GetValidatorByConsAddr(ctx, consAddr in return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorByConsAddr", reflect.TypeOf((*MockStakingKeeper)(nil).GetValidatorByConsAddr), ctx, consAddr) } +// GetValidatorByUnbondingID mocks base method. +func (m *MockStakingKeeper) GetValidatorByUnbondingID(ctx context.Context, id uint64) (types3.Validator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetValidatorByUnbondingID", ctx, id) + ret0, _ := ret[0].(types3.Validator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetValidatorByUnbondingID indicates an expected call of GetValidatorByUnbondingID. +func (mr *MockStakingKeeperMockRecorder) GetValidatorByUnbondingID(ctx, id interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorByUnbondingID", reflect.TypeOf((*MockStakingKeeper)(nil).GetValidatorByUnbondingID), ctx, id) +} + // GetValidatorUpdates mocks base method. func (m *MockStakingKeeper) GetValidatorUpdates(ctx context.Context) ([]types0.ValidatorUpdate, error) { m.ctrl.T.Helper() @@ -284,6 +314,21 @@ func (mr *MockStakingKeeperMockRecorder) MaxValidators(ctx interface{}) *gomock. return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaxValidators", reflect.TypeOf((*MockStakingKeeper)(nil).MaxValidators), ctx) } +// MinCommissionRate mocks base method. +func (m *MockStakingKeeper) MinCommissionRate(ctx context.Context) (math.LegacyDec, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MinCommissionRate", ctx) + ret0, _ := ret[0].(math.LegacyDec) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MinCommissionRate indicates an expected call of MinCommissionRate. +func (mr *MockStakingKeeperMockRecorder) MinCommissionRate(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinCommissionRate", reflect.TypeOf((*MockStakingKeeper)(nil).MinCommissionRate), ctx) +} + // PowerReduction mocks base method. func (m *MockStakingKeeper) PowerReduction(ctx context.Context) math.Int { m.ctrl.T.Helper() @@ -918,6 +963,20 @@ func (m *MockDistributionKeeper) EXPECT() *MockDistributionKeeperMockRecorder { return m.recorder } +// AllocateTokensToValidator mocks base method. +func (m *MockDistributionKeeper) AllocateTokensToValidator(ctx context.Context, validator types3.ValidatorI, reward types1.DecCoins) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AllocateTokensToValidator", ctx, validator, reward) + ret0, _ := ret[0].(error) + return ret0 +} + +// AllocateTokensToValidator indicates an expected call of AllocateTokensToValidator. +func (mr *MockDistributionKeeperMockRecorder) AllocateTokensToValidator(ctx, validator, reward interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AllocateTokensToValidator", reflect.TypeOf((*MockDistributionKeeper)(nil).AllocateTokensToValidator), ctx, validator, reward) +} + // FundCommunityPool mocks base method. func (m *MockDistributionKeeper) FundCommunityPool(ctx context.Context, amount types1.Coins, sender types1.AccAddress) error { m.ctrl.T.Helper() @@ -932,6 +991,21 @@ func (mr *MockDistributionKeeperMockRecorder) FundCommunityPool(ctx, amount, sen return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FundCommunityPool", reflect.TypeOf((*MockDistributionKeeper)(nil).FundCommunityPool), ctx, amount, sender) } +// GetCommunityTax mocks base method. +func (m *MockDistributionKeeper) GetCommunityTax(ctx context.Context) (math.LegacyDec, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCommunityTax", ctx) + ret0, _ := ret[0].(math.LegacyDec) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCommunityTax indicates an expected call of GetCommunityTax. +func (mr *MockDistributionKeeperMockRecorder) GetCommunityTax(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCommunityTax", reflect.TypeOf((*MockDistributionKeeper)(nil).GetCommunityTax), ctx) +} + // MockConsumerHooks is a mock of ConsumerHooks interface. type MockConsumerHooks struct { ctrl *gomock.Controller diff --git a/testutil/keeper/unit_test_helpers.go b/testutil/keeper/unit_test_helpers.go index af31cd973c..a80138551a 100644 --- a/testutil/keeper/unit_test_helpers.go +++ b/testutil/keeper/unit_test_helpers.go @@ -227,6 +227,9 @@ func SetupForStoppingConsumerChain(t *testing.T, ctx sdk.Context, providerKeeper *providerkeeper.Keeper, mocks MockedKeepers, ) { t.Helper() + + SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 1, []stakingtypes.Validator{}, []int64{}, 1) + expectations := GetMocksForCreateConsumerClient(ctx, &mocks, "chainID", clienttypes.NewHeight(4, 5)) expectations = append(expectations, GetMocksForSetConsumerChain(ctx, &mocks, "chainID")...) @@ -261,10 +264,15 @@ func TestProviderStateIsCleanedAfterConsumerChainIsStopped(t *testing.T, ctx sdk require.Empty(t, providerKeeper.GetAllVscSendTimestamps(ctx, expectedChainID)) + // in case the chain was successfully stopped, it should not contain a Top N associated to it + _, found = providerKeeper.GetTopN(ctx, expectedChainID) + require.False(t, found) + // test key assignment state is cleaned require.Empty(t, providerKeeper.GetAllValidatorConsumerPubKeys(ctx, &expectedChainID)) require.Empty(t, providerKeeper.GetAllValidatorsByConsumerAddr(ctx, &expectedChainID)) require.Empty(t, providerKeeper.GetAllConsumerAddrsToPrune(ctx, expectedChainID)) + require.Empty(t, providerKeeper.GetAllCommissionRateValidators(ctx, expectedChainID)) } func GetTestConsumerAdditionProp() *providertypes.ConsumerAdditionProposal { @@ -283,6 +291,11 @@ func GetTestConsumerAdditionProp() *providertypes.ConsumerAdditionProposal { types.DefaultCCVTimeoutPeriod, types.DefaultTransferTimeoutPeriod, types.DefaultConsumerUnbondingPeriod, + 0, + 0, + 0, + nil, + nil, ).(*providertypes.ConsumerAdditionProposal) return prop diff --git a/x/ccv/consumer/keeper/changeover_test.go b/x/ccv/consumer/keeper/changeover_test.go index 4f52fc926e..b9b160ffec 100644 --- a/x/ccv/consumer/keeper/changeover_test.go +++ b/x/ccv/consumer/keeper/changeover_test.go @@ -3,7 +3,6 @@ package keeper_test import ( "testing" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" sdkcryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" @@ -30,6 +29,8 @@ func TestChangeoverToConsumer(t *testing.T) { cIds[4].SDKStakingValidator(), } + powers := []int64{55, 87324, 2, 42389479, 9089080} + // Instantiate 5 ics val updates for use in test initialValUpdates := []abci.ValidatorUpdate{ {Power: 55, PubKey: cIds[5].TMProtoCryptoPublicKey()}, @@ -41,7 +42,7 @@ func TestChangeoverToConsumer(t *testing.T) { testCases := []struct { name string - // Last standalone validators that will be mock returned from stakingKeeper.GetLastValidators() + // Last standalone validators that will be mock returned from consumerKeeper.GetLastBondedValidators() lastSovVals []stakingtypes.Validator // Val updates corresponding to initial valset set for ccv set initGenesis initialValUpdates []abci.ValidatorUpdate @@ -100,10 +101,13 @@ func TestChangeoverToConsumer(t *testing.T) { // Set initial valset, as would be done in InitGenesis consumerKeeper.SetInitialValSet(ctx, tc.initialValUpdates) - // Setup mocked return value for stakingKeeper.GetLastValidators() - gomock.InOrder( - mocks.MockStakingKeeper.EXPECT().GetLastValidators(ctx).Return(tc.lastSovVals, nil), - ) + // Setup mocked return value for consumerkeeper.GetLastBondedValidators() + uthelpers.SetupMocksForLastBondedValidatorsExpectation( + mocks.MockStakingKeeper, + 180, // max validators + tc.lastSovVals, + powers, + -1) // any times // Add ref to standalone staking keeper consumerKeeper.SetStandaloneStakingKeeper(mocks.MockStakingKeeper) diff --git a/x/ccv/consumer/keeper/keeper.go b/x/ccv/consumer/keeper/keeper.go index 242babda4d..644cfc33a7 100644 --- a/x/ccv/consumer/keeper/keeper.go +++ b/x/ccv/consumer/keeper/keeper.go @@ -353,7 +353,7 @@ func (k Keeper) GetLastStandaloneValidators(ctx sdk.Context) ([]stakingtypes.Val if !k.IsPreCCV(ctx) || k.standaloneStakingKeeper == nil { panic("cannot get last standalone validators if not in pre-ccv state, or if standalone staking keeper is nil") } - return k.standaloneStakingKeeper.GetLastValidators(ctx) + return k.GetLastBondedValidators(ctx) } // GetElapsedPacketMaturityTimes returns a slice of already elapsed PacketMaturityTimes, sorted by maturity times, @@ -712,3 +712,9 @@ func (k Keeper) IsPrevStandaloneChain(ctx sdk.Context) bool { store := ctx.KVStore(k.storeKey) return store.Has(types.PrevStandaloneChainKey()) } + +// GetLastBondedValidators iterates the last validator powers in the staking module +// and returns the first MaxValidators many validators with the largest powers. +func (k Keeper) GetLastBondedValidators(ctx sdk.Context) ([]stakingtypes.Validator, error) { + return ccv.GetLastBondedValidatorsUtil(ctx, k.standaloneStakingKeeper, k.Logger(ctx)) +} diff --git a/x/ccv/consumer/keeper/keeper_test.go b/x/ccv/consumer/keeper/keeper_test.go index 87a8a5051f..ea90b2002f 100644 --- a/x/ccv/consumer/keeper/keeper_test.go +++ b/x/ccv/consumer/keeper/keeper_test.go @@ -184,11 +184,14 @@ func TestGetLastSovereignValidators(t *testing.T) { cId1 := crypto.NewCryptoIdentityFromIntSeed(11) val := cId1.SDKStakingValidator() val.Description.Moniker = "sanity check this is the correctly serialized val" - gomock.InOrder( - mocks.MockStakingKeeper.EXPECT().GetLastValidators(ctx).Return([]stakingtypes.Validator{ - val, - }, nil), + testkeeper.SetupMocksForLastBondedValidatorsExpectation( + mocks.MockStakingKeeper, + 180, + []stakingtypes.Validator{val}, + []int64{1000}, + 1, ) + lastSovVals, err := ck.GetLastStandaloneValidators(ctx) require.NoError(t, err) require.Equal(t, []stakingtypes.Validator{val}, lastSovVals) diff --git a/x/ccv/consumer/keeper/soft_opt_out.go b/x/ccv/consumer/keeper/soft_opt_out.go index 1de2345cbc..39b5bc22bc 100644 --- a/x/ccv/consumer/keeper/soft_opt_out.go +++ b/x/ccv/consumer/keeper/soft_opt_out.go @@ -59,13 +59,13 @@ func (k Keeper) UpdateSmallestNonOptOutPower(ctx sdk.Context) { // get total power in set totalPower := math.LegacyZeroDec() for _, val := range valset { - totalPower = totalPower.Add(math.LegacyNewDecFromInt(math.NewInt(val.Power))) + totalPower = totalPower.Add(math.LegacyNewDec(val.Power)) } // get power of the smallest validator that cannot soft opt out powerSum := math.LegacyZeroDec() for _, val := range valset { - powerSum = powerSum.Add(math.LegacyNewDecFromInt(math.NewInt(val.Power))) + powerSum = powerSum.Add(math.LegacyNewDec(val.Power)) // if powerSum / totalPower > SoftOptOutThreshold if powerSum.Quo(totalPower).GT(optOutThreshold) { // set smallest non opt out power diff --git a/x/ccv/provider/client/cli/query.go b/x/ccv/provider/client/cli/query.go index b3494ac884..697fccbb76 100644 --- a/x/ccv/provider/client/cli/query.go +++ b/x/ccv/provider/client/cli/query.go @@ -35,6 +35,10 @@ func NewQueryCmd() *cobra.Command { cmd.AddCommand(CmdProposedConsumerChains()) cmd.AddCommand(CmdAllPairsValConAddrByConsumerChainID()) cmd.AddCommand(CmdProviderParameters()) + cmd.AddCommand(CmdConsumerChainOptedInValidators()) + cmd.AddCommand(CmdConsumerValidators()) + cmd.AddCommand(CmdConsumerChainsValidatorHasToValidate()) + cmd.AddCommand(CmdValidatorConsumerCommissionRate()) cmd.AddCommand(CmdOldestUnconfirmedVsc()) return cmd } @@ -352,7 +356,7 @@ $ %s query provider registered-consumer-reward-denoms func CmdAllPairsValConAddrByConsumerChainID() *cobra.Command { cmd := &cobra.Command{ - Use: "all-pairs-valconsensus-address", + Use: "all-pairs-valconsensus-address [consumer-chain-id]", Short: "Query all pairs of valconsensus address by consumer chainId.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { @@ -411,6 +415,161 @@ $ %s query provider params return cmd } +// Command to query opted-in validators by consumer chain ID +func CmdConsumerChainOptedInValidators() *cobra.Command { + cmd := &cobra.Command{ + Use: "consumer-opted-in-validators [chainid]", + Short: "Query opted-in validators for a given consumer chain", + Long: strings.TrimSpace( + fmt.Sprintf(`Query opted-in validators for a given consumer chain. +Example: +$ %s consumer-opted-in-validators foochain + `, version.AppName), + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.QueryConsumerChainOptedInValidators(cmd.Context(), + &types.QueryConsumerChainOptedInValidatorsRequest{ChainId: args[0]}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// Command to query the consumer validators by consumer chain ID +func CmdConsumerValidators() *cobra.Command { + cmd := &cobra.Command{ + Use: "consumer-validators [chainid]", + Short: "Query the last set consumer-validator set for a given consumer chain", + Long: strings.TrimSpace( + fmt.Sprintf(`Query the last set consumer-validator set for a given consumer chain. +Note that this does not necessarily mean that the consumer chain is currently using this validator set because a VSCPacket could be delayed, etc. +Example: +$ %s consumer-validators foochain + `, version.AppName), + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.QueryConsumerValidators(cmd.Context(), + &types.QueryConsumerValidatorsRequest{ChainId: args[0]}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// Command to query the consumer chains list a given validator has to validate +func CmdConsumerChainsValidatorHasToValidate() *cobra.Command { + bech32PrefixConsAddr := sdk.GetConfig().GetBech32ConsensusAddrPrefix() + cmd := &cobra.Command{ + Use: "has-to-validate [provider-validator-address]", + Short: "Query the consumer chains list a given validator has to validate", + Long: strings.TrimSpace( + fmt.Sprintf(`the list of consumer chains that as a validator, you need to be running right now, is always a subset of this, so it seems like a very nice "safe bet". +Example: +$ %s has-to-validate %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj + `, version.AppName, bech32PrefixConsAddr), + ), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + addr, err := sdk.ConsAddressFromBech32(args[0]) + if err != nil { + return err + } + + res, err := queryClient.QueryConsumerChainsValidatorHasToValidate(cmd.Context(), + &types.QueryConsumerChainsValidatorHasToValidateRequest{ + ProviderAddress: addr.String(), + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// Command to query the consumer commission rate a validator charges +// on a consumer chain +func CmdValidatorConsumerCommissionRate() *cobra.Command { + bech32PrefixConsAddr := sdk.GetConfig().GetBech32ConsensusAddrPrefix() + cmd := &cobra.Command{ + Use: "validator-consumer-commission-rate [chainid] [provider-validator-address]", + Short: "Query the consumer commission rate a validator charges on a consumer chain", + Long: strings.TrimSpace( + fmt.Sprintf(`Query the consumer commission rate a validator charges on a consumer chain. +Example: +$ %s validator-consumer-commission-rate foochain %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj + `, version.AppName, bech32PrefixConsAddr), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + addr, err := sdk.ConsAddressFromBech32(args[1]) + if err != nil { + return err + } + + res, err := queryClient.QueryValidatorConsumerCommissionRate(cmd.Context(), + &types.QueryValidatorConsumerCommissionRateRequest{ + ChainId: args[0], + ProviderAddress: addr.String(), + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + func CmdOldestUnconfirmedVsc() *cobra.Command { cmd := &cobra.Command{ Use: "oldest_unconfirmed_vsc [chainid]", diff --git a/x/ccv/provider/client/cli/tx.go b/x/ccv/provider/client/cli/tx.go index 536145267b..eadb3a7e57 100644 --- a/x/ccv/provider/client/cli/tx.go +++ b/x/ccv/provider/client/cli/tx.go @@ -6,6 +6,8 @@ import ( "os" "strings" + "cosmossdk.io/math" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/spf13/cobra" @@ -34,6 +36,9 @@ func GetTxCmd() *cobra.Command { cmd.AddCommand(NewAssignConsumerKeyCmd()) cmd.AddCommand(NewSubmitConsumerMisbehaviourCmd()) cmd.AddCommand(NewSubmitConsumerDoubleVotingCmd()) + cmd.AddCommand(NewOptInCmd()) + cmd.AddCommand(NewOptOutCmd()) + cmd.AddCommand(NewSetConsumerCommissionRateCmd()) return cmd } @@ -203,3 +208,135 @@ Example: return cmd } + +func NewOptInCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "opt-in [consumer-chain-id] [consumer-pubkey]", + Short: "opts in validator to the consumer chain, and if given uses the " + + "provided consensus public key for this consumer chain", + Args: cobra.RangeArgs(1, 2), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } + txf = txf.WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + + providerValAddr := clientCtx.GetFromAddress() + + var consumerPubKey string + if len(args) == 2 { + // consumer public key was provided + consumerPubKey = args[1] + } else { + consumerPubKey = "" + } + + signer := clientCtx.GetFromAddress().String() + msg, err := types.NewMsgOptIn(args[0], sdk.ValAddress(providerValAddr), consumerPubKey, signer) + if err != nil { + return err + } + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + _ = cmd.MarkFlagRequired(flags.FlagFrom) + + return cmd +} + +func NewOptOutCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "opt-out [consumer-chain-id]", + Short: "opts out validator from this consumer chain", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } + txf = txf.WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + + providerValAddr := clientCtx.GetFromAddress() + + signer := clientCtx.GetFromAddress().String() + msg, err := types.NewMsgOptOut(args[0], sdk.ValAddress(providerValAddr), signer) + if err != nil { + return err + } + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + _ = cmd.MarkFlagRequired(flags.FlagFrom) + + return cmd +} + +func NewSetConsumerCommissionRateCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "set-consumer-commission-rate [consumer-chain-id] [commission-rate]", + Short: "set a per-consumer chain commission", + Long: strings.TrimSpace( + fmt.Sprintf(`Note that the "commission-rate" argument is a fraction and should be in the range [0,1]. + Example: + %s set-consumer-commission-rate consumer-1 0.5 --from node0 --home ../node0`, + version.AppName), + ), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } + txf = txf.WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + + providerValAddr := clientCtx.GetFromAddress() + + commission, err := math.LegacyNewDecFromStr(args[1]) + if err != nil { + return err + } + msg := types.NewMsgSetConsumerCommissionRate(args[0], commission, sdk.ValAddress(providerValAddr)) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxWithFactory(clientCtx, txf, msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + _ = cmd.MarkFlagRequired(flags.FlagFrom) + + return cmd +} diff --git a/x/ccv/provider/client/legacy_proposal_handler.go b/x/ccv/provider/client/legacy_proposal_handler.go index 7ac9198be2..f837e7bab2 100644 --- a/x/ccv/provider/client/legacy_proposal_handler.go +++ b/x/ccv/provider/client/legacy_proposal_handler.go @@ -15,9 +15,10 @@ import ( ) var ( - ConsumerAdditionProposalHandler = govclient.NewProposalHandler(SubmitConsumerAdditionPropTxCmd) - ConsumerRemovalProposalHandler = govclient.NewProposalHandler(SubmitConsumerRemovalProposalTxCmd) - ChangeRewardDenomsProposalHandler = govclient.NewProposalHandler(SubmitChangeRewardDenomsProposalTxCmd) + ConsumerAdditionProposalHandler = govclient.NewProposalHandler(SubmitConsumerAdditionPropTxCmd) + ConsumerRemovalProposalHandler = govclient.NewProposalHandler(SubmitConsumerRemovalProposalTxCmd) + ChangeRewardDenomsProposalHandler = govclient.NewProposalHandler(SubmitChangeRewardDenomsProposalTxCmd) + ConsumerModificationProposalHandler = govclient.NewProposalHandler(SubmitConsumerModificationProposalTxCmd) ) // SubmitConsumerAdditionPropTxCmd returns a CLI command handler for submitting @@ -55,7 +56,12 @@ Where proposal.json contains: "transfer_timeout_period": 3600000000000, "ccv_timeout_period": 2419200000000000, "unbonding_period": 1728000000000000, - "deposit": "10000stake" + "deposit": "10000stake", + "top_n": 0, + "validators_power_cap": 32, + "validator_set_cap": 50, + "allowlist": [], + "denylist": ["validatorAConsensusAddress", "validatorBConsensusAddress"] } `, RunE: func(cmd *cobra.Command, args []string) error { @@ -77,7 +83,8 @@ Where proposal.json contains: proposal.GenesisHash, proposal.BinaryHash, proposal.SpawnTime, proposal.ConsumerRedistributionFraction, proposal.BlocksPerDistributionTransmission, proposal.DistributionTransmissionChannel, proposal.HistoricalEntries, - proposal.CcvTimeoutPeriod, proposal.TransferTimeoutPeriod, proposal.UnbondingPeriod) + proposal.CcvTimeoutPeriod, proposal.TransferTimeoutPeriod, proposal.UnbondingPeriod, proposal.TopN, + proposal.ValidatorsPowerCap, proposal.ValidatorSetCap, proposal.Allowlist, proposal.Denylist) from := clientCtx.GetFromAddress() @@ -213,3 +220,67 @@ func SubmitChangeRewardDenomsProposalTxCmd() *cobra.Command { }, } } + +// SubmitConsumerModificationProposalTxCmd returns a CLI command handler for submitting +// a consumer modification proposal via a transaction. +func SubmitConsumerModificationProposalTxCmd() *cobra.Command { + return &cobra.Command{ + Use: "consumer-modification [proposal-file]", + Args: cobra.ExactArgs(1), + Short: "Submit a consumer modification proposal", + Long: ` +Submit a consumer modification proposal along with an initial deposit. +The proposal details must be supplied via a JSON file. + +Example: +$ tx gov submit-legacy-proposal consumer-modification --from= + +Where proposal.json contains: + +{ + "title": "Modify FooChain", + "summary": "Make it an Opt In chain", + "chain_id": "foochain", + "top_n": 0, + "validators_power_cap": 32, + "validator_set_cap": 50, + "allowlist": [], + "denylist": ["validatorAConsensusAddress", "validatorBConsensusAddress"] +} + `, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + proposal, err := ParseConsumerModificationProposalJSON(args[0]) + if err != nil { + return err + } + + content := types.NewConsumerModificationProposal( + proposal.Title, proposal.Summary, proposal.ChainId, proposal.TopN, + proposal.ValidatorsPowerCap, proposal.ValidatorSetCap, proposal.Allowlist, proposal.Denylist) + + from := clientCtx.GetFromAddress() + + deposit, err := sdk.ParseCoinsNormalized(proposal.Deposit) + if err != nil { + return err + } + + msgContent, err := govv1.NewLegacyContent(content, authtypes.NewModuleAddress(govtypes.ModuleName).String()) + if err != nil { + return err + } + + msg, err := govv1.NewMsgSubmitProposal([]sdk.Msg{msgContent}, deposit, from.String(), "", content.GetTitle(), proposal.Summary, false) + if err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } +} diff --git a/x/ccv/provider/client/legacy_proposals.go b/x/ccv/provider/client/legacy_proposals.go index 9493c0d8c6..b19528b1b7 100644 --- a/x/ccv/provider/client/legacy_proposals.go +++ b/x/ccv/provider/client/legacy_proposals.go @@ -35,6 +35,12 @@ type ConsumerAdditionProposalJSON struct { UnbondingPeriod time.Duration `json:"unbonding_period"` Deposit string `json:"deposit"` + + TopN uint32 `json:"top_N"` + ValidatorsPowerCap uint32 `json:"validators_power_cap"` + ValidatorSetCap uint32 `json:"validator_set_cap"` + Allowlist []string `json:"allowlist"` + Denylist []string `json:"denylist"` } type ConsumerAdditionProposalReq struct { @@ -145,7 +151,8 @@ func CheckPropUnbondingPeriod(clientCtx client.Context, propUnbondingPeriod time providerUnbondingTime := res.Params.UnbondingTime if providerUnbondingTime < propUnbondingPeriod { - fmt.Printf( + fmt.Fprintf( + os.Stderr, `consumer unbonding period is advised to be smaller than provider unbonding period, but is longer. This is not a security risk, but will effectively lengthen the unbonding period on the provider. consumer unbonding: %s @@ -154,3 +161,32 @@ provider unbonding: %s`, providerUnbondingTime) } } + +type ConsumerModificationProposalJSON struct { + Title string `json:"title"` + Summary string `json:"summary"` + ChainId string `json:"chain_id"` + + TopN uint32 `json:"top_N"` + ValidatorsPowerCap uint32 `json:"validators_power_cap"` + ValidatorSetCap uint32 `json:"validator_set_cap"` + Allowlist []string `json:"allowlist"` + Denylist []string `json:"denylist"` + + Deposit string `json:"deposit"` +} + +func ParseConsumerModificationProposalJSON(proposalFile string) (ConsumerModificationProposalJSON, error) { + proposal := ConsumerModificationProposalJSON{} + + contents, err := os.ReadFile(filepath.Clean(proposalFile)) + if err != nil { + return proposal, err + } + + if err := json.Unmarshal(contents, &proposal); err != nil { + return proposal, err + } + + return proposal, nil +} diff --git a/x/ccv/provider/handler.go b/x/ccv/provider/handler.go index 2c2738ce91..78e17257de 100644 --- a/x/ccv/provider/handler.go +++ b/x/ccv/provider/handler.go @@ -27,6 +27,15 @@ func NewHandler(k *keeper.Keeper) baseapp.MsgServiceHandler { case *types.MsgSubmitConsumerDoubleVoting: res, err := msgServer.SubmitConsumerDoubleVoting(ctx, msg) return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgOptIn: + res, err := msgServer.OptIn(ctx, msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgOptOut: + res, err := msgServer.OptOut(ctx, msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgSetConsumerCommissionRate: + res, err := msgServer.SetConsumerCommissionRate(ctx, msg) + return sdk.WrapServiceResult(ctx, res, err) default: return nil, errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg) } diff --git a/x/ccv/provider/handler_test.go b/x/ccv/provider/handler_test.go index 11fb18bf1f..ffb3614e17 100644 --- a/x/ccv/provider/handler_test.go +++ b/x/ccv/provider/handler_test.go @@ -34,6 +34,10 @@ func TestAssignConsensusKeyMsgHandling(t *testing.T) { providerCryptoId := testcrypto.NewCryptoIdentityFromIntSeed(0) providerConsAddr := providerCryptoId.ProviderConsAddress() + // a different providerConsAddr, to simulate different validators having assigned keys + providerCryptoId2 := testcrypto.NewCryptoIdentityFromIntSeed(10) + providerConsAddr2 := providerCryptoId2.ProviderConsAddress() + consumerCryptoId := testcrypto.NewCryptoIdentityFromIntSeed(1) consumerConsAddr := consumerCryptoId.ConsumerConsAddress() consumerKeyBz := base64.StdEncoding.EncodeToString(consumerCryptoId.ConsensusSDKPubKey().Bytes()) @@ -99,7 +103,32 @@ func TestAssignConsensusKeyMsgHandling(t *testing.T) { chainID: "chainid", }, { - name: "fail: consumer key in use", + name: "fail: consumer key in use by other validator", + setup: func(ctx sdk.Context, + k keeper.Keeper, mocks testkeeper.MockedKeepers, + ) { + k.SetPendingConsumerAdditionProp(ctx, &providertypes.ConsumerAdditionProposal{ + ChainId: "chainid", + }) + // Use the consumer key already used by some other validator + k.SetValidatorByConsumerAddr(ctx, "chainid", consumerConsAddr, providerConsAddr2) + + gomock.InOrder( + mocks.MockStakingKeeper.EXPECT().GetValidator( + ctx, providerCryptoId.SDKValOpAddress(), + // validator should not be missing + ).Return(providerCryptoId.SDKStakingValidator(), nil).Times(1), + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, + consumerConsAddr.ToSdkConsAddr(), + // return false - no other validator uses the consumer key to validate *on the provider* + ).Return(stakingtypes.Validator{}, nil), + ) + }, + expError: true, + chainID: "chainid", + }, + { + name: "success: consumer key in use, but by the same validator", setup: func(ctx sdk.Context, k keeper.Keeper, mocks testkeeper.MockedKeepers, ) { @@ -118,7 +147,7 @@ func TestAssignConsensusKeyMsgHandling(t *testing.T) { ).Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound), ) }, - expError: true, + expError: false, chainID: "chainid", }, } diff --git a/x/ccv/provider/ibc_middleware.go b/x/ccv/provider/ibc_middleware.go new file mode 100644 index 0000000000..f4128260e1 --- /dev/null +++ b/x/ccv/provider/ibc_middleware.go @@ -0,0 +1,242 @@ +package provider + +import ( + ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" + "github.com/cosmos/ibc-go/v8/modules/core/exported" + + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" + + "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" +) + +var _ porttypes.Middleware = &IBCMiddleware{} + +// IBCMiddleware implements the callbacks for the IBC transfer middleware given the +// provider keeper and the underlying application. +type IBCMiddleware struct { + app porttypes.IBCModule + keeper keeper.Keeper +} + +// NewIBCMiddleware creates a new IBCMiddlware given the keeper and underlying application +func NewIBCMiddleware(app porttypes.IBCModule, k keeper.Keeper) IBCMiddleware { + return IBCMiddleware{ + app: app, + keeper: k, + } +} + +// OnChanOpenInit implements the IBCMiddleware interface +func (im IBCMiddleware) OnChanOpenInit( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID string, + channelID string, + chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + version string, +) (string, error) { + // call underlying app's OnChanOpenInit callback with the appVersion + return im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, version) +} + +// OnChanOpenTry implements the IBCMiddleware interface +func (im IBCMiddleware) OnChanOpenTry( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID, + channelID string, + chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + counterpartyVersion string, +) (string, error) { + // call underlying app's OnChanOpenTry callback with the appVersion + return im.app.OnChanOpenTry(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, counterpartyVersion) +} + +// OnChanOpenAck implements the IBCMiddleware interface +func (im IBCMiddleware) OnChanOpenAck( + ctx sdk.Context, + portID, + channelID string, + counterpartyChannelID string, + counterpartyVersion string, +) error { + // call underlying app's OnChanOpenAck callback with the counterparty app version. + return im.app.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) +} + +// OnChanOpenConfirm implements the IBCMiddleware interface +func (im IBCMiddleware) OnChanOpenConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + // call underlying app's OnChanOpenConfirm callback. + return im.app.OnChanOpenConfirm(ctx, portID, channelID) +} + +// OnChanCloseInit implements the IBCMiddleware interface +func (im IBCMiddleware) OnChanCloseInit( + ctx sdk.Context, + portID, + channelID string, +) error { + // call underlying app's OnChanCloseInit callback. + return im.app.OnChanCloseInit(ctx, portID, channelID) +} + +// OnChanCloseConfirm implements the IBCMiddleware interface +func (im IBCMiddleware) OnChanCloseConfirm( + ctx sdk.Context, + portID, + channelID string, +) error { + return im.app.OnChanCloseConfirm(ctx, portID, channelID) +} + +// OnRecvPacket executes the IBC transfer. In case of success, +// it verifies if the packet sender is a consumer chain +// and if the received IBC coin is whitelisted. In such instances, +// it appends the coin to the consumer's chain allocation record +func (im IBCMiddleware) OnRecvPacket( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, +) exported.Acknowledgement { + // executes the IBC transfer OnRecv logic + ack := im.app.OnRecvPacket(ctx, packet, relayer) + + // Note that inside the below if condition statement, + // we know that the IBC transfer succeeded. That entails + // that the packet data is valid and can be safely + // deserialized without checking errors. + if ack.Success() { + // execute the middleware logic only if the sender is a consumer chain + consumerID, err := im.keeper.IdentifyConsumerChainIDFromIBCPacket(ctx, packet) + if err != nil { + return ack + } + + // extract the coin info received from the packet data + var data ibctransfertypes.FungibleTokenPacketData + _ = types.ModuleCdc.UnmarshalJSON(packet.GetData(), &data) + + // check if the recipient is the consumer reward's pool address + receiver, _ := sdk.AccAddressFromBech32(data.Receiver) + if receiver.String() != im.keeper.GetConsumerRewardsPoolAddressStr(ctx) { + return ack + } + + coinAmt, _ := math.NewIntFromString(data.Amount) + coinDenom := GetProviderDenom(data.Denom, packet) + + // verify that the coin's denom is a whitelisted consumer denom, + // and if so, adds it to the consumer chain rewards allocation, + // otherwise the prohibited coin just stays in the pool forever. + if im.keeper.ConsumerRewardDenomExists(ctx, coinDenom) { + alloc := im.keeper.GetConsumerRewardsAllocation(ctx, consumerID) + alloc.Rewards = alloc.Rewards.Add( + sdk.NewDecCoinsFromCoins(sdk.Coin{ + Denom: coinDenom, + Amount: coinAmt, + })...) + im.keeper.SetConsumerRewardsAllocation(ctx, consumerID, alloc) + } + } + + return ack +} + +// OnAcknowledgementPacket implements the IBCMiddleware interface +// If fees are not enabled, this callback will default to the ibc-core packet callback +func (im IBCMiddleware) OnAcknowledgementPacket( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + relayer sdk.AccAddress, +) error { + // call underlying app's OnAcknowledgementPacket callback. + return im.app.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer) +} + +// OnTimeoutPacket implements the IBCMiddleware interface +// If fees are not enabled, this callback will default to the ibc-core packet callback +func (im IBCMiddleware) OnTimeoutPacket( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, +) error { + // call underlying app's OnTimeoutPacket callback. + return im.app.OnTimeoutPacket(ctx, packet, relayer) +} + +// SendPacket implements the ICS4 Wrapper interface +func (im IBCMiddleware) SendPacket( + sdk.Context, + *capabilitytypes.Capability, + string, + string, + clienttypes.Height, + uint64, + []byte, +) (uint64, error) { + panic("should never be called since the IBC middleware doesn't have an ICS4wrapper") +} + +// WriteAcknowledgement implements the ICS4 Wrapper interface +func (im IBCMiddleware) WriteAcknowledgement( + ctx sdk.Context, + chanCap *capabilitytypes.Capability, + packet exported.PacketI, + ack exported.Acknowledgement, +) error { + panic("should never be called since the IBC middleware doesn't have an ICS4wrapper") +} + +// GetAppVersion returns the application version of the underlying application +func (im IBCMiddleware) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) { + panic("should never be called since the IBC middleware doesn't have an ICS4wrapper") +} + +// GetProviderDenom returns the updated given denom according to the given IBC packet +// It follows the same logic than the OnRecvPacket method of the IBC transfer module +// see https://github.com/cosmos/ibc-go/blob/v7.3.2/modules/apps/transfer/keeper/relay.go#L162 +func GetProviderDenom(denom string, packet channeltypes.Packet) (providerDenom string) { + // If the the prefix denom corresponds to the packet's source port and channel, + // returns the base denom + if ibctransfertypes.ReceiverChainIsSource(packet.GetSourcePort(), packet.GetSourceChannel(), denom) { + voucherPrefix := ibctransfertypes.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) + unprefixedDenom := denom[len(voucherPrefix):] + + // coin denomination used in sending from the escrow address + providerDenom = unprefixedDenom + + // The denomination used to send the coins is either the native denom or the hash of the path + // if the denomination is not native. + denomTrace := ibctransfertypes.ParseDenomTrace(unprefixedDenom) + if denomTrace.Path != "" { + providerDenom = denomTrace.IBCDenom() + } + // update the prefix denom according to the packet info + } else { + prefixedDenom := ibctransfertypes.GetPrefixedDenom( + packet.GetDestPort(), + packet.GetDestChannel(), + denom, + ) + + providerDenom = ibctransfertypes.ParseDenomTrace(prefixedDenom).IBCDenom() + } + + return providerDenom +} diff --git a/x/ccv/provider/ibc_middleware_test.go b/x/ccv/provider/ibc_middleware_test.go new file mode 100644 index 0000000000..3148069bf2 --- /dev/null +++ b/x/ccv/provider/ibc_middleware_test.go @@ -0,0 +1,77 @@ +package provider_test + +import ( + "testing" + + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + "github.com/stretchr/testify/require" + + "github.com/cosmos/interchain-security/v5/x/ccv/provider" +) + +func TestGetProviderDenom(t *testing.T) { + testCases := []struct { + name string + denom string + packet channeltypes.Packet + expProviderDenom string + }{ + { + name: "returns base denom with destination port and channel as prefix", + denom: "stake", + packet: channeltypes.NewPacket( + []byte{}, + 0, + "srcPort", + "srcChannel", + "dstPort", + "dstChannel", + clienttypes.NewHeight(1, 1), + 0, + ), + expProviderDenom: "dstPort/dstChannel/stake", + }, + { + name: "returns base denom if the prefix denom corresponds to the packet's port and channel source", + denom: "srcPort/srcChannel/stake", + packet: channeltypes.NewPacket( + []byte{}, + 0, + "srcPort", + "srcChannel", + "dstPort", + "dstChannel", + clienttypes.NewHeight(1, 1), + 0, + ), + expProviderDenom: "stake", + }, + { + name: "returns prefixed denom updated with packet's port and channel destination as prefix", + denom: "dstPort/dstChannel/stake", + packet: channeltypes.NewPacket( + []byte{}, + 0, + "srcPort", + "srcChannel", + "dstPort", + "dstChannel", + clienttypes.NewHeight(1, 1), + 0, + ), + expProviderDenom: "dstPort/dstChannel/dstPort/dstChannel/stake", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + res := provider.GetProviderDenom( + tc.denom, + tc.packet, + ) + + require.Equal(t, tc.expProviderDenom, res) + }) + } +} diff --git a/x/ccv/provider/keeper/consumer_equivocation.go b/x/ccv/provider/keeper/consumer_equivocation.go index 34d6857c93..127a3987a5 100644 --- a/x/ccv/provider/keeper/consumer_equivocation.go +++ b/x/ccv/provider/keeper/consumer_equivocation.go @@ -367,23 +367,27 @@ func (k Keeper) JailAndTombstoneValidator(ctx sdk.Context, providerAddr types.Pr } if k.slashingKeeper.IsTombstoned(ctx, providerAddr.ToSdkConsAddr()) { - return fmt.Errorf("validator is tombstoned. provider consensus address: %s", providerAddr.String()) + return errorsmod.Wrapf(slashingtypes.ErrValidatorTombstoned, providerAddr.String()) } // jail validator if not already if !validator.IsJailed() { - k.stakingKeeper.Jail(ctx, providerAddr.ToSdkConsAddr()) + err := k.stakingKeeper.Jail(ctx, providerAddr.ToSdkConsAddr()) + if err != nil { + return err + } } - k.slashingKeeper.JailUntil(ctx, providerAddr.ToSdkConsAddr(), evidencetypes.DoubleSignJailEndTime) + err = k.slashingKeeper.JailUntil(ctx, providerAddr.ToSdkConsAddr(), evidencetypes.DoubleSignJailEndTime) + if err != nil { + return fmt.Errorf("fail to set jail duration for validator: %s: %s", providerAddr.String(), err) + } // Tombstone the validator so that we cannot slash the validator more than once // Note that we cannot simply use the fact that a validator is jailed to avoid slashing more than once // because then a validator could i) perform an equivocation, ii) get jailed (e.g., through downtime) // and in such a case the validator would not get slashed when we call `SlashValidator`. - k.slashingKeeper.Tombstone(ctx, providerAddr.ToSdkConsAddr()) - - return nil + return k.slashingKeeper.Tombstone(ctx, providerAddr.ToSdkConsAddr()) } // ComputePowerToSlash computes the power to be slashed based on the tokens in non-matured `undelegations` and diff --git a/x/ccv/provider/keeper/distribution.go b/x/ccv/provider/keeper/distribution.go index 0b2cdcf0e9..ca16831ee8 100644 --- a/x/ccv/provider/keeper/distribution.go +++ b/x/ccv/provider/keeper/distribution.go @@ -2,17 +2,26 @@ package keeper import ( storetypes "cosmossdk.io/store/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + + "context" + + errorsmod "cosmossdk.io/errors" + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ) -// EndBlockRD executes EndBlock logic for the Reward Distribution sub-protocol. -// Reward Distribution follows a simple model: send tokens to the ConsumerRewardsPool, -// from where they sent to the fee collector address -func (k Keeper) EndBlockRD(ctx sdk.Context) { - // transfers all whitelisted consumer rewards to the fee collector address - k.TransferRewardsToFeeCollector(ctx) +// BeginBlockRD executes BeginBlock logic for the Reward Distribution sub-protocol. +func (k Keeper) BeginBlockRD(ctx sdk.Context) { + // TODO this is Tendermint-dependent + // ref https://github.com/cosmos/cosmos-sdk/issues/3095 + if ctx.BlockHeight() > 1 { + k.AllocateTokens(ctx) + } } func (k Keeper) GetConsumerRewardsPoolAddressStr(ctx sdk.Context) string { @@ -57,32 +66,275 @@ func (k Keeper) GetAllConsumerRewardDenoms(ctx sdk.Context) (consumerRewardDenom return consumerRewardDenoms } -// TransferRewardsToFeeCollector transfers all consumer rewards to the fee collector address -func (k Keeper) TransferRewardsToFeeCollector(ctx sdk.Context) { - // 1. Get the denom whitelist from the store - denoms := k.GetAllConsumerRewardDenoms(ctx) +// AllocateTokens performs rewards distribution to the community pool and validators +// based on the Partial Set Security distribution specification. +func (k Keeper) AllocateTokens(ctx sdk.Context) { + // return if there is no coins in the consumer rewards pool + if k.GetConsumerRewardsPool(ctx).IsZero() { + return + } + + // Iterate over all registered consumer chains + for _, consumerChainID := range k.GetAllRegisteredConsumerChainIDs(ctx) { + + // note that it's possible that no rewards are collected even though the + // reward pool isn't empty. This can happen if the reward pool holds some tokens + // of non-whitelisted denominations. + alloc := k.GetConsumerRewardsAllocation(ctx, consumerChainID) + if alloc.Rewards.IsZero() { + continue + } + + // temporary workaround to keep CanWithdrawInvariant happy + // general discussions here: https://github.com/cosmos/cosmos-sdk/issues/2906#issuecomment-441867634 + if k.ComputeConsumerTotalVotingPower(ctx, consumerChainID) == 0 { + rewardsToSend, rewardsChange := alloc.Rewards.TruncateDecimal() + err := k.distributionKeeper.FundCommunityPool(context.Context(ctx), rewardsToSend, k.accountKeeper.GetModuleAccount(ctx, types.ConsumerRewardsPool).GetAddress()) + if err != nil { + k.Logger(ctx).Error( + "fail to allocate rewards from consumer chain %s to community pool: %s", + consumerChainID, + err, + ) + } + + // set the consumer allocation to the remaining reward decimals + alloc.Rewards = rewardsChange + k.SetConsumerRewardsAllocation(ctx, consumerChainID, alloc) - // 2. Iterate over the whitelist - for _, denom := range denoms { - // 3. For each denom, retrieve the balance from the consumer rewards pool - balance := k.bankKeeper.GetBalance( + return + } + + // Consumer rewards are distributed between the validators and the community pool. + // The decimals resulting from the distribution are expected to remain in the consumer reward allocations. + + communityTax, err := k.distributionKeeper.GetCommunityTax(ctx) + if err != nil { + k.Logger(ctx).Error( + "cannot get community tax while allocating rewards from consumer chain %s: %s", + consumerChainID, + err, + ) + continue + } + + // compute rewards for validators + consumerRewards := alloc.Rewards + voteMultiplier := math.LegacyOneDec().Sub(communityTax) + validatorsRewards := consumerRewards.MulDecTruncate(voteMultiplier) + + // compute remaining rewards for the community pool + remaining := consumerRewards.Sub(validatorsRewards) + + // transfer validators rewards to distribution module account + validatorsRewardsTrunc, validatorsRewardsChange := validatorsRewards.TruncateDecimal() + err = k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ConsumerRewardsPool, distrtypes.ModuleName, validatorsRewardsTrunc) + if err != nil { + k.Logger(ctx).Error( + "cannot send rewards to distribution module account %s: %s", + consumerChainID, + err, + ) + continue + } + + // allocate tokens to consumer validators + k.AllocateTokensToConsumerValidators( ctx, - k.accountKeeper.GetModuleAccount(ctx, types.ConsumerRewardsPool).GetAddress(), - denom, + consumerChainID, + sdk.NewDecCoinsFromCoins(validatorsRewardsTrunc...), ) - // if the balance is not zero, - if !balance.IsZero() { - // 4. Transfer the balance to the fee collector address - err := k.bankKeeper.SendCoinsFromModuleToModule( - ctx, - types.ConsumerRewardsPool, - k.feeCollectorName, - sdk.NewCoins(balance), + // allocate remaining rewards to the community pool + remainingRewards, remainingChanges := remaining.TruncateDecimal() + err = k.distributionKeeper.FundCommunityPool(context.Context(ctx), remainingRewards, k.accountKeeper.GetModuleAccount(ctx, types.ConsumerRewardsPool).GetAddress()) + if err != nil { + k.Logger(ctx).Error( + "fail to allocate rewards from consumer chain %s to community pool: %s", + consumerChainID, + err, ) - if err != nil { - k.Logger(ctx).Error("cannot sent consumer rewards to fee collector:", "reward", balance.String()) - } + continue + } + + // set consumer allocations to the remaining rewards decimals + alloc.Rewards = validatorsRewardsChange.Add(remainingChanges...) + k.SetConsumerRewardsAllocation(ctx, consumerChainID, alloc) + } +} + +// IsEligibleForConsumerRewards returns `true` if the validator with `consumerValidatorHeight` has been a consumer +// validator for a long period of time and hence is eligible to receive rewards, and false otherwise +func (k Keeper) IsEligibleForConsumerRewards(ctx sdk.Context, consumerValidatorHeight int64) bool { + numberOfBlocksToStartReceivingRewards := k.GetNumberOfEpochsToStartReceivingRewards(ctx) * k.GetBlocksPerEpoch(ctx) + + // a validator is eligible for rewards if it has been a consumer validator for `NumberOfEpochsToStartReceivingRewards` epochs + return (ctx.BlockHeight() - consumerValidatorHeight) >= numberOfBlocksToStartReceivingRewards +} + +// AllocateTokensToConsumerValidators allocates tokens +// to the given consumer chain's validator set +func (k Keeper) AllocateTokensToConsumerValidators( + ctx sdk.Context, + chainID string, + tokens sdk.DecCoins, +) (allocated sdk.DecCoins) { + // return early if the tokens are empty + if tokens.Empty() { + return allocated + } + + // get the total voting power of the consumer valset + totalPower := math.LegacyNewDec(k.ComputeConsumerTotalVotingPower(ctx, chainID)) + if totalPower.IsZero() { + return allocated + } + + // Allocate tokens by iterating over the consumer validators + for _, consumerVal := range k.GetConsumerValSet(ctx, chainID) { + // if a validator is not eligible, this means that the other eligible validators would get more rewards + if !k.IsEligibleForConsumerRewards(ctx, consumerVal.JoinHeight) { + continue } + + consAddr := sdk.ConsAddress(consumerVal.ProviderConsAddr) + + // get the validator tokens fraction using its voting power + powerFraction := math.LegacyNewDec(consumerVal.Power).QuoTruncate(totalPower) + tokensFraction := tokens.MulDecTruncate(powerFraction) + + // get the validator type struct for the consensus address + val, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + if err != nil { + k.Logger(ctx).Error( + "cannot find validator by consensus address", + consAddr, + "while allocating rewards from consumer chain", + chainID, + "error", + err, + ) + continue + } + + // check if the validator set a custom commission rate for the consumer chain + if cr, found := k.GetConsumerCommissionRate(ctx, chainID, types.NewProviderConsAddress(consAddr)); found { + // set the validator commission rate + val.Commission.CommissionRates.Rate = cr + } + + // allocate the consumer reward tokens to the validator + err = k.distributionKeeper.AllocateTokensToValidator( + ctx, + val, + tokensFraction, + ) + if err != nil { + k.Logger(ctx).Error("fail to allocate tokens to validator :%s while allocating rewards from consumer chain: %s", + consAddr, chainID) + continue + } + + // sum the tokens allocated + allocated = allocated.Add(tokensFraction...) + } + + return allocated +} + +// consumer reward pools getter and setter + +// GetConsumerRewardsAllocation returns the consumer rewards allocation for the given chain ID +func (k Keeper) GetConsumerRewardsAllocation(ctx sdk.Context, chainID string) (pool types.ConsumerRewardsAllocation) { + store := ctx.KVStore(k.storeKey) + b := store.Get(types.ConsumerRewardsAllocationKey(chainID)) + k.cdc.MustUnmarshal(b, &pool) + return +} + +// SetConsumerRewardsAllocation sets the consumer rewards allocation for the given chain ID +func (k Keeper) SetConsumerRewardsAllocation(ctx sdk.Context, chainID string, pool types.ConsumerRewardsAllocation) { + store := ctx.KVStore(k.storeKey) + b := k.cdc.MustMarshal(&pool) + store.Set(types.ConsumerRewardsAllocationKey(chainID), b) +} + +// GetConsumerRewardsPool returns the balance +// of the consumer rewards pool module account +func (k Keeper) GetConsumerRewardsPool(ctx sdk.Context) sdk.Coins { + return k.bankKeeper.GetAllBalances( + ctx, + k.accountKeeper.GetModuleAccount(ctx, types.ConsumerRewardsPool).GetAddress(), + ) +} + +// ComputeConsumerTotalVotingPower returns the validator set total voting power +// for the given consumer chain +func (k Keeper) ComputeConsumerTotalVotingPower(ctx sdk.Context, chainID string) (totalPower int64) { + // sum the consumer validators set voting powers + for _, v := range k.GetConsumerValSet(ctx, chainID) { + + // only consider the voting power of a validator that would receive rewards (i.e., validator has been validating for a number of blocks) + if !k.IsEligibleForConsumerRewards(ctx, v.JoinHeight) { + continue + } + + totalPower += v.Power + } + + return +} + +// IdentifyConsumerChainIDFromIBCPacket checks if the packet destination matches a registered consumer chain. +// If so, it returns the consumer chain ID, otherwise an error. +func (k Keeper) IdentifyConsumerChainIDFromIBCPacket(ctx sdk.Context, packet channeltypes.Packet) (string, error) { + channel, ok := k.channelKeeper.GetChannel(ctx, packet.DestinationPort, packet.DestinationChannel) + if !ok { + return "", errorsmod.Wrapf(channeltypes.ErrChannelNotFound, "channel not found for channel ID: %s", packet.DestinationChannel) + } + if len(channel.ConnectionHops) != 1 { + return "", errorsmod.Wrap(channeltypes.ErrTooManyConnectionHops, "must have direct connection to consumer chain") + } + connectionID := channel.ConnectionHops[0] + _, tmClient, err := k.getUnderlyingClient(ctx, connectionID) + if err != nil { + return "", err + } + + chainID := tmClient.ChainId + if _, ok := k.GetChainToChannel(ctx, chainID); !ok { + return "", errorsmod.Wrapf(types.ErrUnknownConsumerChannelId, "no CCV channel found for chain with ID: %s", chainID) + } + + return chainID, nil +} + +// HandleSetConsumerCommissionRate sets a per-consumer chain commission rate for the given provider address +// on the condition that the given consumer chain exists. +func (k Keeper) HandleSetConsumerCommissionRate(ctx sdk.Context, chainID string, providerAddr types.ProviderConsAddress, commissionRate math.LegacyDec) error { + // check that the consumer chain exists + if !k.IsConsumerProposedOrRegistered(ctx, chainID) { + return errorsmod.Wrapf( + types.ErrUnknownConsumerChainId, + "unknown consumer chain, with id: %s", chainID) + } + + // validate against the minimum commission rate + minRate, err := k.stakingKeeper.MinCommissionRate(ctx) + if err != nil { + return err + } + if commissionRate.LT(minRate) { + return errorsmod.Wrapf( + stakingtypes.ErrCommissionLTMinRate, + "commission rate cannot be less than %s", minRate, + ) } + // set per-consumer chain commission rate for the validator address + return k.SetConsumerCommissionRate( + ctx, + chainID, + providerAddr, + commissionRate, + ) } diff --git a/x/ccv/provider/keeper/distribution_test.go b/x/ccv/provider/keeper/distribution_test.go new file mode 100644 index 0000000000..ba79458e00 --- /dev/null +++ b/x/ccv/provider/keeper/distribution_test.go @@ -0,0 +1,299 @@ +package keeper_test + +import ( + "testing" + + "cosmossdk.io/math" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + conntypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + + tmtypes "github.com/cometbft/cometbft/types" + + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" +) + +func TestComputeConsumerTotalVotingPower(t *testing.T) { + keeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + // `ComputeConsumerTotalVotingPower` used in this test retrieves the blocks per epoch, so we need to set this param + params := providertypes.DefaultParams() + params.BlocksPerEpoch = 1 + keeper.SetParams(ctx, params) + + // increase the block height so validators are eligible for consumer rewards (see `IsEligibleForConsumerRewards`) + ctx = ctx.WithBlockHeight(params.NumberOfEpochsToStartReceivingRewards * params.BlocksPerEpoch) + + createVal := func(power int64) tmtypes.Validator { + signer := tmtypes.NewMockPV() + val := tmtypes.NewValidator(signer.PrivKey.PubKey(), power) + return *val + } + + chainID := "consumer" + expTotalPower := int64(0) + + // verify that the total power returned is equal to zero + // when the consumer doesn't exist or has no validators. + require.Zero(t, keeper.ComputeConsumerTotalVotingPower( + ctx, + chainID, + )) + + // set 5 validators to the consumer chain + for i := 0; i < 5; i++ { + val := createVal(int64(i)) + keeper.SetConsumerValidator( + ctx, + chainID, + types.ConsumerValidator{ + ProviderConsAddr: val.Address, + Power: val.VotingPower, + }, + ) + + expTotalPower += val.VotingPower + } + + // compute the total power of opted-in validators + res := keeper.ComputeConsumerTotalVotingPower( + ctx, + chainID, + ) + + // check the total power returned + require.Equal(t, expTotalPower, res) +} + +func TestIdentifyConsumerChainIDFromIBCPacket(t *testing.T) { + var ( + chainID = "consumer" + ccvChannel = "channel-0" + ) + + testCases := []struct { + name string + packet channeltypes.Packet + expectedCalls func(sdk.Context, testkeeper.MockedKeepers, channeltypes.Packet) []*gomock.Call + expCCVChannel bool + expErr bool + }{ + { + "channel not found", + channeltypes.NewPacket( + []byte{}, + 0, + "srcPort", + "srcChannel", + "dstPort", + "dstChannel", + clienttypes.NewHeight(1, 1), + 0, + ), + func(ctx sdk.Context, mocks testkeeper.MockedKeepers, packet channeltypes.Packet) []*gomock.Call { + return []*gomock.Call{ + mocks.MockChannelKeeper.EXPECT().GetChannel( + ctx, + packet.DestinationPort, + packet.DestinationChannel, + ).Return(channeltypes.Channel{}, false).Times(1), + } + }, + false, + true, + }, + { + "connection hops can't be greater than 1", + channeltypes.NewPacket( + []byte{}, + 0, + "srcPort", + "srcChannel", + "dstPort", + "dstChannel", + clienttypes.NewHeight(1, 1), + 0, + ), + func(ctx sdk.Context, mocks testkeeper.MockedKeepers, packet channeltypes.Packet) []*gomock.Call { + return []*gomock.Call{ + mocks.MockChannelKeeper.EXPECT().GetChannel( + ctx, + packet.DestinationPort, + packet.DestinationChannel, + ).Return(channeltypes.Channel{ConnectionHops: []string{"conn1", "conn2"}}, true).Times(1), + } + }, + false, + true, + }, + { + "underlying client isn't found", + channeltypes.NewPacket( + []byte{}, + 0, + "srcPort", + "srcChannel", + "dstPort", + "dstChannel", + clienttypes.NewHeight(1, 1), + 0, + ), + func(ctx sdk.Context, mocks testkeeper.MockedKeepers, packet channeltypes.Packet) []*gomock.Call { + return []*gomock.Call{ + mocks.MockChannelKeeper.EXPECT().GetChannel( + ctx, + packet.DestinationPort, + packet.DestinationChannel, + ).Return(channeltypes.Channel{ConnectionHops: []string{"connectionID"}}, true).Times(1), + mocks.MockConnectionKeeper.EXPECT().GetConnection(ctx, "connectionID").Return( + conntypes.ConnectionEnd{ClientId: "clientID"}, true, + ).Times(1), + mocks.MockClientKeeper.EXPECT().GetClientState(ctx, "clientID").Return( + &ibctmtypes.ClientState{ChainId: ""}, false, + ).Times(1), + } + }, + false, + true, + }, + { + "no CCV channel registered", + channeltypes.NewPacket( + []byte{}, + 0, + "srcPort", + "srcChannel", + "dstPort", + "dstChannel", + clienttypes.NewHeight(1, 1), + 0, + ), + func(ctx sdk.Context, mocks testkeeper.MockedKeepers, packet channeltypes.Packet) []*gomock.Call { + return []*gomock.Call{ + mocks.MockChannelKeeper.EXPECT().GetChannel( + ctx, + packet.DestinationPort, + packet.DestinationChannel, + ).Return(channeltypes.Channel{ConnectionHops: []string{"connectionID"}}, true).Times(1), + mocks.MockConnectionKeeper.EXPECT().GetConnection(ctx, "connectionID").Return( + conntypes.ConnectionEnd{ClientId: "clientID"}, true, + ).Times(1), + mocks.MockClientKeeper.EXPECT().GetClientState(ctx, "clientID").Return( + &ibctmtypes.ClientState{ChainId: chainID}, true, + ).Times(1), + } + }, + false, + true, + }, + { + "consumer chain identified", + channeltypes.NewPacket( + []byte{}, + 0, + "srcPort", + "srcChannel", + "dstPort", + "dstChannel", + clienttypes.NewHeight(1, 1), + 0, + ), + func(ctx sdk.Context, mocks testkeeper.MockedKeepers, packet channeltypes.Packet) []*gomock.Call { + return []*gomock.Call{ + mocks.MockChannelKeeper.EXPECT().GetChannel( + ctx, + packet.DestinationPort, + packet.DestinationChannel, + ), + } + }, + false, + true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + keeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + tc.expectedCalls(ctx, mocks, tc.packet) + _, err := keeper.IdentifyConsumerChainIDFromIBCPacket( + ctx, + tc.packet, + ) + + if tc.expCCVChannel { + keeper.SetChainToChannel(ctx, chainID, ccvChannel) + } + + if !tc.expErr { + require.NoError(t, err) + } else { + require.Error(t, err) + } + }) + } +} + +func TestSetConsumerRewardsAllocation(t *testing.T) { + keeperParams := testkeeper.NewInMemKeeperParams(t) + ctx := keeperParams.Ctx + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mocks := testkeeper.NewMockedKeepers(ctrl) + providerKeeper := testkeeper.NewInMemProviderKeeper(keeperParams, mocks) + + rewardAllocation := providertypes.ConsumerRewardsAllocation{ + Rewards: sdk.NewDecCoins(sdk.NewDecCoin("uatom", math.NewInt(1000))), + } + + providerKeeper.SetConsumerRewardsAllocation(ctx, "consumer-1", rewardAllocation) + + alloc := providerKeeper.GetConsumerRewardsAllocation(ctx, "consumer-1") + require.Equal(t, rewardAllocation, alloc) +} + +func TestGetConsumerRewardsAllocationNil(t *testing.T) { + keeperParams := testkeeper.NewInMemKeeperParams(t) + ctx := keeperParams.Ctx + + ctrl := gomock.NewController(t) + defer ctrl.Finish() + mocks := testkeeper.NewMockedKeepers(ctrl) + providerKeeper := testkeeper.NewInMemProviderKeeper(keeperParams, mocks) + + alloc := providerKeeper.GetConsumerRewardsAllocation(ctx, "consumer-1") + + expectedRewardAllocation := providertypes.ConsumerRewardsAllocation{ + Rewards: nil, + } + require.Equal(t, expectedRewardAllocation, alloc) +} + +func TestIsEligibleForConsumerRewards(t *testing.T) { + keeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + params := providertypes.DefaultParams() + params.NumberOfEpochsToStartReceivingRewards = 10 + params.BlocksPerEpoch = 5 + keeper.SetParams(ctx, params) + + numberOfBlocks := params.NumberOfEpochsToStartReceivingRewards * params.BlocksPerEpoch + + require.False(t, keeper.IsEligibleForConsumerRewards(ctx.WithBlockHeight(numberOfBlocks-1), 0)) + require.True(t, keeper.IsEligibleForConsumerRewards(ctx.WithBlockHeight(numberOfBlocks), 0)) + require.True(t, keeper.IsEligibleForConsumerRewards(ctx.WithBlockHeight(numberOfBlocks+1), 0)) + require.True(t, keeper.IsEligibleForConsumerRewards(ctx.WithBlockHeight(numberOfBlocks+1), 1)) + require.False(t, keeper.IsEligibleForConsumerRewards(ctx.WithBlockHeight(numberOfBlocks+1), 2)) +} diff --git a/x/ccv/provider/keeper/genesis.go b/x/ccv/provider/keeper/genesis.go index 66895233a7..b8d6d179fc 100644 --- a/x/ccv/provider/keeper/genesis.go +++ b/x/ccv/provider/keeper/genesis.go @@ -108,47 +108,51 @@ func (k Keeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState) { // ExportGenesis returns the CCV provider module's exported genesis func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { // get a list of all registered consumer chains - registeredChains := k.GetAllConsumerChains(ctx) + registeredChainIDs := k.GetAllRegisteredConsumerChainIDs(ctx) var exportedVscSendTimestamps []types.ExportedVscSendTimestamp // export states for each consumer chains var consumerStates []types.ConsumerState - for _, chain := range registeredChains { - gen, found := k.GetConsumerGenesis(ctx, chain.ChainId) + for _, chainID := range registeredChainIDs { + // no need for the second return value of GetConsumerClientId + // as GetAllRegisteredConsumerChainIDs already iterated through + // the entire prefix range + clientID, _ := k.GetConsumerClientId(ctx, chainID) + gen, found := k.GetConsumerGenesis(ctx, chainID) if !found { - panic(fmt.Errorf("cannot find genesis for consumer chain %s with client %s", chain.ChainId, chain.ClientId)) + panic(fmt.Errorf("cannot find genesis for consumer chain %s with client %s", chainID, clientID)) } // initial consumer chain states cs := types.ConsumerState{ - ChainId: chain.ChainId, - ClientId: chain.ClientId, + ChainId: chainID, + ClientId: clientID, ConsumerGenesis: gen, - UnbondingOpsIndex: k.GetAllUnbondingOpIndexes(ctx, chain.ChainId), + UnbondingOpsIndex: k.GetAllUnbondingOpIndexes(ctx, chainID), } // try to find channel id for the current consumer chain - channelId, found := k.GetChainToChannel(ctx, chain.ChainId) + channelId, found := k.GetChainToChannel(ctx, chainID) if found { cs.ChannelId = channelId - cs.InitialHeight, found = k.GetInitChainHeight(ctx, chain.ChainId) + cs.InitialHeight, found = k.GetInitChainHeight(ctx, chainID) if !found { - panic(fmt.Errorf("cannot find init height for consumer chain %s", chain.ChainId)) + panic(fmt.Errorf("cannot find init height for consumer chain %s", chainID)) } - cs.SlashDowntimeAck = k.GetSlashAcks(ctx, chain.ChainId) + cs.SlashDowntimeAck = k.GetSlashAcks(ctx, chainID) } - cs.PendingValsetChanges = k.GetPendingVSCPackets(ctx, chain.ChainId) + cs.PendingValsetChanges = k.GetPendingVSCPackets(ctx, chainID) consumerStates = append(consumerStates, cs) - vscSendTimestamps := k.GetAllVscSendTimestamps(ctx, chain.ChainId) - exportedVscSendTimestamps = append(exportedVscSendTimestamps, types.ExportedVscSendTimestamp{ChainId: chain.ChainId, VscSendTimestamps: vscSendTimestamps}) + vscSendTimestamps := k.GetAllVscSendTimestamps(ctx, chainID) + exportedVscSendTimestamps = append(exportedVscSendTimestamps, types.ExportedVscSendTimestamp{ChainId: chainID, VscSendTimestamps: vscSendTimestamps}) } // ConsumerAddrsToPrune are added only for registered consumer chains consumerAddrsToPrune := []types.ConsumerAddrsToPrune{} - for _, chain := range registeredChains { - consumerAddrsToPrune = append(consumerAddrsToPrune, k.GetAllConsumerAddrsToPrune(ctx, chain.ChainId)...) + for _, chainID := range registeredChainIDs { + consumerAddrsToPrune = append(consumerAddrsToPrune, k.GetAllConsumerAddrsToPrune(ctx, chainID)...) } params := k.GetParams(ctx) diff --git a/x/ccv/provider/keeper/grpc_query.go b/x/ccv/provider/keeper/grpc_query.go index daaca81e81..d2a36c686d 100644 --- a/x/ccv/provider/keeper/grpc_query.go +++ b/x/ccv/provider/keeper/grpc_query.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "fmt" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -45,17 +46,66 @@ func (k Keeper) QueryConsumerChains(goCtx context.Context, req *types.QueryConsu ctx := sdk.UnwrapSDKContext(goCtx) - // convert to array of pointers chains := []*types.Chain{} - for _, chain := range k.GetAllConsumerChains(ctx) { - // prevent implicit memory aliasing - c := chain + for _, chainID := range k.GetAllRegisteredConsumerChainIDs(ctx) { + c, err := k.GetConsumerChain(ctx, chainID) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } chains = append(chains, &c) } return &types.QueryConsumerChainsResponse{Chains: chains}, nil } +// GetConsumerChain returns a Chain data structure with all the necessary fields +func (k Keeper) GetConsumerChain(ctx sdk.Context, chainID string) (types.Chain, error) { + clientID, found := k.GetConsumerClientId(ctx, chainID) + if !found { + return types.Chain{}, fmt.Errorf("cannot find clientID for consumer (%s)", chainID) + } + + topN, found := k.GetTopN(ctx, chainID) + if !found { + k.Logger(ctx).Error("failed to get top N, treating as 0", "chain", chainID) + topN = 0 + } + + // Get the minimal power in the top N for the consumer chain + minPowerInTopN, found := k.GetMinimumPowerInTopN(ctx, chainID) + if !found { + k.Logger(ctx).Error("failed to get minimum power in top N, treating as -1", "chain", chainID) + minPowerInTopN = -1 + } + + validatorSetCap, _ := k.GetValidatorSetCap(ctx, chainID) + + validatorsPowerCap, _ := k.GetValidatorsPowerCap(ctx, chainID) + + allowlist := k.GetAllowList(ctx, chainID) + strAllowlist := make([]string, len(allowlist)) + for i, addr := range allowlist { + strAllowlist[i] = addr.String() + } + + denylist := k.GetDenyList(ctx, chainID) + strDenylist := make([]string, len(denylist)) + for i, addr := range denylist { + strDenylist[i] = addr.String() + } + + return types.Chain{ + ChainId: chainID, + ClientId: clientID, + Top_N: topN, + MinPowerInTop_N: minPowerInTopN, + ValidatorSetCap: validatorSetCap, + ValidatorsPowerCap: validatorsPowerCap, + Allowlist: strAllowlist, + Denylist: strDenylist, + }, nil +} + func (k Keeper) QueryConsumerChainStarts(goCtx context.Context, req *types.QueryConsumerChainStartProposalsRequest) (*types.QueryConsumerChainStartProposalsResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") @@ -229,6 +279,185 @@ func (k Keeper) QueryParams(goCtx context.Context, req *types.QueryParamsRequest return &types.QueryParamsResponse{Params: params}, nil } +// QueryConsumerChainOptedInValidators returns all validators that opted-in to a given consumer chain +func (k Keeper) QueryConsumerChainOptedInValidators(goCtx context.Context, req *types.QueryConsumerChainOptedInValidatorsRequest) (*types.QueryConsumerChainOptedInValidatorsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + consumerChainID := req.ChainId + if consumerChainID == "" { + return nil, status.Error(codes.InvalidArgument, "empty chainId") + } + + optedInVals := []string{} + ctx := sdk.UnwrapSDKContext(goCtx) + + if !k.IsConsumerProposedOrRegistered(ctx, consumerChainID) { + return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("unknown consumer chain: %s", consumerChainID)) + } + + for _, v := range k.GetAllOptedIn(ctx, consumerChainID) { + optedInVals = append(optedInVals, v.ToSdkConsAddr().String()) + } + + return &types.QueryConsumerChainOptedInValidatorsResponse{ + ValidatorsProviderAddresses: optedInVals, + }, nil +} + +// QueryConsumerValidators returns all validators that are consumer validators in a given consumer chain +func (k Keeper) QueryConsumerValidators(goCtx context.Context, req *types.QueryConsumerValidatorsRequest) (*types.QueryConsumerValidatorsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + consumerChainID := req.ChainId + if consumerChainID == "" { + return nil, status.Error(codes.InvalidArgument, "empty chainId") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + if _, found := k.GetConsumerClientId(ctx, consumerChainID); !found { + // chain has to have started; consumer client id is set for a chain during the chain's spawn time + return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("no started consumer chain: %s", consumerChainID)) + } + + var validators []*types.QueryConsumerValidatorsValidator + for _, v := range k.GetConsumerValSet(ctx, consumerChainID) { + validators = append(validators, &types.QueryConsumerValidatorsValidator{ + ProviderAddress: sdk.ConsAddress(v.ProviderConsAddr).String(), + ConsumerKey: v.ConsumerPublicKey, + Power: v.Power, + }) + } + + return &types.QueryConsumerValidatorsResponse{ + Validators: validators, + }, nil +} + +// QueryConsumerChainsValidatorHasToValidate returns all consumer chains that the given validator has to validate now +// or in the next epoch if nothing changes. +func (k Keeper) QueryConsumerChainsValidatorHasToValidate(goCtx context.Context, req *types.QueryConsumerChainsValidatorHasToValidateRequest) (*types.QueryConsumerChainsValidatorHasToValidateResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + if req.ProviderAddress == "" { + return nil, status.Error(codes.InvalidArgument, "empty provider address") + } + + consAddr, err := sdk.ConsAddressFromBech32(req.ProviderAddress) + if err != nil { + return nil, status.Error(codes.InvalidArgument, "invalid provider address") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + provAddr := types.NewProviderConsAddress(consAddr) + + // get all the consumer chains for which the validator is either already + // opted-in, currently a consumer validator or if its voting power is within the TopN validators + consumersToValidate := []string{} + for _, consumerChainID := range k.GetAllRegisteredConsumerChainIDs(ctx) { + if hasToValidate, err := k.hasToValidate(ctx, provAddr, consumerChainID); err == nil && hasToValidate { + consumersToValidate = append(consumersToValidate, consumerChainID) + } + } + + return &types.QueryConsumerChainsValidatorHasToValidateResponse{ + ConsumerChainIds: consumersToValidate, + }, nil +} + +// hasToValidate checks if a validator needs to validate on a consumer chain +func (k Keeper) hasToValidate( + ctx sdk.Context, + provAddr types.ProviderConsAddress, + chainID string, +) (bool, error) { + // if the validator was sent as part of the packet in the last epoch, it has to validate + if k.IsConsumerValidator(ctx, chainID, provAddr) { + return true, nil + } + + // if the validator was not part of the last epoch, check if the validator is going to be part of te next epoch + bondedValidators, err := k.GetLastBondedValidators(ctx) + if err != nil { + return false, nil + } + if topN, found := k.GetTopN(ctx, chainID); found && topN > 0 { + // in a Top-N chain, we automatically opt in all validators that belong to the top N + minPower, found := k.GetMinimumPowerInTopN(ctx, chainID) + if found { + k.OptInTopNValidators(ctx, chainID, bondedValidators, minPower) + } else { + k.Logger(ctx).Error("did not find min power in top N for chain", "chain", chainID) + } + } + + // if the validator is opted in and belongs to the validators of the next epoch, then if nothing changes + // the validator would have to validate in the next epoch + if k.IsOptedIn(ctx, chainID, provAddr) { + lastVals, err := k.GetLastBondedValidators(ctx) + if err != nil { + return false, err + } + nextValidators := k.ComputeNextValidators(ctx, chainID, lastVals) + for _, v := range nextValidators { + consAddr := sdk.ConsAddress(v.ProviderConsAddr) + if provAddr.ToSdkConsAddr().Equals(consAddr) { + return true, nil + } + } + } + + return false, nil +} + +// QueryValidatorConsumerCommissionRate returns the commission rate a given +// validator charges on a given consumer chain +func (k Keeper) QueryValidatorConsumerCommissionRate(goCtx context.Context, req *types.QueryValidatorConsumerCommissionRateRequest) (*types.QueryValidatorConsumerCommissionRateResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + consumerChainID := req.ChainId + if consumerChainID == "" { + return nil, status.Error(codes.InvalidArgument, "empty chainId") + } + + consAddr, err := sdk.ConsAddressFromBech32(req.ProviderAddress) + if err != nil { + return nil, status.Error(codes.InvalidArgument, "invalid provider address") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + if !k.IsConsumerProposedOrRegistered(ctx, consumerChainID) { + return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("unknown consumer chain: %s", consumerChainID)) + } + + res := &types.QueryValidatorConsumerCommissionRateResponse{} + + // Check if the validator has a commission rate set for the consumer chain, + // otherwise use the commission rate from the validator staking module struct + consumerRate, found := k.GetConsumerCommissionRate(ctx, consumerChainID, types.NewProviderConsAddress(consAddr)) + if found { + res.Rate = consumerRate + } else { + v, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + if err != nil { + return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("unknown validator: %s", consAddr.String())) + } + res.Rate = v.Commission.Rate + } + + return res, nil +} + func (k Keeper) QueryOldestUnconfirmedVsc(goCtx context.Context, req *types.QueryOldestUnconfirmedVscRequest) (*types.QueryOldestUnconfirmedVscResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) diff --git a/x/ccv/provider/keeper/grpc_query_test.go b/x/ccv/provider/keeper/grpc_query_test.go index 3e252a7069..3d9f9ee86d 100644 --- a/x/ccv/provider/keeper/grpc_query_test.go +++ b/x/ccv/provider/keeper/grpc_query_test.go @@ -1,16 +1,22 @@ package keeper_test import ( + "fmt" "testing" "time" - "github.com/stretchr/testify/require" + "cosmossdk.io/math" + "github.com/cometbft/cometbft/proto/tendermint/crypto" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/golang/mock/gomock" + sdk "github.com/cosmos/cosmos-sdk/types" sdktypes "github.com/cosmos/cosmos-sdk/types" cryptotestutil "github.com/cosmos/interchain-security/v5/testutil/crypto" testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" + "github.com/stretchr/testify/require" ) func TestQueryAllPairsValConAddrByConsumerChainID(t *testing.T) { @@ -102,3 +108,242 @@ func TestQueryOldestUnconfirmedVsc(t *testing.T) { } require.Equal(t, expectedResult, response.VscSendTimestamp) } + +func TestQueryConsumerChainOptedInValidators(t *testing.T) { + chainID := "chainID" + + pk, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + req := types.QueryConsumerChainOptedInValidatorsRequest{ + ChainId: chainID, + } + + // error returned from not yet proposed or not yet registered chain + _, err := pk.QueryConsumerChainOptedInValidators(ctx, &req) + require.Error(t, err) + + pk.SetProposedConsumerChain(ctx, chainID, 1) + + providerAddr1 := types.NewProviderConsAddress([]byte("providerAddr1")) + providerAddr2 := types.NewProviderConsAddress([]byte("providerAddr2")) + expectedResponse := types.QueryConsumerChainOptedInValidatorsResponse{ + ValidatorsProviderAddresses: []string{providerAddr1.String(), providerAddr2.String()}, + } + + pk.SetOptedIn(ctx, chainID, providerAddr1) + pk.SetOptedIn(ctx, chainID, providerAddr2) + res, err := pk.QueryConsumerChainOptedInValidators(ctx, &req) + require.NoError(t, err) + require.Equal(t, &expectedResponse, res) +} + +func TestQueryConsumerValidators(t *testing.T) { + chainID := "chainID" + + pk, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + req := types.QueryConsumerValidatorsRequest{ + ChainId: chainID, + } + + // error returned from not-started chain + _, err := pk.QueryConsumerValidators(ctx, &req) + require.Error(t, err) + + providerAddr1 := types.NewProviderConsAddress([]byte("providerAddr1")) + consumerKey1 := cryptotestutil.NewCryptoIdentityFromIntSeed(1).TMProtoCryptoPublicKey() + consumerValidator1 := types.ConsumerValidator{ProviderConsAddr: providerAddr1.ToSdkConsAddr(), Power: 1, ConsumerPublicKey: &consumerKey1} + + providerAddr2 := types.NewProviderConsAddress([]byte("providerAddr2")) + consumerKey2 := cryptotestutil.NewCryptoIdentityFromIntSeed(2).TMProtoCryptoPublicKey() + consumerValidator2 := types.ConsumerValidator{ProviderConsAddr: providerAddr2.ToSdkConsAddr(), Power: 2, ConsumerPublicKey: &consumerKey2} + + expectedResponse := types.QueryConsumerValidatorsResponse{ + Validators: []*types.QueryConsumerValidatorsValidator{ + {providerAddr1.String(), &consumerKey1, 1}, + {providerAddr2.String(), &consumerKey2, 2}, + }, + } + + // set up the client id so the chain looks like it "started" + pk.SetConsumerClientId(ctx, chainID, "clientID") + pk.SetConsumerValSet(ctx, chainID, []types.ConsumerValidator{consumerValidator1, consumerValidator2}) + + res, err := pk.QueryConsumerValidators(ctx, &req) + require.NoError(t, err) + require.Equal(t, &expectedResponse, res) +} + +func TestQueryConsumerChainsValidatorHasToValidate(t *testing.T) { + pk, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + val := createStakingValidator(ctx, mocks, 1, 1, 1) + valConsAddr, _ := val.GetConsAddr() + providerAddr := types.NewProviderConsAddress(valConsAddr) + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valConsAddr).Return(val, nil).AnyTimes() + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 1, []stakingtypes.Validator{val}, []int64{1}, -1) // -1 to allow the calls "AnyTimes" + + req := types.QueryConsumerChainsValidatorHasToValidateRequest{ + ProviderAddress: providerAddr.String(), + } + + // set up some consumer chains + consumerChains := []string{"chain1", "chain2", "chain3", "chain4"} + for _, cc := range consumerChains { + pk.SetConsumerClientId(ctx, cc, "clientID") + } + + // set `providerAddr` as a consumer validator on "chain1" + pk.SetConsumerValidator(ctx, "chain1", types.ConsumerValidator{ + ProviderConsAddr: providerAddr.ToSdkConsAddr(), + Power: 1, + ConsumerPublicKey: &crypto.PublicKey{ + Sum: &crypto.PublicKey_Ed25519{ + Ed25519: []byte{1}, + }, + }, + }) + + // set `providerAddr` as an opted-in validator on "chain3" + pk.SetOptedIn(ctx, "chain3", providerAddr) + + // `providerAddr` has to validate "chain1" because it is a consumer validator in this chain, as well as "chain3" + // because it opted in, in "chain3" and `providerAddr` belongs to the bonded validators + expectedChains := []string{"chain1", "chain3"} + + res, err := pk.QueryConsumerChainsValidatorHasToValidate(ctx, &req) + require.NoError(t, err) + require.Equal(t, expectedChains, res.ConsumerChainIds) +} + +func TestQueryValidatorConsumerCommissionRate(t *testing.T) { + chainID := "chainID" + + pk, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerAddr := types.NewProviderConsAddress([]byte("providerAddr")) + req := types.QueryValidatorConsumerCommissionRateRequest{ + ChainId: chainID, + ProviderAddress: providerAddr.String(), + } + + // error returned from not yet proposed or not yet registered chain + _, err := pk.QueryValidatorConsumerCommissionRate(ctx, &req) + require.Error(t, err) + + pk.SetProposedConsumerChain(ctx, chainID, 1) + // validator with set consumer commission rate + expectedCommissionRate := math.LegacyMustNewDecFromStr("0.123") + pk.SetConsumerCommissionRate(ctx, chainID, providerAddr, expectedCommissionRate) + res, _ := pk.QueryValidatorConsumerCommissionRate(ctx, &req) + require.Equal(t, expectedCommissionRate, res.Rate) + + // validator with no set consumer commission rate + pk.DeleteConsumerCommissionRate(ctx, chainID, providerAddr) + expectedCommissionRate = math.LegacyMustNewDecFromStr("0.456") + + // because no consumer commission rate is set, the validator's set commission rate on the provider is used + val := stakingtypes.Validator{Commission: stakingtypes.Commission{CommissionRates: stakingtypes.CommissionRates{Rate: expectedCommissionRate}}} + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( + ctx, providerAddr.ToSdkConsAddr()).Return(val, nil).Times(1) + res, _ = pk.QueryValidatorConsumerCommissionRate(ctx, &req) + require.Equal(t, expectedCommissionRate, res.Rate) +} + +// TestGetConsumerChain tests GetConsumerChain behaviour correctness +func TestGetConsumerChain(t *testing.T) { + pk, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + chainIDs := []string{"chain-1", "chain-2", "chain-3", "chain-4"} + + // mock the validator set + vals := []stakingtypes.Validator{ + {OperatorAddress: "cosmosvaloper1c4k24jzduc365kywrsvf5ujz4ya6mwympnc4en"}, // 50 power + {OperatorAddress: "cosmosvaloper196ax4vc0lwpxndu9dyhvca7jhxp70rmcvrj90c"}, // 150 power + {OperatorAddress: "cosmosvaloper1clpqr4nrk4khgkxj78fcwwh6dl3uw4epsluffn"}, // 300 power + {OperatorAddress: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3"}, // 500 power + } + powers := []int64{50, 150, 300, 500} // sum = 1000 + maxValidators := uint32(180) + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, maxValidators, vals, powers, -1) // -1 to allow the calls "AnyTimes" + + for i, val := range vals { + valAddr, err := sdk.ValAddressFromBech32(val.GetOperator()) + require.NoError(t, err) + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(gomock.Any(), valAddr).Return(powers[i], nil).AnyTimes() + } + + // set Top N parameters, client ids and expected result + topNs := []uint32{0, 70, 90, 100} + expectedMinPowerInTopNs := []int64{ + -1, // Top N is 0, so not a Top N chain + 300, // 500 and 300 are in Top 70% + 150, // 150 is also in the top 90%, + 50, // everyone is in the top 100% + } + + validatorSetCaps := []uint32{0, 5, 10, 20} + validatorPowerCaps := []uint32{0, 5, 10, 33} + allowlists := [][]types.ProviderConsAddress{ + {}, + {types.NewProviderConsAddress([]byte("providerAddr1")), types.NewProviderConsAddress([]byte("providerAddr2"))}, + {types.NewProviderConsAddress([]byte("providerAddr3"))}, + {}, + } + + denylists := [][]types.ProviderConsAddress{ + {types.NewProviderConsAddress([]byte("providerAddr4")), types.NewProviderConsAddress([]byte("providerAddr5"))}, + {}, + {types.NewProviderConsAddress([]byte("providerAddr6"))}, + {}, + } + + expectedGetAllOrder := []types.Chain{} + for i, chainID := range chainIDs { + clientID := fmt.Sprintf("client-%d", len(chainIDs)-i) + topN := topNs[i] + pk.SetConsumerClientId(ctx, chainID, clientID) + pk.SetTopN(ctx, chainID, topN) + pk.SetValidatorSetCap(ctx, chainID, validatorSetCaps[i]) + pk.SetValidatorsPowerCap(ctx, chainID, validatorPowerCaps[i]) + pk.SetMinimumPowerInTopN(ctx, chainID, expectedMinPowerInTopNs[i]) + for _, addr := range allowlists[i] { + pk.SetAllowlist(ctx, chainID, addr) + } + for _, addr := range denylists[i] { + pk.SetDenylist(ctx, chainID, addr) + } + strAllowlist := make([]string, len(allowlists[i])) + for j, addr := range allowlists[i] { + strAllowlist[j] = addr.String() + } + + strDenylist := make([]string, len(denylists[i])) + for j, addr := range denylists[i] { + strDenylist[j] = addr.String() + } + + expectedGetAllOrder = append(expectedGetAllOrder, + types.Chain{ + ChainId: chainID, + ClientId: clientID, + Top_N: topN, + MinPowerInTop_N: expectedMinPowerInTopNs[i], + ValidatorSetCap: validatorSetCaps[i], + ValidatorsPowerCap: validatorPowerCaps[i], + Allowlist: strAllowlist, + Denylist: strDenylist, + }) + } + + for i, chainID := range pk.GetAllRegisteredAndProposedChainIDs(ctx) { + c, err := pk.GetConsumerChain(ctx, chainID) + require.NoError(t, err) + require.Equal(t, expectedGetAllOrder[i], c) + } +} diff --git a/x/ccv/provider/keeper/hooks.go b/x/ccv/provider/keeper/hooks.go index dee2b7869e..81226a2bdf 100644 --- a/x/ccv/provider/keeper/hooks.go +++ b/x/ccv/provider/keeper/hooks.go @@ -10,6 +10,7 @@ import ( v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) @@ -38,9 +39,65 @@ func (h Hooks) AfterUnbondingInitiated(goCtx context.Context, id uint64) error { var consumerChainIDS []string ctx := sdk.UnwrapSDKContext(goCtx) - for _, chain := range h.k.GetAllConsumerChains(ctx) { - consumerChainIDS = append(consumerChainIDS, chain.ChainId) + // get validator address from unbonding operation + unbondingType, err := h.k.stakingKeeper.GetUnbondingType(ctx, id) + vadAddrBech32 := "" + if err != nil { + ctx.Logger().Error("undefined type for unbonding operation: id: %d: %s", id, err) + return nil + } + + switch unbondingType { + case stakingtypes.UnbondingType_UnbondingDelegation: + ubd, err := h.k.stakingKeeper.GetUnbondingDelegationByUnbondingID(ctx, id) + if err != nil { + ctx.Logger().Error("unfound ubonding delegation for unbonding id: %d: %s", id, err) + return nil + } + vadAddrBech32 = ubd.ValidatorAddress + case stakingtypes.UnbondingType_Redelegation: + red, err := h.k.stakingKeeper.GetRedelegationByUnbondingID(ctx, id) + if err != nil { + ctx.Logger().Error("unfound relegation for unbonding operation id: %d: %s", id, err) + return nil + } + vadAddrBech32 = red.ValidatorSrcAddress + case stakingtypes.UnbondingType_ValidatorUnbonding: + val, err := h.k.stakingKeeper.GetValidatorByUnbondingID(ctx, id) + if err != nil { + ctx.Logger().Error("unfound validator for unbonding operation id: %d: %s", id, err) + return nil + } + vadAddrBech32 = val.OperatorAddress + default: + ctx.Logger().Error("invalid unbonding operation type: %s", unbondingType) + return nil + } + + valAddr, err := sdk.ValAddressFromBech32(vadAddrBech32) + if err != nil { + ctx.Logger().Error(err.Error()) + return nil + } + + validator, err := h.k.stakingKeeper.GetValidator(ctx, valAddr) + if err != nil { + ctx.Logger().Error("unfound validator for validator address: %s: %s", vadAddrBech32, err) + return nil + } + + consAddr, err := validator.GetConsAddr() + if err != nil { + ctx.Logger().Error(err.Error()) + return nil + } + + // get all consumers where the validator is in the validator set + for _, chainID := range h.k.GetAllRegisteredConsumerChainIDs(ctx) { + if h.k.IsConsumerValidator(ctx, chainID, types.NewProviderConsAddress(consAddr)) { + consumerChainIDS = append(consumerChainIDS, chainID) + } } if len(consumerChainIDS) == 0 { @@ -141,6 +198,10 @@ func (h Hooks) BeforeDelegationRemoved(_ context.Context, _ sdk.AccAddress, _ sd return nil } +func (h Hooks) BeforeTokenizeShareRecordRemoved(_ context.Context, _ uint64) error { + return nil +} + // // gov hooks // @@ -214,7 +275,3 @@ func (h Hooks) GetConsumerAdditionLegacyPropFromProp( } return providertypes.ConsumerAdditionProposal{}, false } - -func (h Hooks) BeforeTokenizeShareRecordRemoved(_ sdk.Context, _ uint64) error { - return nil -} diff --git a/x/ccv/provider/keeper/hooks_test.go b/x/ccv/provider/keeper/hooks_test.go index 2a6d60db85..2447b5edf3 100644 --- a/x/ccv/provider/keeper/hooks_test.go +++ b/x/ccv/provider/keeper/hooks_test.go @@ -3,13 +3,11 @@ package keeper_test import ( "testing" - "github.com/golang/mock/gomock" - sdk "github.com/cosmos/cosmos-sdk/types" - cryptotestutil "github.com/cosmos/interchain-security/v5/testutil/crypto" testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + "github.com/golang/mock/gomock" ) func TestValidatorConsensusKeyInUse(t *testing.T) { diff --git a/x/ccv/provider/keeper/keeper.go b/x/ccv/provider/keeper/keeper.go index a697eb1b4a..22f5f33626 100644 --- a/x/ccv/provider/keeper/keeper.go +++ b/x/ccv/provider/keeper/keeper.go @@ -8,6 +8,7 @@ import ( "time" addresscodec "cosmossdk.io/core/address" + "cosmossdk.io/math" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" conntypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types" @@ -214,9 +215,14 @@ func (k Keeper) SetProposedConsumerChain(ctx sdk.Context, chainID string, propos } // GetProposedConsumerChain returns the proposed chainID for the given consumerAddition proposal ID. -func (k Keeper) GetProposedConsumerChain(ctx sdk.Context, proposalID uint64) string { +// This method is only used for testing. +func (k Keeper) GetProposedConsumerChain(ctx sdk.Context, proposalID uint64) (string, bool) { store := ctx.KVStore(k.storeKey) - return string(store.Get(types.ProposedConsumerChainKey(proposalID))) + consumerChain := store.Get(types.ProposedConsumerChainKey(proposalID)) + if consumerChain != nil { + return string(consumerChain), true + } + return "", false } // DeleteProposedConsumerChainInStore deletes the consumer chainID from store @@ -260,13 +266,15 @@ func (k Keeper) GetAllPendingConsumerChainIDs(ctx sdk.Context) []string { return chainIDs } -// GetAllConsumerChains gets all of the consumer chains, for which the provider module +// GetAllRegisteredConsumerChainIDs gets all of the consumer chain IDs, for which the provider module // created IBC clients. Consumer chains with created clients are also referred to as registered. // // Note that the registered consumer chains are stored under keys with the following format: // ChainToClientBytePrefix | chainID // Thus, the returned array is in ascending order of chainIDs. -func (k Keeper) GetAllConsumerChains(ctx sdk.Context) (chains []types.Chain) { +func (k Keeper) GetAllRegisteredConsumerChainIDs(ctx sdk.Context) []string { + chainIDs := []string{} + store := ctx.KVStore(k.storeKey) iterator := storetypes.KVStorePrefixIterator(store, []byte{types.ChainToClientBytePrefix}) defer iterator.Close() @@ -274,15 +282,10 @@ func (k Keeper) GetAllConsumerChains(ctx sdk.Context) (chains []types.Chain) { for ; iterator.Valid(); iterator.Next() { // remove 1 byte prefix from key to retrieve chainID chainID := string(iterator.Key()[1:]) - clientID := string(iterator.Value()) - - chains = append(chains, types.Chain{ - ChainId: chainID, - ClientId: clientID, - }) + chainIDs = append(chainIDs, chainID) } - return chains + return chainIDs } // SetChannelToChain sets the mapping from the CCV channel ID to the consumer chainID. @@ -747,13 +750,9 @@ func (k Keeper) GetValidatorSetUpdateId(ctx sdk.Context) (validatorSetUpdateId u bz := store.Get(types.ValidatorSetUpdateIdKey()) if bz == nil { - validatorSetUpdateId = 0 - } else { - // Unmarshal - validatorSetUpdateId = binary.BigEndian.Uint64(bz) + return 0 } - - return validatorSetUpdateId + return binary.BigEndian.Uint64(bz) } // SetValsetUpdateBlockHeight sets the block height for a given valset update id @@ -1152,10 +1151,7 @@ func (k Keeper) BondDenom(ctx sdk.Context) (string, error) { func (k Keeper) GetAllRegisteredAndProposedChainIDs(ctx sdk.Context) []string { allConsumerChains := []string{} - consumerChains := k.GetAllConsumerChains(ctx) - for _, consumerChain := range consumerChains { - allConsumerChains = append(allConsumerChains, consumerChain.ChainId) - } + allConsumerChains = append(allConsumerChains, k.GetAllRegisteredConsumerChainIDs(ctx)...) proposedChains := k.GetAllProposedConsumerChainIDs(ctx) for _, proposedChain := range proposedChains { allConsumerChains = append(allConsumerChains, proposedChain.ChainID) @@ -1165,3 +1161,424 @@ func (k Keeper) GetAllRegisteredAndProposedChainIDs(ctx sdk.Context) []string { return allConsumerChains } + +// SetTopN stores the N value associated to chain with `chainID` +func (k Keeper) SetTopN( + ctx sdk.Context, + chainID string, + N uint32, +) { + store := ctx.KVStore(k.storeKey) + + buf := make([]byte, 4) + binary.BigEndian.PutUint32(buf, N) + + store.Set(types.TopNKey(chainID), buf) +} + +// DeleteTopN removes the N value associated to chain with `chainID` +func (k Keeper) DeleteTopN( + ctx sdk.Context, + chainID string, +) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.TopNKey(chainID)) +} + +// GetTopN returns (N, true) if chain `chainID` has a top N associated, and (0, false) otherwise. +func (k Keeper) GetTopN( + ctx sdk.Context, + chainID string, +) (uint32, bool) { + store := ctx.KVStore(k.storeKey) + buf := store.Get(types.TopNKey(chainID)) + if buf == nil { + return 0, false + } + return binary.BigEndian.Uint32(buf), true +} + +// IsTopN returns true if chain with `chainID` is a Top-N chain (i.e., enforces at least one validator to validate chain `chainID`) +func (k Keeper) IsTopN(ctx sdk.Context, chainID string) bool { + topN, found := k.GetTopN(ctx, chainID) + return found && topN > 0 +} + +// IsOptIn returns true if chain with `chainID` is an Opt-In chain (i.e., no validator is forced to validate chain `chainID`) +func (k Keeper) IsOptIn(ctx sdk.Context, chainID string) bool { + topN, found := k.GetTopN(ctx, chainID) + return !found || topN == 0 +} + +func (k Keeper) SetOptedIn( + ctx sdk.Context, + chainID string, + providerConsAddress types.ProviderConsAddress, +) { + store := ctx.KVStore(k.storeKey) + store.Set(types.OptedInKey(chainID, providerConsAddress), []byte{}) +} + +func (k Keeper) DeleteOptedIn( + ctx sdk.Context, + chainID string, + providerAddr types.ProviderConsAddress, +) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.OptedInKey(chainID, providerAddr)) +} + +func (k Keeper) IsOptedIn( + ctx sdk.Context, + chainID string, + providerAddr types.ProviderConsAddress, +) bool { + store := ctx.KVStore(k.storeKey) + return store.Get(types.OptedInKey(chainID, providerAddr)) != nil +} + +// GetAllOptedIn returns all the opted-in validators on chain `chainID` +func (k Keeper) GetAllOptedIn( + ctx sdk.Context, + chainID string, +) (providerConsAddresses []types.ProviderConsAddress) { + store := ctx.KVStore(k.storeKey) + key := types.ChainIdWithLenKey(types.OptedInBytePrefix, chainID) + iterator := storetypes.KVStorePrefixIterator(store, key) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + providerConsAddresses = append(providerConsAddresses, types.NewProviderConsAddress(iterator.Key()[len(key):])) + } + + return providerConsAddresses +} + +// DeleteAllOptedIn deletes all the opted-in validators for chain with `chainID` +func (k Keeper) DeleteAllOptedIn( + ctx sdk.Context, + chainID string, +) { + store := ctx.KVStore(k.storeKey) + key := types.ChainIdWithLenKey(types.OptedInBytePrefix, chainID) + iterator := storetypes.KVStorePrefixIterator(store, key) + + var keysToDel [][]byte + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + keysToDel = append(keysToDel, iterator.Key()) + } + for _, delKey := range keysToDel { + store.Delete(delKey) + } +} + +// SetConsumerCommissionRate sets a per-consumer chain commission rate +// for the given validator address +func (k Keeper) SetConsumerCommissionRate( + ctx sdk.Context, + chainID string, + providerAddr types.ProviderConsAddress, + commissionRate math.LegacyDec, +) error { + store := ctx.KVStore(k.storeKey) + bz, err := commissionRate.Marshal() + if err != nil { + err = fmt.Errorf("consumer commission rate marshalling failed: %s", err) + k.Logger(ctx).Error(err.Error()) + return err + } + + store.Set(types.ConsumerCommissionRateKey(chainID, providerAddr), bz) + return nil +} + +// GetConsumerCommissionRate returns the per-consumer commission rate set +// for the given validator address +func (k Keeper) GetConsumerCommissionRate( + ctx sdk.Context, + chainID string, + providerAddr types.ProviderConsAddress, +) (math.LegacyDec, bool) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.ConsumerCommissionRateKey(chainID, providerAddr)) + if bz == nil { + return math.LegacyZeroDec(), false + } + + cr := math.LegacyZeroDec() + // handle error gracefully since it's called in BeginBlockRD + if err := cr.Unmarshal(bz); err != nil { + k.Logger(ctx).Error("consumer commission rate unmarshalling failed: %s", err) + return cr, false + } + + return cr, true +} + +// GetAllCommissionRateValidators returns all the validator address +// that set a commission rate for the given chain ID +func (k Keeper) GetAllCommissionRateValidators( + ctx sdk.Context, + chainID string, +) (addresses []types.ProviderConsAddress) { + store := ctx.KVStore(k.storeKey) + key := types.ChainIdWithLenKey(types.ConsumerCommissionRatePrefix, chainID) + iterator := storetypes.KVStorePrefixIterator(store, key) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + providerAddr := types.NewProviderConsAddress(iterator.Key()[len(key):]) + addresses = append(addresses, providerAddr) + } + + return addresses +} + +// DeleteConsumerCommissionRate the per-consumer chain commission rate +// associated to the given validator address +func (k Keeper) DeleteConsumerCommissionRate( + ctx sdk.Context, + chainID string, + providerAddr types.ProviderConsAddress, +) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.ConsumerCommissionRateKey(chainID, providerAddr)) +} + +// SetValidatorsPowerCap sets the power-cap value `p` associated to chain with `chainID` +func (k Keeper) SetValidatorsPowerCap( + ctx sdk.Context, + chainID string, + p uint32, +) { + store := ctx.KVStore(k.storeKey) + + buf := make([]byte, 4) + binary.BigEndian.PutUint32(buf, p) + + store.Set(types.ValidatorsPowerCapKey(chainID), buf) +} + +// DeleteValidatorsPowerCap removes the power-cap value associated to chain with `chainID` +func (k Keeper) DeleteValidatorsPowerCap( + ctx sdk.Context, + chainID string, +) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.ValidatorsPowerCapKey(chainID)) +} + +// GetValidatorsPowerCap returns `(p, true)` if chain `chainID` has power cap `p` associated with it, and (0, false) otherwise +func (k Keeper) GetValidatorsPowerCap( + ctx sdk.Context, + chainID string, +) (uint32, bool) { + store := ctx.KVStore(k.storeKey) + buf := store.Get(types.ValidatorsPowerCapKey(chainID)) + if buf == nil { + return 0, false + } + return binary.BigEndian.Uint32(buf), true +} + +// SetValidatorSetCap stores the validator-set cap value `c` associated to chain with `chainID` +func (k Keeper) SetValidatorSetCap( + ctx sdk.Context, + chainID string, + c uint32, +) { + store := ctx.KVStore(k.storeKey) + + buf := make([]byte, 4) + binary.BigEndian.PutUint32(buf, c) + + store.Set(types.ValidatorSetCapKey(chainID), buf) +} + +// DeleteValidatorSetCap removes the validator-set cap value associated to chain with `chainID` +func (k Keeper) DeleteValidatorSetCap( + ctx sdk.Context, + chainID string, +) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.ValidatorSetCapKey(chainID)) +} + +// GetValidatorSetCap returns `(c, true)` if chain `chainID` has validator-set cap `c` associated with it, and (0, false) otherwise +func (k Keeper) GetValidatorSetCap( + ctx sdk.Context, + chainID string, +) (uint32, bool) { + store := ctx.KVStore(k.storeKey) + buf := store.Get(types.ValidatorSetCapKey(chainID)) + if buf == nil { + return 0, false + } + return binary.BigEndian.Uint32(buf), true +} + +// SetAllowlist allowlists validator with `providerAddr` address on chain `chainID` +func (k Keeper) SetAllowlist( + ctx sdk.Context, + chainID string, + providerAddr types.ProviderConsAddress, +) { + store := ctx.KVStore(k.storeKey) + store.Set(types.AllowlistCapKey(chainID, providerAddr), []byte{}) +} + +// GetAllowList returns all allowlisted validators +func (k Keeper) GetAllowList( + ctx sdk.Context, + chainID string, +) (providerConsAddresses []types.ProviderConsAddress) { + store := ctx.KVStore(k.storeKey) + key := types.ChainIdWithLenKey(types.AllowlistPrefix, chainID) + iterator := storetypes.KVStorePrefixIterator(store, key) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + providerConsAddresses = append(providerConsAddresses, types.NewProviderConsAddress(iterator.Key()[len(key):])) + } + + return providerConsAddresses +} + +// IsAllowlisted returns `true` if validator with `providerAddr` has been allowlisted on chain `chainID` +func (k Keeper) IsAllowlisted( + ctx sdk.Context, + chainID string, + providerAddr types.ProviderConsAddress, +) bool { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.AllowlistCapKey(chainID, providerAddr)) + return bz != nil +} + +// DeleteAllowlist deletes all allowlisted validators +func (k Keeper) DeleteAllowlist(ctx sdk.Context, chainID string) { + store := ctx.KVStore(k.storeKey) + iterator := storetypes.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.AllowlistPrefix, chainID)) + defer iterator.Close() + + keysToDel := [][]byte{} + for ; iterator.Valid(); iterator.Next() { + keysToDel = append(keysToDel, iterator.Key()) + } + + for _, key := range keysToDel { + store.Delete(key) + } +} + +// IsAllowlistEmpty returns `true` if no validator is allowlisted on chain `chainID` +func (k Keeper) IsAllowlistEmpty(ctx sdk.Context, chainID string) bool { + store := ctx.KVStore(k.storeKey) + iterator := storetypes.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.AllowlistPrefix, chainID)) + defer iterator.Close() + + return !iterator.Valid() +} + +// SetDenylist denylists validator with `providerAddr` address on chain `chainID` +func (k Keeper) SetDenylist( + ctx sdk.Context, + chainID string, + providerAddr types.ProviderConsAddress, +) { + store := ctx.KVStore(k.storeKey) + store.Set(types.DenylistCapKey(chainID, providerAddr), []byte{}) +} + +// GetDenyList returns all denylisted validators +func (k Keeper) GetDenyList( + ctx sdk.Context, + chainID string, +) (providerConsAddresses []types.ProviderConsAddress) { + store := ctx.KVStore(k.storeKey) + key := types.ChainIdWithLenKey(types.DenylistPrefix, chainID) + iterator := storetypes.KVStorePrefixIterator(store, key) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + providerConsAddresses = append(providerConsAddresses, types.NewProviderConsAddress(iterator.Key()[len(key):])) + } + + return providerConsAddresses +} + +// IsDenylisted returns `true` if validator with `providerAddr` has been denylisted on chain `chainID` +func (k Keeper) IsDenylisted( + ctx sdk.Context, + chainID string, + providerAddr types.ProviderConsAddress, +) bool { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.DenylistCapKey(chainID, providerAddr)) + return bz != nil +} + +// DeleteDenylist deletes all denylisted validators +func (k Keeper) DeleteDenylist(ctx sdk.Context, chainID string) { + store := ctx.KVStore(k.storeKey) + iterator := storetypes.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.DenylistPrefix, chainID)) + defer iterator.Close() + + keysToDel := [][]byte{} + for ; iterator.Valid(); iterator.Next() { + keysToDel = append(keysToDel, iterator.Key()) + } + + for _, key := range keysToDel { + store.Delete(key) + } +} + +// IsDenylistEmpty returns `true` if no validator is denylisted on chain `chainID` +func (k Keeper) IsDenylistEmpty(ctx sdk.Context, chainID string) bool { + store := ctx.KVStore(k.storeKey) + iterator := storetypes.KVStorePrefixIterator(store, types.ChainIdWithLenKey(types.DenylistPrefix, chainID)) + defer iterator.Close() + + return !iterator.Valid() +} + +// SetMinimumPowerInTopN sets the minimum power required for a validator to be in the top N +// for a given consumer chain. +func (k Keeper) SetMinimumPowerInTopN( + ctx sdk.Context, + chainID string, + power int64, +) { + store := ctx.KVStore(k.storeKey) + + buf := make([]byte, 8) + binary.BigEndian.PutUint64(buf, uint64(power)) + + store.Set(types.MinimumPowerInTopNKey(chainID), buf) +} + +// GetMinimumPowerInTopN returns the minimum power required for a validator to be in the top N +// for a given consumer chain. +func (k Keeper) GetMinimumPowerInTopN( + ctx sdk.Context, + chainID string, +) (int64, bool) { + store := ctx.KVStore(k.storeKey) + buf := store.Get(types.MinimumPowerInTopNKey(chainID)) + if buf == nil { + return 0, false + } + return int64(binary.BigEndian.Uint64(buf)), true +} + +// DeleteMinimumPowerInTopN removes the minimum power required for a validator to be in the top N +// for a given consumer chain. +func (k Keeper) DeleteMinimumPowerInTopN( + ctx sdk.Context, + chainID string, +) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.MinimumPowerInTopNKey(chainID)) +} diff --git a/x/ccv/provider/keeper/keeper_test.go b/x/ccv/provider/keeper/keeper_test.go index 6e117551b7..e61a93cda1 100644 --- a/x/ccv/provider/keeper/keeper_test.go +++ b/x/ccv/provider/keeper/keeper_test.go @@ -1,11 +1,13 @@ package keeper_test import ( + "bytes" "fmt" "sort" "testing" "time" + "cosmossdk.io/math" ibctesting "github.com/cosmos/ibc-go/v8/testing" "github.com/stretchr/testify/require" @@ -391,26 +393,22 @@ func TestVscSendTimestamp(t *testing.T) { require.Empty(t, providerKeeper.GetAllVscSendTimestamps(ctx, chainID)) } -// TestGetAllConsumerChains tests GetAllConsumerChains behaviour correctness -func TestGetAllConsumerChains(t *testing.T) { +func TestGetAllRegisteredConsumerChainIDs(t *testing.T) { pk, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() chainIDs := []string{"chain-2", "chain-1", "chain-4", "chain-3"} - expectedGetAllOrder := []types.Chain{} + // GetAllRegisteredConsumerChainIDs iterates over chainID in lexicographical order + expectedChainIDs := []string{"chain-1", "chain-2", "chain-3", "chain-4"} + for i, chainID := range chainIDs { clientID := fmt.Sprintf("client-%d", len(chainIDs)-i) pk.SetConsumerClientId(ctx, chainID, clientID) - expectedGetAllOrder = append(expectedGetAllOrder, types.Chain{ChainId: chainID, ClientId: clientID}) } - // sorting by chainID - sort.Slice(expectedGetAllOrder, func(i, j int) bool { - return expectedGetAllOrder[i].ChainId < expectedGetAllOrder[j].ChainId - }) - result := pk.GetAllConsumerChains(ctx) + result := pk.GetAllRegisteredConsumerChainIDs(ctx) require.Len(t, result, len(chainIDs)) - require.Equal(t, expectedGetAllOrder, result) + require.Equal(t, expectedChainIDs, result) } // TestGetAllChannelToChains tests GetAllChannelToChains behaviour correctness @@ -550,7 +548,7 @@ func TestSetProposedConsumerChains(t *testing.T) { for _, test := range tests { providerKeeper.SetProposedConsumerChain(ctx, test.chainID, test.proposalID) - cID := providerKeeper.GetProposedConsumerChain(ctx, test.proposalID) + cID, _ := providerKeeper.GetProposedConsumerChain(ctx, test.proposalID) require.Equal(t, cID, test.chainID) } } @@ -572,9 +570,9 @@ func TestDeleteProposedConsumerChainInStore(t *testing.T) { for _, test := range tests { providerKeeper.SetProposedConsumerChain(ctx, test.chainID, test.proposalID) providerKeeper.DeleteProposedConsumerChainInStore(ctx, test.deleteProposalID) - cID := providerKeeper.GetProposedConsumerChain(ctx, test.proposalID) + cID, found := providerKeeper.GetProposedConsumerChain(ctx, test.proposalID) if test.ok { - require.Equal(t, cID, "") + require.False(t, found) } else { require.Equal(t, cID, test.chainID) } @@ -628,3 +626,238 @@ func TestGetAllProposedConsumerChainIDs(t *testing.T) { } } } + +// TestTopN tests the `SetTopN`, `GetTopN`, `IsTopN`, and `IsOptIn` methods +func TestTopN(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + tests := []struct { + chainID string + N uint32 + isOptIn bool + }{ + {chainID: "TopNChain1", N: 50, isOptIn: false}, + {chainID: "TopNChain2", N: 100, isOptIn: false}, + {chainID: "OptInChain", N: 0, isOptIn: true}, + } + + for _, test := range tests { + providerKeeper.SetTopN(ctx, test.chainID, test.N) + topN, found := providerKeeper.GetTopN(ctx, test.chainID) + require.Equal(t, test.N, topN) + require.True(t, found) + + if test.isOptIn { + require.True(t, providerKeeper.IsOptIn(ctx, test.chainID)) + require.False(t, providerKeeper.IsTopN(ctx, test.chainID)) + } else { + require.False(t, providerKeeper.IsOptIn(ctx, test.chainID)) + require.True(t, providerKeeper.IsTopN(ctx, test.chainID)) + } + } +} + +func TestGetAllOptedIn(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + expectedOptedInValidators := []types.ProviderConsAddress{ + types.NewProviderConsAddress([]byte("providerAddr1")), + types.NewProviderConsAddress([]byte("providerAddr2")), + types.NewProviderConsAddress([]byte("providerAddr3")), + } + + for _, expectedOptedInValidator := range expectedOptedInValidators { + providerKeeper.SetOptedIn(ctx, "chainID", expectedOptedInValidator) + } + + actualOptedInValidators := providerKeeper.GetAllOptedIn(ctx, "chainID") + + // sort validators first to be able to compare + sortOptedInValidators := func(addresses []types.ProviderConsAddress) { + sort.Slice(addresses, func(i, j int) bool { + return bytes.Compare(addresses[i].ToSdkConsAddr(), addresses[j].ToSdkConsAddr()) < 0 + }) + } + sortOptedInValidators(expectedOptedInValidators) + sortOptedInValidators(actualOptedInValidators) + require.Equal(t, expectedOptedInValidators, actualOptedInValidators) +} + +// TestOptedIn tests the `SetOptedIn`, `IsOptedIn`, `DeleteOptedIn` and `DeleteAllOptedIn` methods +func TestOptedIn(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + optedInValidator1 := types.NewProviderConsAddress([]byte("providerAddr1")) + optedInValidator2 := types.NewProviderConsAddress([]byte("providerAddr2")) + + require.False(t, providerKeeper.IsOptedIn(ctx, "chainID", optedInValidator1)) + providerKeeper.SetOptedIn(ctx, "chainID", optedInValidator1) + require.True(t, providerKeeper.IsOptedIn(ctx, "chainID", optedInValidator1)) + providerKeeper.DeleteOptedIn(ctx, "chainID", optedInValidator1) + require.False(t, providerKeeper.IsOptedIn(ctx, "chainID", optedInValidator1)) + + providerKeeper.SetOptedIn(ctx, "chainID", optedInValidator1) + providerKeeper.SetOptedIn(ctx, "chainID", optedInValidator2) + require.True(t, providerKeeper.IsOptedIn(ctx, "chainID", optedInValidator1)) + require.True(t, providerKeeper.IsOptedIn(ctx, "chainID", optedInValidator2)) + providerKeeper.DeleteAllOptedIn(ctx, "chainID") + require.False(t, providerKeeper.IsOptedIn(ctx, "chainID", optedInValidator1)) + require.False(t, providerKeeper.IsOptedIn(ctx, "chainID", optedInValidator2)) +} + +// TestConsumerCommissionRate tests the `SetConsumerCommissionRate`, `GetConsumerCommissionRate`, and `DeleteConsumerCommissionRate` methods +func TestConsumerCommissionRate(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerAddr1 := types.NewProviderConsAddress([]byte("providerAddr1")) + providerAddr2 := types.NewProviderConsAddress([]byte("providerAddr2")) + + cr, found := providerKeeper.GetConsumerCommissionRate(ctx, "chainID", providerAddr1) + require.False(t, found) + require.Equal(t, math.LegacyZeroDec(), cr) + + providerKeeper.SetConsumerCommissionRate(ctx, "chainID", providerAddr1, math.LegacyOneDec()) + cr, found = providerKeeper.GetConsumerCommissionRate(ctx, "chainID", providerAddr1) + require.True(t, found) + require.Equal(t, math.LegacyOneDec(), cr) + + providerKeeper.SetConsumerCommissionRate(ctx, "chainID", providerAddr2, math.LegacyZeroDec()) + cr, found = providerKeeper.GetConsumerCommissionRate(ctx, "chainID", providerAddr2) + require.True(t, found) + require.Equal(t, math.LegacyZeroDec(), cr) + + provAddrs := providerKeeper.GetAllCommissionRateValidators(ctx, "chainID") + require.Len(t, provAddrs, 2) + + for _, addr := range provAddrs { + providerKeeper.DeleteConsumerCommissionRate(ctx, "chainID", addr) + } + + _, found = providerKeeper.GetConsumerCommissionRate(ctx, "chainID", providerAddr1) + require.False(t, found) + + _, found = providerKeeper.GetConsumerCommissionRate(ctx, "chainID", providerAddr2) + require.False(t, found) +} + +// TestValidatorsPowerCap tests the `SetValidatorsPowerCap`, `GetValidatorsPowerCap`, and `DeleteValidatorsPowerCap` methods +func TestValidatorsPowerCap(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + expectedPowerCap := uint32(10) + providerKeeper.SetValidatorsPowerCap(ctx, "chainID", expectedPowerCap) + powerCap, found := providerKeeper.GetValidatorsPowerCap(ctx, "chainID") + require.Equal(t, expectedPowerCap, powerCap) + require.True(t, found) + + providerKeeper.DeleteValidatorsPowerCap(ctx, "chainID") + _, found = providerKeeper.GetValidatorsPowerCap(ctx, "chainID") + require.False(t, found) +} + +// TestValidatorSetCap tests the `SetValidatorSetCap`, `GetValidatorSetCap`, and `DeleteValidatorSetCap` methods +func TestValidatorSetCap(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + expectedPowerCap := uint32(10) + providerKeeper.SetValidatorSetCap(ctx, "chainID", expectedPowerCap) + powerCap, found := providerKeeper.GetValidatorSetCap(ctx, "chainID") + require.Equal(t, expectedPowerCap, powerCap) + require.True(t, found) + + providerKeeper.DeleteValidatorSetCap(ctx, "chainID") + _, found = providerKeeper.GetValidatorSetCap(ctx, "chainID") + require.False(t, found) +} + +// TestAllowlist tests the `SetAllowlist`, `IsAllowlisted`, `DeleteAllowlist`, and `IsAllowlistEmpty` methods +func TestAllowlist(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + chainID := "chainID" + + // no validator was allowlisted and hence the allowlist is empty + require.True(t, providerKeeper.IsAllowlistEmpty(ctx, chainID)) + + providerAddr1 := types.NewProviderConsAddress([]byte("providerAddr1")) + providerKeeper.SetAllowlist(ctx, chainID, providerAddr1) + require.True(t, providerKeeper.IsAllowlisted(ctx, chainID, providerAddr1)) + + // allowlist is not empty anymore + require.False(t, providerKeeper.IsAllowlistEmpty(ctx, chainID)) + + providerAddr2 := types.NewProviderConsAddress([]byte("providerAddr2")) + providerKeeper.SetAllowlist(ctx, chainID, providerAddr2) + require.True(t, providerKeeper.IsAllowlisted(ctx, chainID, providerAddr2)) + require.False(t, providerKeeper.IsAllowlistEmpty(ctx, chainID)) + + providerKeeper.DeleteAllowlist(ctx, chainID) + require.False(t, providerKeeper.IsAllowlisted(ctx, chainID, providerAddr1)) + require.False(t, providerKeeper.IsAllowlisted(ctx, chainID, providerAddr2)) + require.True(t, providerKeeper.IsAllowlistEmpty(ctx, chainID)) +} + +// TestDenylist tests the `SetDenylist`, `IsDenylisted`, `DeleteDenylist`, and `IsDenylistEmpty` methods +func TestDenylist(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + chainID := "chainID" + + // no validator was denylisted and hence the denylist is empty + require.True(t, providerKeeper.IsDenylistEmpty(ctx, chainID)) + + providerAddr1 := types.NewProviderConsAddress([]byte("providerAddr1")) + providerKeeper.SetDenylist(ctx, chainID, providerAddr1) + require.True(t, providerKeeper.IsDenylisted(ctx, chainID, providerAddr1)) + + // denylist is not empty anymore + require.False(t, providerKeeper.IsDenylistEmpty(ctx, chainID)) + + providerAddr2 := types.NewProviderConsAddress([]byte("providerAddr2")) + providerKeeper.SetDenylist(ctx, chainID, providerAddr2) + require.True(t, providerKeeper.IsDenylisted(ctx, chainID, providerAddr2)) + require.False(t, providerKeeper.IsDenylistEmpty(ctx, chainID)) + + providerKeeper.DeleteDenylist(ctx, chainID) + require.False(t, providerKeeper.IsDenylisted(ctx, chainID, providerAddr1)) + require.False(t, providerKeeper.IsDenylisted(ctx, chainID, providerAddr2)) + require.True(t, providerKeeper.IsDenylistEmpty(ctx, chainID)) +} + +func TestMinimumPowerInTopN(t *testing.T) { + k, ctx, _, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + + chainID := "testChain" + minPower := int64(1000) + + // Set the minimum power in top N + k.SetMinimumPowerInTopN(ctx, chainID, minPower) + + // Retrieve the minimum power in top N + actualMinPower, found := k.GetMinimumPowerInTopN(ctx, chainID) + require.True(t, found) + require.Equal(t, minPower, actualMinPower) + + // Update the minimum power + newMinPower := int64(2000) + k.SetMinimumPowerInTopN(ctx, chainID, newMinPower) + + // Retrieve the updated minimum power in top N + newActualMinPower, found := k.GetMinimumPowerInTopN(ctx, chainID) + require.True(t, found) + require.Equal(t, newMinPower, newActualMinPower) + + // Test when the chain ID does not exist + nonExistentChainID := "nonExistentChain" + nonExistentMinPower, found := k.GetMinimumPowerInTopN(ctx, nonExistentChainID) + require.False(t, found) + require.Equal(t, int64(0), nonExistentMinPower) +} diff --git a/x/ccv/provider/keeper/key_assignment.go b/x/ccv/provider/keeper/key_assignment.go index f68211861b..b7d1f2de0b 100644 --- a/x/ccv/provider/keeper/key_assignment.go +++ b/x/ccv/provider/keeper/key_assignment.go @@ -1,6 +1,7 @@ package keeper import ( + "encoding/base64" "fmt" errorsmod "cosmossdk.io/errors" @@ -15,6 +16,53 @@ import ( ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) +// ParseConsumerKey parses the ED25519 PubKey`consumerKey` from a JSON string +// and constructs its corresponding `tmprotocrypto.PublicKey` +func (k Keeper) ParseConsumerKey(consumerKey string) (tmprotocrypto.PublicKey, error) { + // parse consumer key as long as it's in the right format + pkType, keyStr, err := types.ParseConsumerKeyFromJson(consumerKey) + if err != nil { + return tmprotocrypto.PublicKey{}, err + } + + // Note: the correct way to decide if a key type is supported is to check the + // consensus params. However this functionality was disabled in https://github.com/cosmos/interchain-security/pull/916 + // as a quick way to get ed25519 working, avoiding amino/proto-any marshalling issues. + + // make sure the consumer key type is supported + // cp := ctx.ConsensusParams() + // if cp != nil && cp.Validator != nil { + // if !tmstrings.StringInSlice(pkType, cp.Validator.PubKeyTypes) { + // return nil, errorsmod.Wrapf( + // stakingtypes.ErrValidatorPubKeyTypeNotSupported, + // "got: %s, expected one of: %s", pkType, cp.Validator.PubKeyTypes, + // ) + // } + // } + + // For now, only accept ed25519. + // TODO: decide what types should be supported. + if pkType != "/cosmos.crypto.ed25519.PubKey" { + return tmprotocrypto.PublicKey{}, errorsmod.Wrapf( + stakingtypes.ErrValidatorPubKeyTypeNotSupported, + "got: %s, expected: %s", pkType, "/cosmos.crypto.ed25519.PubKey", + ) + } + + pubKeyBytes, err := base64.StdEncoding.DecodeString(keyStr) + if err != nil { + return tmprotocrypto.PublicKey{}, err + } + + consumerTMPublicKey := tmprotocrypto.PublicKey{ + Sum: &tmprotocrypto.PublicKey_Ed25519{ + Ed25519: pubKeyBytes, + }, + } + + return consumerTMPublicKey, nil +} + // GetValidatorConsumerPubKey returns a validator's public key assigned for a consumer chain func (k Keeper) GetValidatorConsumerPubKey( ctx sdk.Context, @@ -324,12 +372,24 @@ func (k Keeper) AssignConsumerKey( } } - if _, found := k.GetValidatorByConsumerAddr(ctx, chainID, consumerAddr); found { + if existingProviderAddr, found := k.GetValidatorByConsumerAddr(ctx, chainID, consumerAddr); found { // consumer key is already in use - // prevent multiple validators from assigning the same key - return errorsmod.Wrapf( - types.ErrConsumerKeyInUse, "a validator has assigned the consumer key already", - ) + if providerAddr.Address.Equals(existingProviderAddr.Address) { + // the validator itself is the one already using the consumer key, + // just do a noop + k.Logger(ctx).Info("tried to assign a consumer key that is already assigned to the validator", + "consumer chainID", chainID, + "validator", providerAddr.String(), + "consumer consensus addr", consumerAddr.String(), + ) + return nil + } else { + // the validators are different -> throw an error to + // prevent multiple validators from assigning the same key + return errorsmod.Wrapf( + types.ErrConsumerKeyInUse, "a validator has assigned the consumer key already", + ) + } } // get the previous key assigned for this validator on this consumer chain diff --git a/x/ccv/provider/keeper/key_assignment_test.go b/x/ccv/provider/keeper/key_assignment_test.go index dc0faf52d4..2f67890b00 100644 --- a/x/ccv/provider/keeper/key_assignment_test.go +++ b/x/ccv/provider/keeper/key_assignment_test.go @@ -641,6 +641,7 @@ type Assignment struct { // of simulated scenarios where random key assignments and validator // set updates are generated. func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { + CHAINID := ChainID // The number of full test executions to run NUM_EXECUTIONS := 100 // Each test execution mimics the adding of a consumer chain and the @@ -768,9 +769,12 @@ func TestSimulatedAssignmentsAndUpdateApplication(t *testing.T) { }) } - nextValidators := k.ComputeNextEpochConsumerValSet(ctx, ChainID, bondedValidators) - updates = providerkeeper.DiffValidators(k.GetConsumerValSet(ctx, ChainID), nextValidators) - k.SetConsumerValSet(ctx, ChainID, nextValidators) + nextValidators := k.FilterValidators(ctx, CHAINID, bondedValidators, + func(providerAddr types.ProviderConsAddress) bool { + return true + }) + updates = providerkeeper.DiffValidators(k.GetConsumerValSet(ctx, CHAINID), nextValidators) + k.SetConsumerValSet(ctx, CHAINID, nextValidators) consumerValset.apply(updates) // Simulate the VSCID update in EndBlock diff --git a/x/ccv/provider/keeper/legacy_proposal.go b/x/ccv/provider/keeper/legacy_proposal.go index a5391ceff3..19ad553038 100644 --- a/x/ccv/provider/keeper/legacy_proposal.go +++ b/x/ccv/provider/keeper/legacy_proposal.go @@ -1,6 +1,7 @@ package keeper import ( + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" @@ -81,3 +82,61 @@ func (k Keeper) HandleLegacyConsumerRemovalProposal(ctx sdk.Context, p *types.Co return nil } + +// HandleConsumerModificationProposal modifies a running consumer chain +func (k Keeper) HandleLegacyConsumerModificationProposal(ctx sdk.Context, p *types.ConsumerModificationProposal) error { + if _, found := k.GetConsumerClientId(ctx, p.ChainId); !found { + return errorsmod.Wrapf(types.ErrInvalidConsumerChainID, "consumer %s chain is not running", p.ChainId) + } + + k.SetTopN(ctx, p.ChainId, p.Top_N) + k.SetValidatorsPowerCap(ctx, p.ChainId, p.ValidatorsPowerCap) + k.SetValidatorSetCap(ctx, p.ChainId, p.ValidatorSetCap) + + k.DeleteAllowlist(ctx, p.ChainId) + for _, address := range p.Allowlist { + consAddr, err := sdk.ConsAddressFromBech32(address) + if err != nil { + continue + } + + k.SetAllowlist(ctx, p.ChainId, types.NewProviderConsAddress(consAddr)) + } + + k.DeleteDenylist(ctx, p.ChainId) + for _, address := range p.Denylist { + consAddr, err := sdk.ConsAddressFromBech32(address) + if err != nil { + continue + } + + k.SetDenylist(ctx, p.ChainId, types.NewProviderConsAddress(consAddr)) + } + + oldTopN, found := k.GetTopN(ctx, p.ChainId) + if !found { + oldTopN = 0 + k.Logger(ctx).Info("consumer chain top N not found, treating as 0", "chainID", p.ChainId) + } + + // if the top N changes, we need to update the new minimum power in top N + if p.Top_N != oldTopN { + if p.Top_N > 0 { + // if the chain receives a non-zero top N value, store the minimum power in the top N + bondedValidators, err := k.GetLastBondedValidators(ctx) + if err != nil { + return err + } + minPower, err := k.ComputeMinPowerInTopN(ctx, bondedValidators, p.Top_N) + if err != nil { + return err + } + k.SetMinimumPowerInTopN(ctx, p.ChainId, minPower) + } else { + // if the chain receives a zero top N value, we delete the min power + k.DeleteMinimumPowerInTopN(ctx, p.ChainId) + } + } + + return nil +} diff --git a/x/ccv/provider/keeper/legacy_proposal_test.go b/x/ccv/provider/keeper/legacy_proposal_test.go index bc7abbc0c6..06533a2503 100644 --- a/x/ccv/provider/keeper/legacy_proposal_test.go +++ b/x/ccv/provider/keeper/legacy_proposal_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" @@ -56,6 +57,11 @@ func TestHandleLegacyConsumerAdditionProposal(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, + 0, + 0, + nil, + nil, ).(*providertypes.ConsumerAdditionProposal), blockTime: now, expAppendProp: true, @@ -81,6 +87,11 @@ func TestHandleLegacyConsumerAdditionProposal(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, + 0, + 0, + nil, + nil, ).(*providertypes.ConsumerAdditionProposal), blockTime: now, expAppendProp: false, @@ -96,6 +107,7 @@ func TestHandleLegacyConsumerAdditionProposal(t *testing.T) { if tc.expAppendProp { // Mock calls are only asserted if we expect a client to be created. + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 1, []stakingtypes.Validator{}, []int64{}, 1) gomock.InOrder( testkeeper.GetMocksForCreateConsumerClient(ctx, &mocks, tc.prop.ChainId, clienttypes.NewHeight(2, 3))..., ) @@ -223,8 +235,7 @@ func TestHandleLegacyConsumerRemovalProposal(t *testing.T) { // meaning no external keeper methods are allowed to be called. if tc.expAppendProp { testkeeper.SetupForStoppingConsumerChain(t, ctx, &providerKeeper, mocks) - - // assert mocks for expected calls to `StopConsumerChain` when closing the underlying channel + // Valid client creation is asserted with mock expectations here gomock.InOrder(testkeeper.GetMocksForStopConsumerChainWithCloseChannel(ctx, &mocks)...) } @@ -254,3 +265,54 @@ func TestHandleLegacyConsumerRemovalProposal(t *testing.T) { ctrl.Finish() } } + +func TestHandleConsumerModificationProposal(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + chainID := "chainID" + + // set up a consumer client, so it seems that "chainID" is running + providerKeeper.SetConsumerClientId(ctx, "chainID", "clientID") + + // set PSS-related fields to update them later on + providerKeeper.SetTopN(ctx, chainID, 50) + providerKeeper.SetValidatorSetCap(ctx, chainID, 10) + providerKeeper.SetValidatorsPowerCap(ctx, chainID, 34) + providerKeeper.SetAllowlist(ctx, chainID, providertypes.NewProviderConsAddress([]byte("allowlistedAddr1"))) + providerKeeper.SetAllowlist(ctx, chainID, providertypes.NewProviderConsAddress([]byte("allowlistedAddr2"))) + providerKeeper.SetDenylist(ctx, chainID, providertypes.NewProviderConsAddress([]byte("denylistedAddr1"))) + + expectedTopN := uint32(75) + expectedValidatorsPowerCap := uint32(67) + expectedValidatorSetCap := uint32(20) + expectedAllowlistedValidator := "cosmosvalcons1wpex7anfv3jhystyv3eq20r35a" + expectedDenylistedValidator := "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39" + proposal := providertypes.NewConsumerModificationProposal("title", "description", chainID, + expectedTopN, + expectedValidatorsPowerCap, + expectedValidatorSetCap, + []string{expectedAllowlistedValidator}, + []string{expectedDenylistedValidator}, + ).(*providertypes.ConsumerModificationProposal) + + err := providerKeeper.HandleLegacyConsumerModificationProposal(ctx, proposal) + require.NoError(t, err) + + actualTopN, _ := providerKeeper.GetTopN(ctx, chainID) + require.Equal(t, expectedTopN, actualTopN) + actualValidatorsPowerCap, _ := providerKeeper.GetValidatorsPowerCap(ctx, chainID) + require.Equal(t, expectedValidatorsPowerCap, actualValidatorsPowerCap) + actualValidatorSetCap, _ := providerKeeper.GetValidatorSetCap(ctx, chainID) + require.Equal(t, expectedValidatorSetCap, actualValidatorSetCap) + + allowlistedValidator, err := sdk.ConsAddressFromBech32(expectedAllowlistedValidator) + require.NoError(t, err) + require.Equal(t, 1, len(providerKeeper.GetAllowList(ctx, chainID))) + require.Equal(t, providertypes.NewProviderConsAddress(allowlistedValidator), providerKeeper.GetAllowList(ctx, chainID)[0]) + + denylistedValidator, err := sdk.ConsAddressFromBech32(expectedDenylistedValidator) + require.NoError(t, err) + require.Equal(t, 1, len(providerKeeper.GetDenyList(ctx, chainID))) + require.Equal(t, providertypes.NewProviderConsAddress(denylistedValidator), providerKeeper.GetDenyList(ctx, chainID)[0]) +} diff --git a/x/ccv/provider/keeper/msg_server.go b/x/ccv/provider/keeper/msg_server.go index 0a5ba95368..4239a7cf41 100644 --- a/x/ccv/provider/keeper/msg_server.go +++ b/x/ccv/provider/keeper/msg_server.go @@ -2,7 +2,6 @@ package keeper import ( "context" - "encoding/base64" errorsmod "cosmossdk.io/errors" @@ -11,7 +10,6 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" tmtypes "github.com/cometbft/cometbft/types" "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" @@ -60,47 +58,11 @@ func (k msgServer) AssignConsumerKey(goCtx context.Context, msg *types.MsgAssign return nil, err } - // parse consumer key as long as it's in the right format - pkType, keyStr, err := types.ParseConsumerKeyFromJson(msg.ConsumerKey) + consumerTMPublicKey, err := k.ParseConsumerKey(msg.ConsumerKey) if err != nil { return nil, err } - // Note: the correct way to decide if a key type is supported is to check the - // consensus params. However this functionality was disabled in https://github.com/cosmos/interchain-security/pull/916 - // as a quick way to get ed25519 working, avoiding amino/proto-any marshalling issues. - - // make sure the consumer key type is supported - // cp := ctx.ConsensusParams() - // if cp != nil && cp.Validator != nil { - // if !tmstrings.StringInSlice(pkType, cp.Validator.PubKeyTypes) { - // return nil, errorsmod.Wrapf( - // stakingtypes.ErrValidatorPubKeyTypeNotSupported, - // "got: %s, expected one of: %s", pkType, cp.Validator.PubKeyTypes, - // ) - // } - // } - - // For now, only accept ed25519. - // TODO: decide what types should be supported. - if pkType != "/cosmos.crypto.ed25519.PubKey" { - return nil, errorsmod.Wrapf( - stakingtypes.ErrValidatorPubKeyTypeNotSupported, - "got: %s, expected: %s", pkType, "/cosmos.crypto.ed25519.PubKey", - ) - } - - pubKeyBytes, err := base64.StdEncoding.DecodeString(keyStr) - if err != nil { - return nil, err - } - - consumerTMPublicKey := tmprotocrypto.PublicKey{ - Sum: &tmprotocrypto.PublicKey_Ed25519{ - Ed25519: pubKeyBytes, - }, - } - if err := k.Keeper.AssignConsumerKey(ctx, msg.ChainId, validator, consumerTMPublicKey); err != nil { return nil, err } @@ -235,3 +197,123 @@ func (k msgServer) SubmitConsumerDoubleVoting(goCtx context.Context, msg *types. return &types.MsgSubmitConsumerDoubleVotingResponse{}, nil } + +func (k msgServer) OptIn(goCtx context.Context, msg *types.MsgOptIn) (*types.MsgOptInResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + valAddress, err := sdk.ValAddressFromBech32(msg.ProviderAddr) + if err != nil { + return nil, err + } + + // validator must already be registered + validator, err := k.stakingKeeper.GetValidator(ctx, valAddress) + if err != nil { + return nil, err + } + + consAddrTmp, err := validator.GetConsAddr() + if err != nil { + return nil, err + } + providerConsAddr := types.NewProviderConsAddress(consAddrTmp) + + err = k.Keeper.HandleOptIn(ctx, msg.ChainId, providerConsAddr, msg.ConsumerKey) + if err != nil { + return nil, err + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeOptIn, + sdk.NewAttribute(types.AttributeProviderValidatorAddress, msg.ProviderAddr), + sdk.NewAttribute(types.AttributeConsumerConsensusPubKey, msg.ConsumerKey), + ), + }) + + return &types.MsgOptInResponse{}, nil +} + +func (k msgServer) OptOut(goCtx context.Context, msg *types.MsgOptOut) (*types.MsgOptOutResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + valAddress, err := sdk.ValAddressFromBech32(msg.ProviderAddr) + if err != nil { + return nil, err + } + + // validator must already be registered + validator, err := k.stakingKeeper.GetValidator(ctx, valAddress) + if err != nil { + return nil, err + } + + consAddrTmp, err := validator.GetConsAddr() + if err != nil { + return nil, err + } + providerConsAddr := types.NewProviderConsAddress(consAddrTmp) + + err = k.Keeper.HandleOptOut(ctx, msg.ChainId, providerConsAddr) + if err != nil { + return nil, err + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeOptOut, + sdk.NewAttribute(types.AttributeProviderValidatorAddress, msg.ProviderAddr), + ), + }) + + return &types.MsgOptOutResponse{}, nil +} + +func (k msgServer) SetConsumerCommissionRate(goCtx context.Context, msg *types.MsgSetConsumerCommissionRate) (*types.MsgSetConsumerCommissionRateResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + providerValidatorAddr, err := sdk.ValAddressFromBech32(msg.ProviderAddr) + if err != nil { + return nil, err + } + + // validator must already be registered + validator, err := k.stakingKeeper.GetValidator(ctx, providerValidatorAddr) + if err != nil { + return nil, stakingtypes.ErrNoValidatorFound + } + + consAddr, err := validator.GetConsAddr() + if err != nil { + return nil, err + } + + if err := k.HandleSetConsumerCommissionRate(ctx, msg.ChainId, types.NewProviderConsAddress(consAddr), msg.Rate); err != nil { + return nil, err + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeSetConsumerCommissionRate, + sdk.NewAttribute(types.AttributeConsumerChainID, msg.ChainId), + sdk.NewAttribute(types.AttributeProviderValidatorAddress, msg.ProviderAddr), + sdk.NewAttribute(types.AttributeConsumerCommissionRate, msg.Rate.String()), + ), + }) + + return &types.MsgSetConsumerCommissionRateResponse{}, nil +} + +func (k msgServer) ConsumerModification(goCtx context.Context, msg *types.MsgConsumerModification) (*types.MsgConsumerModificationResponse, error) { + if k.GetAuthority() != msg.Authority { + return nil, errorsmod.Wrapf(types.ErrUnauthorized, "expected %s, got %s", k.GetAuthority(), msg.Authority) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + err := k.Keeper.HandleConsumerModificationProposal(ctx, msg) + if err != nil { + return nil, errorsmod.Wrapf(err, "failed handling ConsumerModification proposal") + } + + return &types.MsgConsumerModificationResponse{}, nil +} diff --git a/x/ccv/provider/keeper/params.go b/x/ccv/provider/keeper/params.go index 9c1d276d4f..da3dda92b7 100644 --- a/x/ccv/provider/keeper/params.go +++ b/x/ccv/provider/keeper/params.go @@ -78,6 +78,13 @@ func (k Keeper) GetBlocksPerEpoch(ctx sdk.Context) int64 { return params.BlocksPerEpoch } +// GetNumberOfEpochsToStartReceivingRewards returns the number of epochs needed by a validator to continuously validate +// to start receiving rewards +func (k Keeper) GetNumberOfEpochsToStartReceivingRewards(ctx sdk.Context) int64 { + params := k.GetParams(ctx) + return params.NumberOfEpochsToStartReceivingRewards +} + // GetParams returns the paramset for the provider module func (k Keeper) GetParams(ctx sdk.Context) types.Params { store := ctx.KVStore(k.storeKey) diff --git a/x/ccv/provider/keeper/params_test.go b/x/ccv/provider/keeper/params_test.go index 6450102c2a..cb1dc3cfe0 100644 --- a/x/ccv/provider/keeper/params_test.go +++ b/x/ccv/provider/keeper/params_test.go @@ -50,6 +50,7 @@ func TestParams(t *testing.T) { Amount: math.NewInt(10000000), }, 600, + 24, ) providerKeeper.SetParams(ctx, newParams) params = providerKeeper.GetParams(ctx) diff --git a/x/ccv/provider/keeper/partial_set_security.go b/x/ccv/provider/keeper/partial_set_security.go new file mode 100644 index 0000000000..069eb219dc --- /dev/null +++ b/x/ccv/provider/keeper/partial_set_security.go @@ -0,0 +1,320 @@ +package keeper + +import ( + "fmt" + "sort" + + errorsmod "cosmossdk.io/errors" + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" +) + +// HandleOptIn prepares validator `providerAddr` to opt in to `chainID` with an optional `consumerKey` consumer public key. +// Note that the validator only opts in at the end of an epoch. +func (k Keeper) HandleOptIn(ctx sdk.Context, chainID string, providerAddr types.ProviderConsAddress, consumerKey string) error { + if !k.IsConsumerProposedOrRegistered(ctx, chainID) { + return errorsmod.Wrapf( + types.ErrUnknownConsumerChainId, + "opting in to an unknown consumer chain, with id: %s", chainID) + } + + k.SetOptedIn(ctx, chainID, providerAddr) + + if consumerKey != "" { + consumerTMPublicKey, err := k.ParseConsumerKey(consumerKey) + if err != nil { + return err + } + + validator, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, providerAddr.Address) + if err != nil { + return err + } + + err = k.AssignConsumerKey(ctx, chainID, validator, consumerTMPublicKey) + if err != nil { + return err + } + } + + return nil +} + +// HandleOptOut prepares validator `providerAddr` to opt out from running `chainID`. +// Note that the validator only opts out at the end of an epoch. +func (k Keeper) HandleOptOut(ctx sdk.Context, chainID string, providerAddr types.ProviderConsAddress) error { + if _, found := k.GetConsumerClientId(ctx, chainID); !found { + // A validator can only opt out from a running chain. We check this by checking the consumer client id, because + // `SetConsumerClientId` is set when the chain starts in `CreateConsumerClientInCachedCtx` of `BeginBlockInit`. + return errorsmod.Wrapf( + types.ErrUnknownConsumerChainId, + "opting out of an unknown or not running consumer chain, with id: %s", chainID) + } + + if topN, found := k.GetTopN(ctx, chainID); found && topN > 0 { + // a validator cannot opt out from a Top N chain if the validator is in the Top N validators + validator, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, providerAddr.ToSdkConsAddr()) + if err != nil { + return err + } + valAddr, err := sdk.ValAddressFromBech32(validator.GetOperator()) + if err != nil { + return err + } + power, err := k.stakingKeeper.GetLastValidatorPower(ctx, valAddr) + if err != nil { + return err + } + minPowerInTopN, found := k.GetMinimumPowerInTopN(ctx, chainID) + if !found { + return errorsmod.Wrapf( + types.ErrUnknownConsumerChainId, + "Could not find minimum power in top N for chain with id: %s", chainID) + } + + if power >= minPowerInTopN { + return errorsmod.Wrapf( + types.ErrCannotOptOutFromTopN, + "validator with power (%d) cannot opt out from Top N chain (%s) because all validators"+ + " with at least %d power have to validate", power, chainID, minPowerInTopN) + } + } + + k.DeleteOptedIn(ctx, chainID, providerAddr) + return nil +} + +// OptInTopNValidators opts in to `chainID` all the `bondedValidators` that have at least `minPowerToOptIn` power +func (k Keeper) OptInTopNValidators(ctx sdk.Context, chainID string, bondedValidators []stakingtypes.Validator, minPowerToOptIn int64) { + for _, val := range bondedValidators { + valAddr, err := sdk.ValAddressFromBech32(val.GetOperator()) + if err != nil { + k.Logger(ctx).Error("could not retrieve validator address: %s: %s", + val.GetOperator(), err) + continue + } + power, err := k.stakingKeeper.GetLastValidatorPower(ctx, valAddr) + if err != nil { + k.Logger(ctx).Error("could not retrieve last power of validator address: %s: %s", + val.GetOperator(), err) + continue + } + if power >= minPowerToOptIn { + consAddr, err := val.GetConsAddr() + if err != nil { + k.Logger(ctx).Error("could not retrieve validators consensus address: %s: %s", + val, err) + continue + } + + // if validator already exists it gets overwritten + k.SetOptedIn(ctx, chainID, types.NewProviderConsAddress(consAddr)) + } // else validators that do not belong to the top N validators but were opted in, remain opted in + } +} + +// ComputeMinPowerInTopN returns the minimum power needed for a validator (from the bonded validators) +// to belong to the `topN`% of validators for a Top N chain. +func (k Keeper) ComputeMinPowerInTopN(ctx sdk.Context, bondedValidators []stakingtypes.Validator, topN uint32) (int64, error) { + if topN == 0 || topN > 100 { + // Note that Top N chains have a lower limit on `topN`, namely that topN cannot be less than 50. + // However, we can envision that this method could be used for other (future) reasons where this might not + // be the case. For this, this method operates for `topN`s in (0, 100]. + return 0, fmt.Errorf("trying to compute minimum power with an incorrect"+ + " topN value (%d). topN has to be in (0, 100]", topN) + } + + totalPower := math.LegacyZeroDec() + var powers []int64 + + for _, val := range bondedValidators { + valAddr, err := sdk.ValAddressFromBech32(val.GetOperator()) + if err != nil { + return 0, err + } + power, err := k.stakingKeeper.GetLastValidatorPower(ctx, valAddr) + if err != nil { + return 0, err + } + powers = append(powers, power) + totalPower = totalPower.Add(math.LegacyNewDec(power)) + } + + // sort by powers descending + sort.Slice(powers, func(i, j int) bool { + return powers[i] > powers[j] + }) + + topNThreshold := math.LegacyNewDec(int64(topN)).QuoInt64(int64(100)) + powerSum := math.LegacyZeroDec() + for _, power := range powers { + powerSum = powerSum.Add(math.LegacyNewDec(power)) + if powerSum.Quo(totalPower).GTE(topNThreshold) { + return power, nil + } + } + + // We should never reach this point because the topN can be up to 1.0 (100%) and in the above `for` loop we + // perform an equal comparison as well (`GTE`). + return 0, fmt.Errorf("should never reach this point with topN (%d), totalPower (%d), and powerSum (%d)", topN, totalPower, powerSum) +} + +// CapValidatorSet caps the provided `validators` if chain `chainID` is an Opt In chain with a validator-set cap. If cap +// is `k`, `CapValidatorSet` returns the first `k` validators from `validators` with the highest power. +func (k Keeper) CapValidatorSet(ctx sdk.Context, chainID string, validators []types.ConsumerValidator) []types.ConsumerValidator { + if topN, found := k.GetTopN(ctx, chainID); found && topN > 0 { + // is a no-op if the chain is a Top N chain + return validators + } + + if validatorSetCap, found := k.GetValidatorSetCap(ctx, chainID); found && validatorSetCap != 0 && int(validatorSetCap) < len(validators) { + sort.Slice(validators, func(i, j int) bool { + return validators[i].Power > validators[j].Power + }) + + return validators[:int(validatorSetCap)] + } else { + return validators + } +} + +// CapValidatorsPower caps the power of the validators on chain `chainID` and returns an updated slice of validators +// with their new powers. Works on a best-basis effort because there are cases where we cannot guarantee that all validators +// on the consumer chain have less power than the set validators-power cap. For example, if we have 10 validators and +// the power cap is set to 5%, we need at least one validator to have more than 10% of the voting power on the consumer chain. +func (k Keeper) CapValidatorsPower(ctx sdk.Context, chainID string, validators []types.ConsumerValidator) []types.ConsumerValidator { + if p, found := k.GetValidatorsPowerCap(ctx, chainID); found && p > 0 { + return NoMoreThanPercentOfTheSum(validators, p) + } else { + // is a no-op if power cap is not set for `chainID` + return validators + } +} + +// sum is a helper function to sum all the validators' power +func sum(validators []types.ConsumerValidator) int64 { + s := int64(0) + for _, v := range validators { + s = s + v.Power + } + return s +} + +// NoMoreThanPercentOfTheSum returns a set of validators with updated powers such that no validator has more than the +// provided `percent` of the sum of all validators' powers. Operates on a best-effort basis. +func NoMoreThanPercentOfTheSum(validators []types.ConsumerValidator, percent uint32) []types.ConsumerValidator { + // Algorithm's idea + // ---------------- + // Consider the validators' powers to be `a_1, a_2, ... a_n` and `p` to be the percent in [1, 100]. Now, consider + // the sum `s = a_1 + a_2 + ... + a_n`. Then `maxPower = s * p / 100 <=> 100 * maxPower = s * p`. + // The problem of capping the validators' powers to be no more than `p` has no solution if `(100 / n) > p`. For example, + // for n = 10 and p = 5 we do not have a solution. We would need at least one validator with power greater than 10% + // for a solution to exist. + // So, if `(100 / n) > p` there's no solution. We know that `100 * maxPower = s * p` and so `(100 / n) > (100 * maxPower) / s` + // `100 * s > 100 * maxPower * n <=> s > maxPower * n`. Thus, we do not have a solution if `s > n * maxPower`. + + // If `s <= n * maxPower` the idea of the algorithm is rather simple. + // - Compute the `maxPower` a validator must have so that it does not have more than `percent` of the voting power. + // - If a validator `v` has power `p`, then: + // - if `p > maxPower` we set `v`'s power to `maxPower` and distribute the `p - maxPower` to validators that + // have less than `maxPower` power. This way, the total sum remains the same and no validator has more than + // `maxPower` and so the power capping is satisfied. + // - Note that in order to avoid setting multiple validators to `maxPower`, we first compute all the `remainingPower` + // we have to distribute and then attempt to add `remainingPower / validatorsWithPowerLessThanMaxPower` to each validator. + // To guarantee that the sum remains the same after the distribution of powers, we sort the powers in descending + // order. This way, we first attempt to add `remainingPower / validatorsWithPowerLessThanMaxPower` to validators + // with greater power and if we cannot add the `remainingPower / validatorsWithPowerLessThanMaxPower` without + // exceeding `maxPower`, we just add enough to reach `maxPower` and add the remaining power to validators with smaller + // power. + + // If `s > n * maxPower` there's no solution and the algorithm would set everything to `maxPower`. + // ---------------- + + // Computes `floor((sum(validators) * percent) / 100)` + maxPower := math.LegacyNewDec(sum(validators)).Mul(math.LegacyNewDec(int64(percent))).QuoInt64(100).TruncateInt64() + + if maxPower == 0 { + // edge case: set `maxPower` to 1 to avoid setting the power of a validator to 0 + maxPower = 1 + } + + // Sort by `.Power` in decreasing order. Sorting in descending order is needed because otherwise we would have cases + // like this `powers =[60, 138, 559]` and `p = 35%` where sum is `757` and `maxValue = 264`. + // Because `559 - 264 = 295` we have to distribute 295 to the first 2 numbers (`295/2 = 147` to each number). However, + // note that `138 + 147 > 264`. If we were to add 147 to 60 first, then we cannot give the remaining 147 to 138. + // So, the idea is to first give `126 (= 264 - 138)` to 138, so it becomes 264, and then add `21 (=147 - 26) + 147` to 60. + sort.Slice(validators, func(i, j int) bool { + return validators[i].Power > validators[j].Power + }) + + // `remainingPower` is to be distributed to validators that have power less than `maxPower` + remainingPower := int64(0) + validatorsWithPowerLessThanMaxPower := 0 + for _, v := range validators { + if v.Power >= maxPower { + remainingPower = remainingPower + (v.Power - maxPower) + } else { + validatorsWithPowerLessThanMaxPower++ + } + } + + updatedValidators := make([]types.ConsumerValidator, len(validators)) + + powerPerValidator := int64(0) + remainingValidators := int64(validatorsWithPowerLessThanMaxPower) + if remainingValidators != 0 { + // power to give to each validator in order to distribute the `remainingPower` + powerPerValidator = remainingPower / remainingValidators + } + + for i, v := range validators { + if v.Power >= maxPower { + updatedValidators[i] = validators[i] + updatedValidators[i].Power = maxPower + } else if v.Power+powerPerValidator >= maxPower { + updatedValidators[i] = validators[i] + updatedValidators[i].Power = maxPower + remainingPower = remainingPower - (maxPower - v.Power) + remainingValidators-- + } else { + updatedValidators[i] = validators[i] + updatedValidators[i].Power = v.Power + powerPerValidator + remainingPower = remainingPower - (updatedValidators[i].Power - validators[i].Power) + remainingValidators-- + } + if remainingValidators == 0 { + continue + } + powerPerValidator = remainingPower / remainingValidators + } + + return updatedValidators +} + +// CanValidateChain returns true if the validator `providerAddr` is opted-in to chain `chainID` and the allowlist and +// denylist do not prevent the validator from validating the chain. +func (k Keeper) CanValidateChain(ctx sdk.Context, chainID string, providerAddr types.ProviderConsAddress) bool { + // only consider opted-in validators + return k.IsOptedIn(ctx, chainID, providerAddr) && + // if an allowlist is declared, only consider allowlisted validators + (k.IsAllowlistEmpty(ctx, chainID) || + k.IsAllowlisted(ctx, chainID, providerAddr)) && + // if a denylist is declared, only consider denylisted validators + (k.IsDenylistEmpty(ctx, chainID) || + !k.IsDenylisted(ctx, chainID, providerAddr)) +} + +// ComputeNextValidators computes the validators for the upcoming epoch based on the currently `bondedValidators`. +func (k Keeper) ComputeNextValidators(ctx sdk.Context, chainID string, bondedValidators []stakingtypes.Validator) []types.ConsumerValidator { + nextValidators := k.FilterValidators(ctx, chainID, bondedValidators, + func(providerAddr types.ProviderConsAddress) bool { + return k.CanValidateChain(ctx, chainID, providerAddr) + }) + + nextValidators = k.CapValidatorSet(ctx, chainID, nextValidators) + return k.CapValidatorsPower(ctx, chainID, nextValidators) +} diff --git a/x/ccv/provider/keeper/partial_set_security_test.go b/x/ccv/provider/keeper/partial_set_security_test.go new file mode 100644 index 0000000000..2dfbfd3b82 --- /dev/null +++ b/x/ccv/provider/keeper/partial_set_security_test.go @@ -0,0 +1,684 @@ +package keeper_test + +import ( + "bytes" + "sort" + "testing" + + gomath "math" + + "cosmossdk.io/math" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "pgregory.net/rapid" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/cometbft/cometbft/proto/tendermint/crypto" + + testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" +) + +func TestHandleOptIn(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerAddr := types.NewProviderConsAddress([]byte("providerAddr")) + + // trying to opt in to a non-proposed and non-registered chain returns an error + require.Error(t, providerKeeper.HandleOptIn(ctx, "unknownChainID", providerAddr, "")) + + providerKeeper.SetProposedConsumerChain(ctx, "chainID", 1) + require.False(t, providerKeeper.IsOptedIn(ctx, "chainID", providerAddr)) + providerKeeper.HandleOptIn(ctx, "chainID", providerAddr, "") + require.True(t, providerKeeper.IsOptedIn(ctx, "chainID", providerAddr)) +} + +func TestHandleOptInWithConsumerKey(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + // generate a consensus public key for the provider + providerConsPubKey := ed25519.GenPrivKeyFromSecret([]byte{1}).PubKey() + consAddr := sdk.ConsAddress(providerConsPubKey.Address()) + providerAddr := types.NewProviderConsAddress(consAddr) + + calls := []*gomock.Call{ + mocks.MockStakingKeeper.EXPECT(). + GetValidatorByConsAddr(gomock.Any(), gomock.Any()). + DoAndReturn(func(ctx sdk.Context, addr sdk.ConsAddress) (stakingtypes.Validator, error) { + if addr.Equals(providerAddr.Address) { + // Given `providerAddr`, `GetValidatorByConsAddr` returns a validator with the + // exact same `ConsensusPubkey` + pkAny, _ := codectypes.NewAnyWithValue(providerConsPubKey) + return stakingtypes.Validator{ConsensusPubkey: pkAny}, nil + } else { + // for any other consensus address, we cannot find a validator + return stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound + } + }).Times(2), + } + + gomock.InOrder(calls...) + providerKeeper.SetProposedConsumerChain(ctx, "chainID", 1) + + // create a sample consumer key to assign to the `providerAddr` validator + // on the consumer chain with id `chainID` + consumerKey := "{\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is=\"}" + expectedConsumerPubKey, err := providerKeeper.ParseConsumerKey(consumerKey) + require.NoError(t, err) + + err = providerKeeper.HandleOptIn(ctx, "chainID", providerAddr, consumerKey) + require.NoError(t, err) + + // assert that the consumeKey was assigned to `providerAddr` validator on chain with id `chainID` + actualConsumerPubKey, found := providerKeeper.GetValidatorConsumerPubKey(ctx, "chainID", providerAddr) + require.True(t, found) + require.Equal(t, expectedConsumerPubKey, actualConsumerPubKey) + + // assert that the `consumerAddr` to `providerAddr` association was set as well + consumerAddr, _ := ccvtypes.TMCryptoPublicKeyToConsAddr(actualConsumerPubKey) + actualProviderConsAddr, found := providerKeeper.GetValidatorByConsumerAddr(ctx, "chainID", types.NewConsumerConsAddress(consumerAddr)) + require.Equal(t, providerAddr, actualProviderConsAddr) +} + +func TestHandleOptOut(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerAddr := types.NewProviderConsAddress([]byte("providerAddr")) + + // trying to opt out from a not running chain returns an error + require.Error(t, providerKeeper.HandleOptOut(ctx, "unknownChainID", providerAddr)) + + // set a consumer client so that the chain is considered running + providerKeeper.SetConsumerClientId(ctx, "chainID", "clientID") + + // if validator (`providerAddr`) is already opted in, then an opt-out would remove this validator + providerKeeper.SetOptedIn(ctx, "chainID", providerAddr) + require.True(t, providerKeeper.IsOptedIn(ctx, "chainID", providerAddr)) + providerKeeper.HandleOptOut(ctx, "chainID", providerAddr) + require.False(t, providerKeeper.IsOptedIn(ctx, "chainID", providerAddr)) +} + +func TestHandleOptOutFromTopNChain(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + chainID := "chainID" + + // set a consumer client so that the chain is considered running + providerKeeper.SetConsumerClientId(ctx, chainID, "clientID") + + // set the chain as Top 50 and create 4 validators with 10%, 20%, 30%, and 40% of the total voting power + // respectively + providerKeeper.SetTopN(ctx, "chainID", 50) + valA := createStakingValidator(ctx, mocks, 1, 1, 1) // 10% of the total voting power (can opt out) + valAConsAddr, _ := valA.GetConsAddr() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valAConsAddr).Return(valA, nil).AnyTimes() + valB := createStakingValidator(ctx, mocks, 2, 2, 2) // 20% of the total voting power (can opt out) + valBConsAddr, _ := valB.GetConsAddr() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valBConsAddr).Return(valB, nil).AnyTimes() + valC := createStakingValidator(ctx, mocks, 3, 3, 3) // 30% of the total voting power (cannot opt out) + valCConsAddr, _ := valC.GetConsAddr() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valCConsAddr).Return(valC, nil).AnyTimes() + valD := createStakingValidator(ctx, mocks, 4, 4, 4) // 40% of the total voting power (cannot opt out) + valDConsAddr, _ := valD.GetConsAddr() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valDConsAddr).Return(valD, nil).AnyTimes() + + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 4, []stakingtypes.Validator{valA, valB, valC, valD}, []int64{1, 2, 3, 4}, -1) // -1 to allow mocks AnyTimes + + // initialize the minPowerInTopN correctly + minPowerInTopN, err := providerKeeper.ComputeMinPowerInTopN(ctx, []stakingtypes.Validator{valA, valB, valC, valD}, 50) + require.NoError(t, err) + providerKeeper.SetMinimumPowerInTopN(ctx, chainID, minPowerInTopN) + + // opt in all validators + providerKeeper.SetOptedIn(ctx, chainID, types.NewProviderConsAddress(valAConsAddr)) + providerKeeper.SetOptedIn(ctx, chainID, types.NewProviderConsAddress(valBConsAddr)) + providerKeeper.SetOptedIn(ctx, chainID, types.NewProviderConsAddress(valCConsAddr)) + providerKeeper.SetOptedIn(ctx, chainID, types.NewProviderConsAddress(valDConsAddr)) + + // validators A and B can opt out because they belong the bottom 30% of validators + require.NoError(t, providerKeeper.HandleOptOut(ctx, chainID, types.NewProviderConsAddress(valAConsAddr))) + require.NoError(t, providerKeeper.HandleOptOut(ctx, chainID, types.NewProviderConsAddress(valBConsAddr))) + + // validators C and D cannot opt out because C has 30% of the voting power and D has 40% of the voting power + // and hence both are needed to keep validating a Top 50 chain + require.Error(t, providerKeeper.HandleOptOut(ctx, chainID, types.NewProviderConsAddress(valCConsAddr))) + require.Error(t, providerKeeper.HandleOptOut(ctx, chainID, types.NewProviderConsAddress(valDConsAddr))) + + // opting out a validator that cannot be found from a Top N chain should also return an error + notFoundValidator := createStakingValidator(ctx, mocks, 5, 5, 5) + notFoundValidatorConsAddr, _ := notFoundValidator.GetConsAddr() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, notFoundValidatorConsAddr). + Return(stakingtypes.Validator{}, stakingtypes.ErrNoValidatorFound) + require.Error(t, providerKeeper.HandleOptOut(ctx, chainID, types.NewProviderConsAddress(notFoundValidatorConsAddr))) +} + +func TestHandleSetConsumerCommissionRate(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerAddr := types.NewProviderConsAddress([]byte("providerAddr")) + + // trying to set a commission rate to a unknown consumer chain + require.Error(t, providerKeeper.HandleSetConsumerCommissionRate(ctx, "unknownChainID", providerAddr, math.LegacyZeroDec())) + + // setup a pending consumer chain + chainID := "pendingChainID" + providerKeeper.SetPendingConsumerAdditionProp(ctx, &types.ConsumerAdditionProposal{ChainId: chainID}) + + // check that there's no commission rate set for the validator yet + _, found := providerKeeper.GetConsumerCommissionRate(ctx, chainID, providerAddr) + require.False(t, found) + + mocks.MockStakingKeeper.EXPECT().MinCommissionRate(ctx).Return(math.LegacyZeroDec(), nil).Times(1) + require.NoError(t, providerKeeper.HandleSetConsumerCommissionRate(ctx, chainID, providerAddr, math.LegacyOneDec())) + + // check that the commission rate is now set + cr, found := providerKeeper.GetConsumerCommissionRate(ctx, chainID, providerAddr) + require.Equal(t, math.LegacyOneDec(), cr) + require.True(t, found) + + // set minimum rate of 1/2 + commissionRate := math.LegacyNewDec(1).Quo(math.LegacyNewDec(2)) + mocks.MockStakingKeeper.EXPECT().MinCommissionRate(ctx).Return(commissionRate, nil).AnyTimes() + + // try to set a rate slightly below the minimum + require.Error(t, providerKeeper.HandleSetConsumerCommissionRate( + ctx, + chainID, + providerAddr, + commissionRate.Sub(math.LegacyNewDec(1).Quo(math.LegacyNewDec(100)))), // 0.5 - 0.01 + "commission rate should be rejected (below min), but is not", + ) + + // set a valid commission equal to the minimum + require.NoError(t, providerKeeper.HandleSetConsumerCommissionRate(ctx, chainID, providerAddr, commissionRate)) + // check that the rate was set + cr, found = providerKeeper.GetConsumerCommissionRate(ctx, chainID, providerAddr) + require.Equal(t, commissionRate, cr) + require.True(t, found) +} + +func TestOptInTopNValidators(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + // create 4 validators with powers 1, 2, 3, and 1 respectively + valA := createStakingValidator(ctx, mocks, 1, 1, 1) + valAConsAddr, _ := valA.GetConsAddr() + valB := createStakingValidator(ctx, mocks, 2, 2, 2) + valBConsAddr, _ := valB.GetConsAddr() + valC := createStakingValidator(ctx, mocks, 3, 3, 3) + valCConsAddr, _ := valC.GetConsAddr() + valD := createStakingValidator(ctx, mocks, 4, 1, 4) + valDConsAddr, _ := valD.GetConsAddr() + + // Start Test 1: opt in all validators with power >= 0 + providerKeeper.OptInTopNValidators(ctx, "chainID", []stakingtypes.Validator{valA, valB, valC, valD}, 0) + expectedOptedInValidators := []types.ProviderConsAddress{ + types.NewProviderConsAddress(valAConsAddr), + types.NewProviderConsAddress(valBConsAddr), + types.NewProviderConsAddress(valCConsAddr), + types.NewProviderConsAddress(valDConsAddr), + } + actualOptedInValidators := providerKeeper.GetAllOptedIn(ctx, "chainID") + + // sort validators first to be able to compare + sortUpdates := func(addresses []types.ProviderConsAddress) { + sort.Slice(addresses, func(i, j int) bool { + return bytes.Compare(addresses[i].ToSdkConsAddr(), addresses[j].ToSdkConsAddr()) < 0 + }) + } + + sortUpdates(expectedOptedInValidators) + sortUpdates(actualOptedInValidators) + require.Equal(t, expectedOptedInValidators, actualOptedInValidators) + + // reset state for the upcoming checks + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valAConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valBConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valCConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valDConsAddr)) + + // Start Test 2: opt in all validators with power >= 1 + // We expect the same `expectedOptedInValidators` as when we opted in all validators with power >= 0 because the + // validators with the smallest power have power == 1 + providerKeeper.OptInTopNValidators(ctx, "chainID", []stakingtypes.Validator{valA, valB, valC, valD}, 0) + actualOptedInValidators = providerKeeper.GetAllOptedIn(ctx, "chainID") + sortUpdates(actualOptedInValidators) + require.Equal(t, expectedOptedInValidators, actualOptedInValidators) + + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valAConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valBConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valCConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valDConsAddr)) + + // Start Test 3: opt in all validators with power >= 2 and hence we do not expect to opt in validator A + providerKeeper.OptInTopNValidators(ctx, "chainID", []stakingtypes.Validator{valA, valB, valC, valD}, 2) + expectedOptedInValidators = []types.ProviderConsAddress{ + types.NewProviderConsAddress(valBConsAddr), + types.NewProviderConsAddress(valCConsAddr), + } + actualOptedInValidators = providerKeeper.GetAllOptedIn(ctx, "chainID") + + // sort validators first to be able to compare + sortUpdates(expectedOptedInValidators) + sortUpdates(actualOptedInValidators) + require.Equal(t, expectedOptedInValidators, actualOptedInValidators) + + // reset state for the upcoming checks + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valAConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valBConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valCConsAddr)) + providerKeeper.DeleteOptedIn(ctx, "chainID", types.NewProviderConsAddress(valDConsAddr)) + + // Start Test 4: opt in all validators with power >= 4 and hence we do not expect any opted-in validators + providerKeeper.OptInTopNValidators(ctx, "chainID", []stakingtypes.Validator{valA, valB, valC, valD}, 4) + require.Empty(t, providerKeeper.GetAllOptedIn(ctx, "chainID")) +} + +func TestComputeMinPowerInTopN(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + // create 5 validators with powers 1, 3, 5, 6, 10 (not in that order) with total power of 25 (= 1 + 3 + 5 + 6 + 10) + // such that: + // validator power => cumulative share + // 10 => 40% + // 6 => 64% + // 5 => 84% + // 3 => 96% + // 1 => 100% + + bondedValidators := []stakingtypes.Validator{ + createStakingValidator(ctx, mocks, 1, 5, 1), + createStakingValidator(ctx, mocks, 2, 10, 2), + createStakingValidator(ctx, mocks, 3, 3, 3), + createStakingValidator(ctx, mocks, 4, 1, 4), + createStakingValidator(ctx, mocks, 5, 6, 5), + } + + m, err := providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 100) + require.NoError(t, err) + require.Equal(t, int64(1), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 97) + require.NoError(t, err) + require.Equal(t, int64(1), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 96) + require.NoError(t, err) + require.Equal(t, int64(3), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 85) + require.NoError(t, err) + require.Equal(t, int64(3), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 84) + require.NoError(t, err) + require.Equal(t, int64(5), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 65) + require.NoError(t, err) + require.Equal(t, int64(5), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 64) + require.NoError(t, err) + require.Equal(t, int64(6), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 50) + require.NoError(t, err) + require.Equal(t, int64(6), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 40) + require.NoError(t, err) + require.Equal(t, int64(10), m) + + m, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 1) + require.NoError(t, err) + require.Equal(t, int64(10), m) + + _, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 0) + require.Error(t, err) + + _, err = providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, 101) + require.Error(t, err) +} + +// TestCanValidateChain returns true if `validator` is opted in, in `chainID. +func TestCanValidateChain(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + validator := createStakingValidator(ctx, mocks, 0, 1, 1) + consAddr, _ := validator.GetConsAddr() + providerAddr := types.NewProviderConsAddress(consAddr) + + // with no allowlist or denylist, the validator has to be opted in, in order to consider it + require.False(t, providerKeeper.CanValidateChain(ctx, "chainID", providerAddr)) + providerKeeper.SetOptedIn(ctx, "chainID", types.NewProviderConsAddress(consAddr)) + require.True(t, providerKeeper.CanValidateChain(ctx, "chainID", providerAddr)) + + // create an allow list but do not add the validator `providerAddr` to it + validatorA := createStakingValidator(ctx, mocks, 1, 1, 2) + consAddrA, _ := validatorA.GetConsAddr() + providerKeeper.SetAllowlist(ctx, "chainID", types.NewProviderConsAddress(consAddrA)) + require.False(t, providerKeeper.CanValidateChain(ctx, "chainID", providerAddr)) + providerKeeper.SetAllowlist(ctx, "chainID", types.NewProviderConsAddress(consAddr)) + require.True(t, providerKeeper.CanValidateChain(ctx, "chainID", providerAddr)) + + // create a denylist but do not add validator `providerAddr` to it + providerKeeper.SetDenylist(ctx, "chainID", types.NewProviderConsAddress(consAddrA)) + require.True(t, providerKeeper.CanValidateChain(ctx, "chainID", providerAddr)) + // add validator `providerAddr` to the denylist + providerKeeper.SetDenylist(ctx, "chainID", types.NewProviderConsAddress(consAddr)) + require.False(t, providerKeeper.CanValidateChain(ctx, "chainID", providerAddr)) +} + +func TestCapValidatorSet(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + validatorA := types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddrA"), + Power: 1, + ConsumerPublicKey: &crypto.PublicKey{}, + } + + validatorB := types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddrB"), + Power: 2, + ConsumerPublicKey: &crypto.PublicKey{}, + } + + validatorC := types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddrC"), + Power: 3, + ConsumerPublicKey: &crypto.PublicKey{}, + } + validators := []types.ConsumerValidator{validatorA, validatorB, validatorC} + + consumerValidators := providerKeeper.CapValidatorSet(ctx, "chainID", validators) + require.Equal(t, validators, consumerValidators) + + providerKeeper.SetValidatorSetCap(ctx, "chainID", 0) + consumerValidators = providerKeeper.CapValidatorSet(ctx, "chainID", validators) + require.Equal(t, validators, consumerValidators) + + providerKeeper.SetValidatorSetCap(ctx, "chainID", 100) + consumerValidators = providerKeeper.CapValidatorSet(ctx, "chainID", validators) + require.Equal(t, validators, consumerValidators) + + providerKeeper.SetValidatorSetCap(ctx, "chainID", 1) + consumerValidators = providerKeeper.CapValidatorSet(ctx, "chainID", validators) + require.Equal(t, []types.ConsumerValidator{validatorC}, consumerValidators) + + providerKeeper.SetValidatorSetCap(ctx, "chainID", 2) + consumerValidators = providerKeeper.CapValidatorSet(ctx, "chainID", validators) + require.Equal(t, []types.ConsumerValidator{validatorC, validatorB}, consumerValidators) + + providerKeeper.SetValidatorSetCap(ctx, "chainID", 3) + consumerValidators = providerKeeper.CapValidatorSet(ctx, "chainID", validators) + require.Equal(t, []types.ConsumerValidator{validatorC, validatorB, validatorA}, consumerValidators) +} + +func TestCapValidatorsPower(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + validatorA := types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddrA"), + Power: 1, + ConsumerPublicKey: &crypto.PublicKey{}, + } + + validatorB := types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddrB"), + Power: 2, + ConsumerPublicKey: &crypto.PublicKey{}, + } + + validatorC := types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddrC"), + Power: 3, + ConsumerPublicKey: &crypto.PublicKey{}, + } + + validatorD := types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddrD"), + Power: 4, + ConsumerPublicKey: &crypto.PublicKey{}, + } + + validators := []types.ConsumerValidator{validatorA, validatorB, validatorC, validatorD} + + expectedValidators := make([]types.ConsumerValidator, len(validators)) + copy(expectedValidators, validators) + expectedValidators[0].Power = 2 + expectedValidators[1].Power = 2 + expectedValidators[2].Power = 3 + expectedValidators[3].Power = 3 + + sortValidators := func(validators []types.ConsumerValidator) { + sort.Slice(validators, func(i, j int) bool { + return bytes.Compare(validators[i].ProviderConsAddr, validators[j].ProviderConsAddr) < 0 + }) + } + + // no capping takes place because validators power-cap is not set + cappedValidators := providerKeeper.CapValidatorsPower(ctx, "chainID", validators) + sortValidators(validators) + sortValidators(cappedValidators) + require.Equal(t, validators, cappedValidators) + + providerKeeper.SetValidatorsPowerCap(ctx, "chainID", 33) + cappedValidators = providerKeeper.CapValidatorsPower(ctx, "chainID", validators) + sortValidators(expectedValidators) + sortValidators(cappedValidators) + require.Equal(t, expectedValidators, cappedValidators) +} + +func TestNoMoreThanPercentOfTheSum(t *testing.T) { + // **impossible** case where we only have 9 powers, and we want that no number has more than 10% of the total sum + powers := []int64{1, 2, 3, 4, 5, 6, 7, 8, 9} + percent := uint32(10) + require.False(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) + + powers = []int64{1, 2, 3, 4, 5} + percent = 20 + require.True(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) + + powers = []int64{1, 2, 3, 4, 5} + percent = 21 + require.True(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) + + powers = []int64{1, 2, 3, 4, 5} + percent = 25 + require.True(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) + + powers = []int64{1, 2, 3, 4, 5} + percent = 32 + require.True(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) + + powers = []int64{1, 2, 3, 4, 5} + percent = 33 + require.True(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) + + powers = []int64{1, 2, 3, 4, 5} + percent = 34 + require.True(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) + + powers = []int64{1, 2, 3, 4, 5} + percent = 50 + require.True(t, noMoreThanPercent(keeper.NoMoreThanPercentOfTheSum(createConsumerValidators(powers), percent), percent)) +} + +func createConsumerValidators(powers []int64) []types.ConsumerValidator { + var validators []types.ConsumerValidator + for _, p := range powers { + validators = append(validators, types.ConsumerValidator{ + ProviderConsAddr: []byte("providerConsAddr"), + Power: p, + ConsumerPublicKey: &crypto.PublicKey{}, + }) + } + return validators +} + +// returns `true` if no validator in `validators` corresponds to more than `percent` of the total sum of all +// validators' powers +func noMoreThanPercent(validators []types.ConsumerValidator, percent uint32) bool { + sum := int64(0) + for _, v := range validators { + sum = sum + v.Power + } + + for _, v := range validators { + if float64(v.Power)*100.0 > float64(percent)*float64(sum) { + return false + } + } + return true +} + +func sumPowers(vals []types.ConsumerValidator) int64 { + sum := int64(0) + for _, v := range vals { + sum += v.Power + } + return sum +} + +func CapSatisfiable(vals []types.ConsumerValidator, percent uint32) bool { + // 100 / len(vals) is what each validator gets if each has the same power. + // if this is more than the cap, it cannot be satisfied. + return float64(100)/float64(len(vals)) < float64(percent) +} + +func TestNoMoreThanPercentOfTheSumProps(t *testing.T) { + // define properties to test + + // capRespectedIfSatisfiable: if the cap can be respected, then it will be respected + capRespectedIfSatisfiable := func(valsBefore, valsAfter []types.ConsumerValidator, percent uint32) bool { + if CapSatisfiable(valsBefore, percent) { + return noMoreThanPercent(valsAfter, percent) + } + return true + } + + evenPowersIfCapCannotBeSatisfied := func(valsBefore, valsAfter []types.ConsumerValidator, percent uint32) bool { + if !CapSatisfiable(valsBefore, percent) { + // if the cap cannot be satisfied, each validator should have the same power + for _, valAfter := range valsAfter { + if valAfter.Power != valsAfter[0].Power { + return false + } + } + } + return true + } + + // fairness: if before, v1 has more power than v2, then afterwards v1 will not have less power than v2 + // (they might get the same power if they are both capped) + fairness := func(valsBefore, valsAfter []types.ConsumerValidator) bool { + for i, v := range valsBefore { + // find the validator after with the same address + vAfter := findConsumerValidator(t, v, valsAfter) + + // go through all other validators before (after this one, to avoid double checking) + for j := i + 1; j < len(valsBefore); j++ { + otherV := valsBefore[j] + otherVAfter := findConsumerValidator(t, otherV, valsAfter) + + // v has at least as much power before + if v.Power >= otherV.Power { + // then otherV should not have more power after + if vAfter.Power < otherVAfter.Power { + return false + } + } else { + // v has less power before + // then v should not have more power after + if vAfter.Power > otherVAfter.Power { + return false + } + } + } + } + return true + } + + // non-zero: v has non-zero power before IFF it has non-zero power after + nonZero := func(valsBefore, valsAfter []types.ConsumerValidator) bool { + for _, v := range valsBefore { + vAfter := findConsumerValidator(t, v, valsAfter) + if (v.Power == 0) != (vAfter.Power == 0) { + return false + } + } + return true + } + + // equalSumIfCapSatisfiable: the sum of the powers of the validators will not change if the cap can be satisfied + // (except for small changes by rounding errors) + equalSumIfCapSatisfiable := func(valsBefore, valsAfter []types.ConsumerValidator, percent uint32) bool { + if CapSatisfiable(valsBefore, percent) { + difference := gomath.Abs(float64(sumPowers(valsBefore) - sumPowers(valsAfter))) + if difference > 1 { + // if the difference is more than a rounding error, they are not equal + return false + } + } + return true + } + + // num validators: the number of validators will not change + equalNumVals := func(valsBefore, valsAfter []types.ConsumerValidator) bool { + return len(valsBefore) == len(valsAfter) + } + + // test setup for pbt + rapid.Check(t, func(t *rapid.T) { + powers := rapid.SliceOf(rapid.Int64Range(1, 1000000000000)).Draw(t, "powers") + percent := uint32(rapid.Int32Range(1, 100).Draw(t, "percent")) + + consumerValidators := createConsumerValidators(powers) + cappedValidators := keeper.NoMoreThanPercentOfTheSum(consumerValidators, percent) + + t.Log("can the cap be satisfied: ", CapSatisfiable(consumerValidators, percent)) + t.Log("before: ", consumerValidators) + t.Log("after: ", cappedValidators) + + // check properties + require.True(t, capRespectedIfSatisfiable(consumerValidators, cappedValidators, percent)) + require.True(t, evenPowersIfCapCannotBeSatisfied(consumerValidators, cappedValidators, percent)) + require.True(t, fairness(consumerValidators, cappedValidators)) + require.True(t, nonZero(consumerValidators, cappedValidators)) + require.True(t, equalSumIfCapSatisfiable(consumerValidators, cappedValidators, percent), "sum before: %v, sum after: %v", sumPowers(consumerValidators), sumPowers(cappedValidators)) + require.True(t, equalNumVals(consumerValidators, cappedValidators), "num before: %v, num after: %v", len(consumerValidators), len(cappedValidators)) + }) +} + +func findConsumerValidator(t *testing.T, v types.ConsumerValidator, valsAfter []types.ConsumerValidator) *types.ConsumerValidator { + var vAfter *types.ConsumerValidator + for _, vA := range valsAfter { + if bytes.Equal(v.ProviderConsAddr, vA.ProviderConsAddr) { + vAfter = &vA + break + } + } + if vAfter == nil { + t.Fatalf("could not find validator with address %v in validators after \n validators after capping: %v", v.ProviderConsAddr, valsAfter) + } + return vAfter +} diff --git a/x/ccv/provider/keeper/proposal.go b/x/ccv/provider/keeper/proposal.go index ecb9b5156b..887251c87a 100644 --- a/x/ccv/provider/keeper/proposal.go +++ b/x/ccv/provider/keeper/proposal.go @@ -1,11 +1,12 @@ package keeper import ( - "errors" "fmt" "strconv" "time" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" commitmenttypes "github.com/cosmos/ibc-go/v8/modules/core/23-commitment/types" @@ -16,7 +17,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" tmtypes "github.com/cometbft/cometbft/types" @@ -41,8 +41,8 @@ func (k Keeper) HandleConsumerAdditionProposal(ctx sdk.Context, proposal *types. HistoricalEntries: proposal.HistoricalEntries, DistributionTransmissionChannel: proposal.DistributionTransmissionChannel, } - return k.HandleLegacyConsumerAdditionProposal(ctx, &p) + return k.HandleLegacyConsumerAdditionProposal(ctx, &p) } // Wrapper for the new proposal message MsgConsumerRemoval @@ -52,8 +52,8 @@ func (k Keeper) HandleConsumerRemovalProposal(ctx sdk.Context, proposal *types.M ChainId: proposal.ChainId, StopTime: proposal.StopTime, } - return k.HandleLegacyConsumerRemovalProposal(ctx, &p) + return k.HandleLegacyConsumerRemovalProposal(ctx, &p) } // Wrapper for the new proposal message MsgChangeRewardDenoms @@ -63,9 +63,26 @@ func (k Keeper) HandleConsumerRewardDenomProposal(ctx sdk.Context, proposal *typ DenomsToAdd: proposal.DenomsToAdd, DenomsToRemove: proposal.DenomsToRemove, } + return k.HandleLegacyConsumerRewardDenomProposal(ctx, &p) } +// HandleConsumerModificationProposal modifies a running consumer chain +func (k Keeper) HandleConsumerModificationProposal(ctx sdk.Context, proposal *types.MsgConsumerModification) error { + p := types.ConsumerModificationProposal{ + Title: proposal.Title, + Description: proposal.Description, + ChainId: proposal.ChainId, + Top_N: proposal.Top_N, + ValidatorsPowerCap: proposal.ValidatorsPowerCap, + ValidatorSetCap: proposal.ValidatorSetCap, + Allowlist: proposal.Allowlist, + Denylist: proposal.Denylist, + } + + return k.HandleLegacyConsumerModificationProposal(ctx, &p) +} + // CreateConsumerClient will create the CCV client for the given consumer chain. The CCV channel must be built // on top of the CCV client to ensure connection with the right consumer chain. // @@ -160,6 +177,7 @@ func (k Keeper) StopConsumerChain(ctx sdk.Context, chainID string, closeChan boo k.DeleteInitTimeoutTimestamp(ctx, chainID) // Note: this call panics if the key assignment state is invalid k.DeleteKeyAssignments(ctx, chainID) + k.DeleteMinimumPowerInTopN(ctx, chainID) // close channel and delete the mappings between chain ID and channel ID if channelID, found := k.GetChainToChannel(ctx, chainID); found { @@ -185,6 +203,12 @@ func (k Keeper) StopConsumerChain(ctx sdk.Context, chainID string, closeChan boo k.DeleteVscSendTimestampsForConsumer(ctx, chainID) } + // delete consumer commission rate + provAddrs := k.GetAllCommissionRateValidators(ctx, chainID) + for _, addr := range provAddrs { + k.DeleteConsumerCommissionRate(ctx, chainID, addr) + } + k.DeleteInitChainHeight(ctx, chainID) k.DeleteSlashAcks(ctx, chainID) k.DeletePendingVSCPackets(ctx, chainID) @@ -209,6 +233,15 @@ func (k Keeper) StopConsumerChain(ctx sdk.Context, chainID string, closeChan boo k.DeleteUnbondingOpIndex(ctx, chainID, unbondingOpsIndex.VscId) } + k.DeleteTopN(ctx, chainID) + k.DeleteValidatorsPowerCap(ctx, chainID) + k.DeleteValidatorSetCap(ctx, chainID) + k.DeleteAllowlist(ctx, chainID) + k.DeleteDenylist(ctx, chainID) + + k.DeleteAllOptedIn(ctx, chainID) + k.DeleteConsumerValSet(ctx, chainID) + k.Logger(ctx).Info("consumer chain removed from provider", "chainID", chainID) return nil @@ -244,43 +277,23 @@ func (k Keeper) MakeConsumerGenesis( return gen, nil, errorsmod.Wrapf(clienttypes.ErrConsensusStateNotFound, "error %s getting self consensus state for: %s", err, height) } - var lastPowers []stakingtypes.LastValidatorPower - - k.stakingKeeper.IterateLastValidatorPowers(ctx, func(addr sdk.ValAddress, power int64) (stop bool) { - lastPowers = append(lastPowers, stakingtypes.LastValidatorPower{Address: addr.String(), Power: power}) - return false - }) - - var bondedValidators []stakingtypes.Validator + // get the bonded validators from the staking module + bondedValidators, err := k.GetLastBondedValidators(ctx) + if err != nil { + return gen, nil, errorsmod.Wrapf(stakingtypes.ErrNoValidatorFound, "error getting last bonded validators: %s", err) + } - for _, p := range lastPowers { - addr, err := sdk.ValAddressFromBech32(p.Address) + if prop.Top_N > 0 { + // in a Top-N chain, we automatically opt in all validators that belong to the top N + minPower, err := k.ComputeMinPowerInTopN(ctx, bondedValidators, prop.Top_N) if err != nil { return gen, nil, err } - - val, err := k.stakingKeeper.GetValidator(ctx, addr) - if err != nil && errors.Is(err, stakingtypes.ErrNoValidatorFound) { - return gen, nil, errorsmod.Wrapf(stakingtypes.ErrNoValidatorFound, "error getting validator from LastValidatorPowers") - } else if err != nil { - return gen, nil, errorsmod.Wrapf(err, "error getting validator from LastValidatorPowers") - } - - // TODO: Remove this code block after main merge - // tmProtoPk, err := val.CmtConsPublicKey() - // if err != nil { - // return gen, nil, err - // } - - // initialUpdates = append(initialUpdates, abci.ValidatorUpdate{ - // PubKey: tmProtoPk, - // Power: p.Power, - // }) - // gather all the bonded validators in order to construct the consumer validator set for consumer chain `chainID` - bondedValidators = append(bondedValidators, val) + k.OptInTopNValidators(ctx, chainID, bondedValidators, minPower) + k.SetMinimumPowerInTopN(ctx, chainID, minPower) } + nextValidators := k.ComputeNextValidators(ctx, chainID, bondedValidators) - nextValidators := k.ComputeNextEpochConsumerValSet(ctx, chainID, bondedValidators) k.SetConsumerValSet(ctx, chainID, nextValidators) // get the initial updates with the latest set consumer public keys @@ -364,14 +377,52 @@ func (k Keeper) GetPendingConsumerAdditionProp(ctx sdk.Context, spawnTime time.T func (k Keeper) BeginBlockInit(ctx sdk.Context) { propsToExecute := k.GetConsumerAdditionPropsToExecute(ctx) - for _, prop := range propsToExecute { + for i, prop := range propsToExecute { // create consumer client in a cached context to handle errors - cachedCtx, writeFn, err := k.CreateConsumerClientInCachedCtx(ctx, prop) + cachedCtx, writeFn := ctx.CacheContext() + + k.SetTopN(cachedCtx, prop.ChainId, prop.Top_N) + k.SetValidatorSetCap(cachedCtx, prop.ChainId, prop.ValidatorSetCap) + k.SetValidatorsPowerCap(cachedCtx, prop.ChainId, prop.ValidatorsPowerCap) + + for _, address := range prop.Allowlist { + consAddr, err := sdk.ConsAddressFromBech32(address) + if err != nil { + continue + } + + k.SetAllowlist(cachedCtx, prop.ChainId, types.NewProviderConsAddress(consAddr)) + } + + for _, address := range prop.Denylist { + consAddr, err := sdk.ConsAddressFromBech32(address) + if err != nil { + continue + } + + k.SetDenylist(cachedCtx, prop.ChainId, types.NewProviderConsAddress(consAddr)) + } + + err := k.CreateConsumerClient(cachedCtx, &propsToExecute[i]) if err != nil { // drop the proposal ctx.Logger().Info("consumer client could not be created: %w", err) continue } + + consumerGenesis, found := k.GetConsumerGenesis(cachedCtx, prop.ChainId) + if !found { + // drop the proposal + ctx.Logger().Info("consumer genesis could not be created") + continue + } + + if len(consumerGenesis.Provider.InitialValSet) == 0 { + // drop the proposal + ctx.Logger().Info("consumer genesis initial validator set is empty - no validators opted in") + continue + } + // The cached context is created with a new EventManager so we merge the event // into the original context ctx.EventManager().EmitEvents(cachedCtx.EventManager().Events()) diff --git a/x/ccv/provider/keeper/proposal_test.go b/x/ccv/provider/keeper/proposal_test.go index 6968110de5..3cd957f61a 100644 --- a/x/ccv/provider/keeper/proposal_test.go +++ b/x/ccv/provider/keeper/proposal_test.go @@ -7,6 +7,8 @@ import ( "testing" "time" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "cosmossdk.io/math" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" @@ -18,6 +20,7 @@ import ( abci "github.com/cometbft/cometbft/abci/types" + cryptotestutil "github.com/cosmos/interchain-security/v5/testutil/crypto" testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" @@ -28,6 +31,120 @@ import ( // Initialization sub-protocol related tests of proposal.go // +// Tests the HandleConsumerAdditionProposal method against the SpawnConsumerChainProposalHandler spec. +// See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-hcaprop1 +// Spec tag: [CCV-PCF-HCAPROP.1] +func TestHandleConsumerAdditionProposal(t *testing.T) { + type testCase struct { + description string + malleate func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) + prop *providertypes.ConsumerAdditionProposal + // Time when prop is handled + blockTime time.Time + // Whether it's expected that the proposal is successfully verified + // and appended to the pending proposals + expAppendProp bool + } + + // Snapshot times asserted in tests + now := time.Now().UTC() + + tests := []testCase{ + { + description: "expect to append valid proposal", + malleate: func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) {}, + prop: providertypes.NewConsumerAdditionProposal( + "title", + "description", + "chainID", + clienttypes.NewHeight(2, 3), + []byte("gen_hash"), + []byte("bin_hash"), + now, // Spawn time + "0.75", + 10, + "", + 10000, + 100000000000, + 100000000000, + 100000000000, + 0, + 0, + 0, + nil, + nil, + ).(*providertypes.ConsumerAdditionProposal), + blockTime: now, + expAppendProp: true, + }, + { + description: "expect to not append invalid proposal using an already existing chain id", + malleate: func(ctx sdk.Context, k providerkeeper.Keeper, chainID string) { + k.SetConsumerClientId(ctx, chainID, "anyClientId") + }, + + prop: providertypes.NewConsumerAdditionProposal( + "title", + "description", + "chainID", + clienttypes.NewHeight(2, 3), + []byte("gen_hash"), + []byte("bin_hash"), + now, + "0.75", + 10, + "", + 10000, + 100000000000, + 100000000000, + 100000000000, + 0, + 0, + 0, + nil, + nil, + ).(*providertypes.ConsumerAdditionProposal), + blockTime: now, + expAppendProp: false, + }, + } + + for _, tc := range tests { + // Common setup + keeperParams := testkeeper.NewInMemKeeperParams(t) + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, keeperParams) + providerKeeper.SetParams(ctx, providertypes.DefaultParams()) + ctx = ctx.WithBlockTime(tc.blockTime) + + if tc.expAppendProp { + // Mock calls are only asserted if we expect a client to be created. + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 0, []stakingtypes.Validator{}, []int64{}, 1) // returns empty validator set + gomock.InOrder( + testkeeper.GetMocksForCreateConsumerClient(ctx, &mocks, tc.prop.ChainId, clienttypes.NewHeight(2, 3))..., + ) + } + + tc.malleate(ctx, providerKeeper, tc.prop.ChainId) + + err := providerKeeper.HandleLegacyConsumerAdditionProposal(ctx, tc.prop) + + if tc.expAppendProp { + require.NoError(t, err) + // check that prop was added to the stored pending props + gotProposal, found := providerKeeper.GetPendingConsumerAdditionProp(ctx, tc.prop.SpawnTime, tc.prop.ChainId) + require.True(t, found) + require.Equal(t, *tc.prop, gotProposal) + } else { + require.Error(t, err) + // check that prop wasn't added to the stored pending props + _, found := providerKeeper.GetPendingConsumerAdditionProp(ctx, tc.prop.SpawnTime, tc.prop.ChainId) + require.False(t, found) + } + + ctrl.Finish() + } +} + // Tests the CreateConsumerClient method against the spec, // with more granularity than what's covered in TestHandleCreateConsumerChainProposal. // See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-crclient1 @@ -45,6 +162,7 @@ func TestCreateConsumerClient(t *testing.T) { description: "No state mutation, new client should be created", setup: func(providerKeeper *providerkeeper.Keeper, ctx sdk.Context, mocks *testkeeper.MockedKeepers) { // Valid client creation is asserted with mock expectations here + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 0, []stakingtypes.Validator{}, []int64{}, 1) // returns empty validator set gomock.InOrder( testkeeper.GetMocksForCreateConsumerClient(ctx, mocks, "chainID", clienttypes.NewHeight(4, 5))..., ) @@ -60,7 +178,7 @@ func TestCreateConsumerClient(t *testing.T) { mocks.MockStakingKeeper.EXPECT().UnbondingTime(gomock.Any()).Times(0) mocks.MockClientKeeper.EXPECT().CreateClient(gomock.Any(), gomock.Any(), gomock.Any()).Times(0) mocks.MockClientKeeper.EXPECT().GetSelfConsensusState(gomock.Any(), gomock.Any()).Times(0) - mocks.MockStakingKeeper.EXPECT().IterateLastValidatorPowers(gomock.Any(), gomock.Any()).Times(0) + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 0, []stakingtypes.Validator{}, []int64{}, 0) // returns empty validator set }, expClientCreated: false, }, @@ -264,10 +382,6 @@ func TestGetAllConsumerAdditionProps(t *testing.T) { require.Equal(t, expectedGetAllOrder, result) } -// -// Consumer Chain Removal sub-protocol related tests of proposal.go -// - // Tests the StopConsumerChain method against the spec, // with more granularity than what's covered in TestHandleLegacyConsumerRemovalProposal, or integration tests. // See: https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#ccv-pcf-stcc1 @@ -540,7 +654,8 @@ func TestMakeConsumerGenesis(t *testing.T) { Denom: "stake", Amount: math.NewInt(1000000), }, - BlocksPerEpoch: 600, + BlocksPerEpoch: 600, + NumberOfEpochsToStartReceivingRewards: 24, } providerKeeper.SetParams(ctx, moduleParams) defer ctrl.Finish() @@ -550,6 +665,7 @@ func TestMakeConsumerGenesis(t *testing.T) { // ctx = ctx.WithChainID("testchain1") // chainID is obtained from ctx ctx = ctx.WithBlockHeight(5) // RevisionHeight obtained from ctx + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 0, []stakingtypes.Validator{}, []int64{}, 1) gomock.InOrder(testkeeper.GetMocksForMakeConsumerGenesis(ctx, &mocks, 1814400000000000)...) // matches params from jsonString @@ -689,6 +805,11 @@ func TestBeginBlockInit(t *testing.T) { 100000000000, 100000000000, 100000000000, + 50, + 0, + 0, + nil, + nil, ).(*providertypes.ConsumerAdditionProposal), providertypes.NewConsumerAdditionProposal( "title", "spawn time passed", "chain2", clienttypes.NewHeight(3, 4), []byte{}, []byte{}, @@ -700,6 +821,11 @@ func TestBeginBlockInit(t *testing.T) { 100000000000, 100000000000, 100000000000, + 50, + 0, + 0, + nil, + nil, ).(*providertypes.ConsumerAdditionProposal), providertypes.NewConsumerAdditionProposal( "title", "spawn time not passed", "chain3", clienttypes.NewHeight(3, 4), []byte{}, []byte{}, @@ -711,6 +837,11 @@ func TestBeginBlockInit(t *testing.T) { 100000000000, 100000000000, 100000000000, + 50, + 0, + 0, + nil, + nil, ).(*providertypes.ConsumerAdditionProposal), providertypes.NewConsumerAdditionProposal( "title", "invalid proposal: chain id already exists", "chain2", clienttypes.NewHeight(4, 5), []byte{}, []byte{}, @@ -722,38 +853,139 @@ func TestBeginBlockInit(t *testing.T) { 100000000000, 100000000000, 100000000000, + 50, + 0, + 0, + nil, + nil, + ).(*providertypes.ConsumerAdditionProposal), + providertypes.NewConsumerAdditionProposal( + "title", "opt-in chain with at least one validator opted in", "chain5", clienttypes.NewHeight(3, 4), []byte{}, []byte{}, + now.Add(-time.Hour*1).UTC(), + "0.75", + 10, + "", + 10000, + 100000000000, + 100000000000, + 100000000000, + 0, + 0, + 0, + nil, + nil, + ).(*providertypes.ConsumerAdditionProposal), + providertypes.NewConsumerAdditionProposal( + "title", "opt-in chain with no validator opted in", "chain6", clienttypes.NewHeight(3, 4), []byte{}, []byte{}, + now.Add(-time.Minute).UTC(), + "0.75", + 10, + "", + 10000, + 100000000000, + 100000000000, + 100000000000, + 0, + 0, + 0, + nil, + nil, ).(*providertypes.ConsumerAdditionProposal), } - // Expect client creation for only for the 1st and second proposals (spawn time already passed and valid) - gomock.InOrder( - append(testkeeper.GetMocksForCreateConsumerClient(ctx, &mocks, "chain1", clienttypes.NewHeight(3, 4)), - testkeeper.GetMocksForCreateConsumerClient(ctx, &mocks, "chain2", clienttypes.NewHeight(3, 4))...)..., - ) + // Expect client creation for only the first, second, and fifth proposals (spawn time already passed and valid) + expectedCalls := testkeeper.GetMocksForCreateConsumerClient(ctx, &mocks, "chain1", clienttypes.NewHeight(3, 4)) + expectedCalls = append(expectedCalls, testkeeper.GetMocksForCreateConsumerClient(ctx, &mocks, "chain2", clienttypes.NewHeight(3, 4))...) + expectedCalls = append(expectedCalls, testkeeper.GetMocksForCreateConsumerClient(ctx, &mocks, "chain5", clienttypes.NewHeight(3, 4))...) + + // The sixth proposal would have spawn time passed and hence needs the mocks but the client will not be + // created because `chain6` is an Opt In chain and has no validator opted in + expectedCalls = append(expectedCalls, testkeeper.GetMocksForCreateConsumerClient(ctx, &mocks, "chain6", clienttypes.NewHeight(3, 4))...) + + gomock.InOrder(expectedCalls...) for _, prop := range pendingProps { providerKeeper.SetPendingConsumerAdditionProp(ctx, prop) } + // opt in a sample validator so the chain's proposal can successfully execute + validator := cryptotestutil.NewCryptoIdentityFromIntSeed(0).SDKStakingValidator() + consAddr, _ := validator.GetConsAddr() + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 1, []stakingtypes.Validator{validator}, []int64{0}, -1) // -1 to allow any number of calls + + valAddr, _ := sdk.ValAddressFromBech32(validator.GetOperator()) + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(gomock.Any(), valAddr).Return(int64(1), nil).AnyTimes() + providerKeeper.SetOptedIn(ctx, pendingProps[4].ChainId, providertypes.NewProviderConsAddress(consAddr)) + providerKeeper.BeginBlockInit(ctx) - // Only the third proposal is still stored as pending + // first proposal is not pending anymore because its spawn time already passed and was executed _, found := providerKeeper.GetPendingConsumerAdditionProp( ctx, pendingProps[0].SpawnTime, pendingProps[0].ChainId) require.False(t, found) + // first proposal was successfully executed and hence consumer genesis was created + _, found = providerKeeper.GetConsumerGenesis(ctx, pendingProps[0].ChainId) + require.True(t, found) + // second proposal is not pending anymore because its spawn time already passed and was executed _, found = providerKeeper.GetPendingConsumerAdditionProp( ctx, pendingProps[1].SpawnTime, pendingProps[1].ChainId) require.False(t, found) + // second proposal was successfully executed and hence consumer genesis was created + _, found = providerKeeper.GetConsumerGenesis(ctx, pendingProps[1].ChainId) + require.True(t, found) + // third proposal is still stored as pending because its spawn time has not passed _, found = providerKeeper.GetPendingConsumerAdditionProp( ctx, pendingProps[2].SpawnTime, pendingProps[2].ChainId) require.True(t, found) + // because the proposal is still pending, no consumer genesis was created + _, found = providerKeeper.GetConsumerGenesis(ctx, pendingProps[2].ChainId) + require.False(t, found) - // check that the invalid proposal was dropped + // check that the invalid proposals were dropped _, found = providerKeeper.GetPendingConsumerAdditionProp( ctx, pendingProps[3].SpawnTime, pendingProps[3].ChainId) require.False(t, found) + // Note that we do not check that `GetConsumerGenesis(ctx, pendingProps[3].ChainId)` returns `false` here because + // `pendingProps[3]` is an invalid proposal due to the chain id already existing so the consumer genesis also exists + + // fifth proposal corresponds to an Opt-In chain with one opted-in validator and hence the proposal gets + // successfully executed + _, found = providerKeeper.GetPendingConsumerAdditionProp( + ctx, pendingProps[4].SpawnTime, pendingProps[4].ChainId) + require.False(t, found) + // fifth proposal was successfully executed and hence consumer genesis was created + _, found = providerKeeper.GetConsumerGenesis(ctx, pendingProps[4].ChainId) + require.True(t, found) + + // sixth proposal corresponds to an Opt-In chain with no opted-in validators and hence the + // proposal is not successful + _, found = providerKeeper.GetPendingConsumerAdditionProp( + ctx, pendingProps[5].SpawnTime, pendingProps[5].ChainId) + // the proposal was dropped and deleted + require.False(t, found) + // no consumer genesis is created + _, found = providerKeeper.GetConsumerGenesis(ctx, pendingProps[5].ChainId) + require.False(t, found) + // no consumer client is associated with this chain + _, found = providerKeeper.GetConsumerClientId(ctx, pendingProps[5].ChainId) + require.False(t, found) + // no fields should be set for this (check some of them) + _, found = providerKeeper.GetTopN(ctx, pendingProps[5].ChainId) + require.False(t, found) + _, found = providerKeeper.GetValidatorsPowerCap(ctx, pendingProps[5].ChainId) + require.False(t, found) + _, found = providerKeeper.GetValidatorSetCap(ctx, pendingProps[5].ChainId) + require.False(t, found) + + // test that Top N is set correctly + require.True(t, providerKeeper.IsTopN(ctx, "chain1")) + topN, found := providerKeeper.GetTopN(ctx, "chain1") + require.True(t, found) + require.Equal(t, uint32(50), topN) + + require.True(t, providerKeeper.IsOptIn(ctx, "chain4")) } // TestBeginBlockCCR tests BeginBlockCCR against the spec. @@ -787,6 +1019,7 @@ func TestBeginBlockCCR(t *testing.T) { expectations := []*gomock.Call{} for _, prop := range pendingProps { // A consumer chain is setup corresponding to each prop, making these mocks necessary + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 0, []stakingtypes.Validator{}, []int64{}, 1) expectations = append(expectations, testkeeper.GetMocksForCreateConsumerClient(ctx, &mocks, prop.ChainId, clienttypes.NewHeight(2, 3))...) expectations = append(expectations, testkeeper.GetMocksForSetConsumerChain(ctx, &mocks, prop.ChainId)...) @@ -805,6 +1038,7 @@ func TestBeginBlockCCR(t *testing.T) { additionProp := testkeeper.GetTestConsumerAdditionProp() additionProp.ChainId = prop.ChainId additionProp.InitialHeight = clienttypes.NewHeight(2, 3) + err := providerKeeper.CreateConsumerClient(ctx, additionProp) require.NoError(t, err) err = providerKeeper.SetConsumerChain(ctx, "channelID") @@ -823,6 +1057,7 @@ func TestBeginBlockCCR(t *testing.T) { // // Test execution // + providerKeeper.BeginBlockCCR(ctx) // Only the 3rd (final) proposal is still stored as pending diff --git a/x/ccv/provider/keeper/relay.go b/x/ccv/provider/keeper/relay.go index 7dcf568a5f..6373e6a7ce 100644 --- a/x/ccv/provider/keeper/relay.go +++ b/x/ccv/provider/keeper/relay.go @@ -167,10 +167,10 @@ func (k Keeper) EndBlockVSU(ctx sdk.Context) { // If the CCV channel is not established for a consumer chain, // the updates will remain queued until the channel is established func (k Keeper) SendVSCPackets(ctx sdk.Context) { - for _, chain := range k.GetAllConsumerChains(ctx) { + for _, chainID := range k.GetAllRegisteredConsumerChainIDs(ctx) { // check if CCV channel is established and send - if channelID, found := k.GetChainToChannel(ctx, chain.ChainId); found { - k.SendVSCPacketsToChain(ctx, chain.ChainId, channelID) + if channelID, found := k.GetChainToChannel(ctx, chainID); found { + k.SendVSCPacketsToChain(ctx, chainID, channelID) } } } @@ -216,31 +216,50 @@ func (k Keeper) SendVSCPacketsToChain(ctx sdk.Context, chainID, channelID string // QueueVSCPackets queues latest validator updates for every registered consumer chain // failing to GetLastValidators will cause a panic in EndBlock + +// TODO: decide if this func shouldn't return an error to be propagated to BeginBlocker func (k Keeper) QueueVSCPackets(ctx sdk.Context) { valUpdateID := k.GetValidatorSetUpdateId(ctx) // current valset update ID // get the bonded validators from the staking module - bondedValidators, err := k.stakingKeeper.GetLastValidators(ctx) + bondedValidators, err := k.GetLastBondedValidators(ctx) if err != nil { panic(fmt.Errorf("failed to get last validators: %w", err)) } - for _, chain := range k.GetAllConsumerChains(ctx) { - currentValidators := k.GetConsumerValSet(ctx, chain.ChainId) - nextValidators := k.ComputeNextEpochConsumerValSet(ctx, chain.ChainId, bondedValidators) + for _, chainID := range k.GetAllRegisteredConsumerChainIDs(ctx) { + currentValidators := k.GetConsumerValSet(ctx, chainID) + topN, _ := k.GetTopN(ctx, chainID) + + if topN > 0 { + // in a Top-N chain, we automatically opt in all validators that belong to the top N + minPower, err := k.ComputeMinPowerInTopN(ctx, bondedValidators, topN) + if err == nil { + // set the minimal power of validators in the top N in the store + k.SetMinimumPowerInTopN(ctx, chainID, minPower) + + k.OptInTopNValidators(ctx, chainID, bondedValidators, minPower) + } else { + // we just log here and do not panic because panic-ing would halt the provider chain + k.Logger(ctx).Error("failed to compute min power to opt in for chain", "chain", chainID, "error", err) + } + } + + nextValidators := k.ComputeNextValidators(ctx, chainID, bondedValidators) + valUpdates := DiffValidators(currentValidators, nextValidators) - k.SetConsumerValSet(ctx, chain.ChainId, nextValidators) + k.SetConsumerValSet(ctx, chainID, nextValidators) // check whether there are changes in the validator set; // note that this also entails unbonding operations // w/o changes in the voting power of the validators in the validator set - unbondingOps := k.GetUnbondingOpsFromIndex(ctx, chain.ChainId, valUpdateID) + unbondingOps := k.GetUnbondingOpsFromIndex(ctx, chainID, valUpdateID) if len(valUpdates) != 0 || len(unbondingOps) != 0 { // construct validator set change packet data - packet := ccv.NewValidatorSetChangePacketData(valUpdates, valUpdateID, k.ConsumeSlashAcks(ctx, chain.ChainId)) - k.AppendPendingVSCPackets(ctx, chain.ChainId, packet) + packet := ccv.NewValidatorSetChangePacketData(valUpdates, valUpdateID, k.ConsumeSlashAcks(ctx, chainID)) + k.AppendPendingVSCPackets(ctx, chainID, packet) k.Logger(ctx).Info("VSCPacket enqueued:", - "chainID", chain.ChainId, + "chainID", chainID, "vscID", valUpdateID, "len updates", len(valUpdates), "len unbonding ops", len(unbondingOps), @@ -333,6 +352,16 @@ func (k Keeper) OnRecvSlashPacket( return ccv.V1Result, nil } + // Check that the validator belongs to the consumer chain valset + if !k.IsConsumerValidator(ctx, chainID, providerConsAddr) { + k.Logger(ctx).Error("cannot jail validator %s that does not belong to consumer %s valset", + providerConsAddr.String(), chainID) + // drop packet but return a slash ack so that the consumer can send another slash packet + k.AppendSlashAck(ctx, chainID, consumerConsAddr.String()) + + return ccv.SlashPacketHandledResult, nil + } + meter := k.GetSlashMeter(ctx) // Return bounce ack if meter is negative in value if meter.IsNegative() { @@ -440,7 +469,11 @@ func (k Keeper) HandleSlashPacket(ctx sdk.Context, chainID string, data ccv.Slas // jail validator if !validator.IsJailed() { - k.stakingKeeper.Jail(ctx, providerConsAddr.ToSdkConsAddr()) + err := k.stakingKeeper.Jail(ctx, providerConsAddr.ToSdkConsAddr()) + if err != nil { + k.Logger(ctx).Error("failed to jail vaidator", providerConsAddr.ToSdkConsAddr().String(), "err", err.Error()) + return + } k.Logger(ctx).Info("validator jailed", "provider cons addr", providerConsAddr.String()) jailDuration, err := k.slashingKeeper.DowntimeJailDuration(ctx) if err != nil { @@ -448,7 +481,11 @@ func (k Keeper) HandleSlashPacket(ctx sdk.Context, chainID string, data ccv.Slas return } jailEndTime := ctx.BlockTime().Add(jailDuration) - k.slashingKeeper.JailUntil(ctx, providerConsAddr.ToSdkConsAddr(), jailEndTime) + err = k.slashingKeeper.JailUntil(ctx, providerConsAddr.ToSdkConsAddr(), jailEndTime) + if err != nil { + k.Logger(ctx).Error("failed to set jail duration", "err", err.Error()) + return + } } ctx.EventManager().EmitEvent( diff --git a/x/ccv/provider/keeper/relay_test.go b/x/ccv/provider/keeper/relay_test.go index 5b11e44d33..b6487e8ec1 100644 --- a/x/ccv/provider/keeper/relay_test.go +++ b/x/ccv/provider/keeper/relay_test.go @@ -11,15 +11,19 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" abci "github.com/cometbft/cometbft/abci/types" + "github.com/cosmos/interchain-security/v5/testutil/crypto" cryptotestutil "github.com/cosmos/interchain-security/v5/testutil/crypto" testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) @@ -65,18 +69,7 @@ func TestQueueVSCPackets(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mocks := testkeeper.NewMockedKeepers(ctrl) - // TODO: remove this after main merge - // mockStakingKeeper := mocks.MockStakingKeeper - - // mockUpdates := []abci.ValidatorUpdate{} - // if len(tc.packets) != 0 { - // mockUpdates = tc.packets[0].ValidatorUpdates - // } - - // gomock.InOrder( - // mockStakingKeeper.EXPECT().GetValidatorUpdates(gomock.Eq(ctx)).Return(mockUpdates, nil), - // ) - mocks.MockStakingKeeper.EXPECT().GetLastValidators(ctx).Times(1) + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 0, []stakingtypes.Validator{}, []int64{}, 1) pk := testkeeper.NewInMemProviderKeeper(keeperParams, mocks) // no-op if tc.packets is empty @@ -93,6 +86,55 @@ func TestQueueVSCPackets(t *testing.T) { } } +// TestQueueVSCPacketsDoesNotResetConsumerValidatorsHeights checks that the heights of consumer validators are not +// getting incorrectly updated +func TestQueueVSCPacketsDoesNotResetConsumerValidatorsHeights(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + chainHeight := int64(987654321) + ctx = ctx.WithBlockHeight(chainHeight) + providerKeeper.SetParams(ctx, providertypes.DefaultParams()) + + // mock 2 bonded validators + valA := createStakingValidator(ctx, mocks, 1, 1, 1) + valAConsAddr, _ := valA.GetConsAddr() + valAPubKey, _ := valA.TmConsPublicKey() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valAConsAddr).Return(valA, nil).AnyTimes() + valB := createStakingValidator(ctx, mocks, 2, 2, 2) + valBConsAddr, _ := valB.GetConsAddr() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valBConsAddr).Return(valB, nil).AnyTimes() + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 2, []stakingtypes.Validator{valA, valB}, []int64{1, 2}, -1) + + // set a consumer client, so we have a consumer chain (i.e., `k.GetAllConsumerChains(ctx)` is non empty) + providerKeeper.SetConsumerClientId(ctx, "chainID", "clientID") + + // opt in validator A and set as a consumer validator + providerKeeper.SetOptedIn(ctx, "chainID", providertypes.NewProviderConsAddress(valAConsAddr)) + consumerValidatorA := types.ConsumerValidator{ + ProviderConsAddr: valAConsAddr, + Power: 1, + ConsumerPublicKey: &valAPubKey, + JoinHeight: 123456789, + } + providerKeeper.SetConsumerValidator(ctx, "chainID", consumerValidatorA) + + // Opt in validator B. Note that validator B is not a consumer validator and hence would become a consumer + // validator for the first time after the `QueueVSCPackets` call. + providerKeeper.SetOptedIn(ctx, "chainID", providertypes.NewProviderConsAddress(valBConsAddr)) + + providerKeeper.QueueVSCPackets(ctx) + + // the height of consumer validator A should not be modified because A was already a consumer validator + cv, _ := providerKeeper.GetConsumerValidator(ctx, "chainID", providertypes.NewProviderConsAddress(valAConsAddr)) + require.Equal(t, consumerValidatorA.JoinHeight, cv.JoinHeight, "the consumer validator's height was erroneously modified") + + // the height of consumer validator B is set to be the same as the one of the current chain height because this + // consumer validator becomes a consumer validator for the first time (i.e., was not a consumer validator in the previous epoch) + cv, _ = providerKeeper.GetConsumerValidator(ctx, "chainID", providertypes.NewProviderConsAddress(valBConsAddr)) + require.Equal(t, chainHeight, cv.JoinHeight, "the consumer validator's height was not correctly set") +} + // TestOnRecvVSCMaturedPacket tests the OnRecvVSCMaturedPacket method of the keeper. // // Note: Handling logic itself is not tested here. @@ -131,12 +173,22 @@ func TestOnRecvDowntimeSlashPacket(t *testing.T) { // Set a block height for the valset update id in the generated packet data providerKeeper.SetValsetUpdateBlockHeight(ctx, packetData.ValsetUpdateId, uint64(15)) + // Set consumer validator + providerKeeper.SetConsumerValidator(ctx, "chain-1", providertypes.ConsumerValidator{ + ProviderConsAddr: packetData.Validator.Address, + }) + // Set slash meter to negative value and assert a bounce ack is returned providerKeeper.SetSlashMeter(ctx, math.NewInt(-5)) ackResult, err := executeOnRecvSlashPacket(t, &providerKeeper, ctx, "channel-1", 1, packetData) require.Equal(t, ccv.SlashPacketBouncedResult, ackResult) require.NoError(t, err) + // Set consumer validator + providerKeeper.SetConsumerValidator(ctx, "chain-2", providertypes.ConsumerValidator{ + ProviderConsAddr: packetData.Validator.Address, + }) + // Also bounced for chain-2 ackResult, err = executeOnRecvSlashPacket(t, &providerKeeper, ctx, "channel-2", 2, packetData) require.Equal(t, ccv.SlashPacketBouncedResult, ackResult) @@ -145,6 +197,9 @@ func TestOnRecvDowntimeSlashPacket(t *testing.T) { // Now set slash meter to positive value and assert slash packet handled result is returned providerKeeper.SetSlashMeter(ctx, math.NewInt(5)) + // Set the consumer validator + providerKeeper.SetConsumerValidator(ctx, "chain-1", providertypes.ConsumerValidator{ProviderConsAddr: packetData.Validator.Address}) + // Mock call to GetEffectiveValPower, so that it returns 2. providerAddr := providertypes.NewProviderConsAddress(packetData.Validator.Address) calls := []*gomock.Call{ @@ -302,6 +357,7 @@ func TestValidateSlashPacket(t *testing.T) { func TestHandleSlashPacket(t *testing.T) { chainId := "consumer-id" validVscID := uint64(234) + providerConsAddr := cryptotestutil.NewCryptoIdentityFromIntSeed(7842334).ProviderConsAddress() consumerConsAddr := cryptotestutil.NewCryptoIdentityFromIntSeed(784987634).ConsumerConsAddress() @@ -309,8 +365,9 @@ func TestHandleSlashPacket(t *testing.T) { name string packetData ccv.SlashPacketData // The mocks that we expect to be called for the specified packet data. - expectedCalls func(sdk.Context, testkeeper.MockedKeepers, ccv.SlashPacketData) []*gomock.Call - expectedSlashAcksLen int + expectedCalls func(sdk.Context, testkeeper.MockedKeepers, ccv.SlashPacketData) []*gomock.Call + expectedSlashAcksLen int + expectedSlashAckConsumerConsAddress providertypes.ConsumerConsAddress }{ { "unfound validator", @@ -332,6 +389,7 @@ func TestHandleSlashPacket(t *testing.T) { } }, 0, + consumerConsAddr, }, { "found, but tombstoned validator", @@ -354,6 +412,7 @@ func TestHandleSlashPacket(t *testing.T) { } }, 0, + consumerConsAddr, }, { "drop packet when infraction height not found", @@ -377,6 +436,7 @@ func TestHandleSlashPacket(t *testing.T) { } }, 0, + consumerConsAddr, }, { "full downtime packet handling, uses init chain height and non-jailed validator", @@ -394,6 +454,7 @@ func TestHandleSlashPacket(t *testing.T) { true) // expectJailing = true }, 1, + consumerConsAddr, }, { "full downtime packet handling, uses valid vscID and jailed validator", @@ -411,39 +472,42 @@ func TestHandleSlashPacket(t *testing.T) { false) // expectJailing = false, validator is already jailed. }, 1, + consumerConsAddr, }, // Note: double-sign slash packet handling should not occur, see OnRecvSlashPacket. } for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx( + t, testkeeper.NewInMemKeeperParams(t)) - providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx( - t, testkeeper.NewInMemKeeperParams(t)) + // Setup expected mock calls + gomock.InOrder(tc.expectedCalls(ctx, mocks, tc.packetData)...) - // Setup expected mock calls - gomock.InOrder(tc.expectedCalls(ctx, mocks, tc.packetData)...) + // Setup init chain height and a single valid valset update ID to block height mapping. + providerKeeper.SetInitChainHeight(ctx, chainId, 5) + providerKeeper.SetValsetUpdateBlockHeight(ctx, validVscID, 99) - // Setup init chain height and a single valid valset update ID to block height mapping. - providerKeeper.SetInitChainHeight(ctx, chainId, 5) - providerKeeper.SetValsetUpdateBlockHeight(ctx, validVscID, 99) + // Setup consumer address to provider address mapping. + require.NotEmpty(t, tc.packetData.Validator.Address) + providerKeeper.SetValidatorByConsumerAddr(ctx, chainId, consumerConsAddr, providerConsAddr) + providerKeeper.SetConsumerValidator(ctx, chainId, providertypes.ConsumerValidator{ProviderConsAddr: providerConsAddr.Address.Bytes()}) - // Setup consumer address to provider address mapping. - require.NotEmpty(t, tc.packetData.Validator.Address) - providerKeeper.SetValidatorByConsumerAddr(ctx, chainId, consumerConsAddr, providerConsAddr) + // Execute method and assert expected mock calls. + providerKeeper.HandleSlashPacket(ctx, chainId, tc.packetData) - // Execute method and assert expected mock calls. - providerKeeper.HandleSlashPacket(ctx, chainId, tc.packetData) + require.Equal(t, tc.expectedSlashAcksLen, len(providerKeeper.GetSlashAcks(ctx, chainId))) - require.Equal(t, tc.expectedSlashAcksLen, len(providerKeeper.GetSlashAcks(ctx, chainId))) + if tc.expectedSlashAcksLen == 1 { + // must match the consumer address + require.Equal(t, tc.expectedSlashAckConsumerConsAddress.String(), providerKeeper.GetSlashAcks(ctx, chainId)[0]) + require.NotEqual(t, providerConsAddr.String(), providerKeeper.GetSlashAcks(ctx, chainId)[0]) + require.NotEqual(t, providerConsAddr.String(), consumerConsAddr.String()) + } - if tc.expectedSlashAcksLen == 1 { - // must match the consumer address - require.Equal(t, consumerConsAddr.String(), providerKeeper.GetSlashAcks(ctx, chainId)[0]) - require.NotEqual(t, providerConsAddr.String(), providerKeeper.GetSlashAcks(ctx, chainId)[0]) - require.NotEqual(t, providerConsAddr.String(), consumerConsAddr.String()) - } - - ctrl.Finish() + ctrl.Finish() + }) } } @@ -458,6 +522,10 @@ func TestHandleVSCMaturedPacket(t *testing.T) { // Start first unbonding without any consumers registered var unbondingOpId uint64 = 1 + gomock.InOrder( + mocks.MockStakingKeeper.EXPECT().GetUnbondingType(ctx, unbondingOpId).Return(stakingtypes.UnbondingType_Undefined, stakingtypes.ErrNoUnbondingType), + ) + err := pk.Hooks().AfterUnbondingInitiated(ctx, unbondingOpId) require.NoError(t, err) // Check that no unbonding op was stored @@ -468,12 +536,34 @@ func TestHandleVSCMaturedPacket(t *testing.T) { pk.IncrementValidatorSetUpdateId(ctx) require.Equal(t, uint64(2), pk.GetValidatorSetUpdateId(ctx)) - // Registered first consumer + // Register first consumer pk.SetConsumerClientId(ctx, "chain-1", "client-1") + // Create 2 validators + vals := []stakingtypes.Validator{} + valsPk := []cryptotypes.PubKey{} + for i := 0; i < 2; i++ { + pubkey, err := cryptocodec.FromTmPubKeyInterface(cryptotestutil.NewCryptoIdentityFromIntSeed(54321 + i).TMCryptoPubKey()) + require.NoError(t, err) + valsPk = append(valsPk, pubkey) + pkAny, err := codectypes.NewAnyWithValue(pubkey) + require.NoError(t, err) + vals = append(vals, stakingtypes.Validator{ConsensusPubkey: pkAny}) + } + + // Opt-in one validator to consumer + pk.SetConsumerValidator(ctx, "chain-1", providertypes.ConsumerValidator{ProviderConsAddr: valsPk[0].Address()}) + // Start second unbonding unbondingOpId = 2 gomock.InOrder( + mocks.MockStakingKeeper.EXPECT().GetUnbondingType(ctx, unbondingOpId).Return(stakingtypes.UnbondingType_UnbondingDelegation, nil), + mocks.MockStakingKeeper.EXPECT().GetUnbondingDelegationByUnbondingID(ctx, unbondingOpId).Return( + stakingtypes.UnbondingDelegation{ + ValidatorAddress: sdk.ValAddress([]byte{1}).String(), + }, nil), + mocks.MockStakingKeeper.EXPECT().GetValidator(ctx, sdk.ValAddress([]byte{1})). + Return(vals[0], nil), mocks.MockStakingKeeper.EXPECT().PutUnbondingOnHold(ctx, unbondingOpId).Return(nil), ) err = pk.Hooks().AfterUnbondingInitiated(ctx, unbondingOpId) @@ -497,10 +587,21 @@ func TestHandleVSCMaturedPacket(t *testing.T) { // Registered second consumer pk.SetConsumerClientId(ctx, "chain-2", "client-2") + // Opt-in both validators to second consumer + pk.SetConsumerValidator(ctx, "chain-2", providertypes.ConsumerValidator{ProviderConsAddr: valsPk[0].Address()}) + pk.SetConsumerValidator(ctx, "chain-2", providertypes.ConsumerValidator{ProviderConsAddr: valsPk[1].Address()}) + // Start third and fourth unbonding unbondingOpIds := []uint64{3, 4} for _, id := range unbondingOpIds { gomock.InOrder( + mocks.MockStakingKeeper.EXPECT().GetUnbondingType(ctx, id).Return(stakingtypes.UnbondingType_Redelegation, nil), + mocks.MockStakingKeeper.EXPECT().GetRedelegationByUnbondingID(ctx, id).Return( + stakingtypes.Redelegation{ + ValidatorSrcAddress: sdk.ValAddress([]byte{1}).String(), + }, nil), + mocks.MockStakingKeeper.EXPECT().GetValidator(ctx, sdk.ValAddress([]byte{1})). + Return(vals[0], nil), mocks.MockStakingKeeper.EXPECT().PutUnbondingOnHold(ctx, id).Return(nil), ) err = pk.Hooks().AfterUnbondingInitiated(ctx, id) @@ -521,6 +622,33 @@ func TestHandleVSCMaturedPacket(t *testing.T) { require.Equal(t, unbondingOpIds, ids) } + // Increment vscID + pk.IncrementValidatorSetUpdateId(ctx) + require.Equal(t, uint64(4), pk.GetValidatorSetUpdateId(ctx)) + + // Start fith unbonding + unbondingOpId = 5 + gomock.InOrder( + mocks.MockStakingKeeper.EXPECT().GetUnbondingType(ctx, unbondingOpId).Return(stakingtypes.UnbondingType_ValidatorUnbonding, nil), + mocks.MockStakingKeeper.EXPECT().GetValidatorByUnbondingID(ctx, unbondingOpId).Return( + stakingtypes.Validator{ + OperatorAddress: sdk.ValAddress([]byte{1}).String(), + }, nil), + mocks.MockStakingKeeper.EXPECT().GetValidator(ctx, sdk.ValAddress([]byte{1})). + Return(vals[1], nil), + mocks.MockStakingKeeper.EXPECT().PutUnbondingOnHold(ctx, unbondingOpId).Return(nil), + ) + err = pk.Hooks().AfterUnbondingInitiated(ctx, unbondingOpId) + require.NoError(t, err) + + // Check that an unbonding op was stored for chain-2 only + // since it's the only consumer the unbonding validator has opted-in to + expectedChains = []string{"chain-2"} + unbondingOp, found = pk.GetUnbondingOp(ctx, unbondingOpId) + require.True(t, found) + require.Equal(t, unbondingOpId, unbondingOp.Id) + require.Equal(t, expectedChains, unbondingOp.UnbondingConsumerChains) + // Handle VSCMatured packet from chain-1 for vscID 1. // Note that no VSCPacket was sent as the chain was not yet registered, // but the code should still work @@ -672,6 +800,10 @@ func TestEndBlockVSU(t *testing.T) { providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() + chainID := "chainID" + + providerKeeper.SetTopN(ctx, chainID, 100) + // 10 blocks constitute an epoch params := providertypes.DefaultParams() params.BlocksPerEpoch = 10 @@ -679,34 +811,118 @@ func TestEndBlockVSU(t *testing.T) { // create 4 sample lastValidators var lastValidators []stakingtypes.Validator + var powers []int64 for i := 0; i < 4; i++ { - lastValidators = append(lastValidators, cryptotestutil.NewCryptoIdentityFromIntSeed(i).SDKStakingValidator()) + validator := crypto.NewCryptoIdentityFromIntSeed(i).SDKStakingValidator() + lastValidators = append(lastValidators, validator) + valAdrr, err := sdk.ValAddressFromBech32(validator.GetOperator()) + require.NoError(t, err) + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(gomock.Any(), valAdrr).Return(int64(i+1), nil).AnyTimes() + powers = append(powers, int64(i+1)) } - mocks.MockStakingKeeper.EXPECT().GetLastValidators(gomock.Any()).Return(lastValidators, nil).AnyTimes() - mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(gomock.Any(), gomock.Any()).Return(int64(2), nil).AnyTimes() + + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 5, lastValidators, powers, -1) // set a sample client for a consumer chain so that `GetAllConsumerChains` in `QueueVSCPackets` iterates at least once - providerKeeper.SetConsumerClientId(ctx, "chainID", "clientID") + providerKeeper.SetConsumerClientId(ctx, chainID, "clientID") // with block height of 1 we do not expect any queueing of VSC packets ctx = ctx.WithBlockHeight(1) providerKeeper.EndBlockVSU(ctx) - require.Equal(t, 0, len(providerKeeper.GetPendingVSCPackets(ctx, "chainID"))) + require.Equal(t, 0, len(providerKeeper.GetPendingVSCPackets(ctx, chainID))) // with block height of 5 we do not expect any queueing of VSC packets ctx = ctx.WithBlockHeight(5) providerKeeper.EndBlockVSU(ctx) - require.Equal(t, 0, len(providerKeeper.GetPendingVSCPackets(ctx, "chainID"))) + require.Equal(t, 0, len(providerKeeper.GetPendingVSCPackets(ctx, chainID))) // with block height of 10 we expect the queueing of one VSC packet ctx = ctx.WithBlockHeight(10) providerKeeper.EndBlockVSU(ctx) - require.Equal(t, 1, len(providerKeeper.GetPendingVSCPackets(ctx, "chainID"))) + require.Equal(t, 1, len(providerKeeper.GetPendingVSCPackets(ctx, chainID))) // With block height of 15 we expect no additional queueing of a VSC packet. // Note that the pending VSC packet is still there because `SendVSCPackets` does not send the packet. We // need to mock channels, etc. for this to work, and it's out of scope for this test. ctx = ctx.WithBlockHeight(15) providerKeeper.EndBlockVSU(ctx) - require.Equal(t, 1, len(providerKeeper.GetPendingVSCPackets(ctx, "chainID"))) + require.Equal(t, 1, len(providerKeeper.GetPendingVSCPackets(ctx, chainID))) +} + +// TestQueueVSCPacketsWithPowerCapping tests queueing validator set updates with power capping +func TestQueueVSCPacketsWithPowerCapping(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerKeeper.SetValidatorSetUpdateId(ctx, 1) + + valA := createStakingValidator(ctx, mocks, 1, 1, 1) // 3.125% of the total voting power + valAConsAddr, _ := valA.GetConsAddr() + valAPubKey, _ := valA.TmConsPublicKey() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valAConsAddr).Return(valA, nil).AnyTimes() + valB := createStakingValidator(ctx, mocks, 2, 3, 2) // 9.375% of the total voting power + valBConsAddr, _ := valB.GetConsAddr() + valBPubKey, _ := valB.TmConsPublicKey() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valBConsAddr).Return(valB, nil).AnyTimes() + valC := createStakingValidator(ctx, mocks, 3, 4, 3) // 12.5% of the total voting power + valCConsAddr, _ := valC.GetConsAddr() + valCPubKey, _ := valC.TmConsPublicKey() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valCConsAddr).Return(valC, nil).AnyTimes() + valD := createStakingValidator(ctx, mocks, 4, 8, 4) // 25% of the total voting power + valDConsAddr, _ := valD.GetConsAddr() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valDConsAddr).Return(valD, nil).AnyTimes() + valE := createStakingValidator(ctx, mocks, 5, 16, 5) // 50% of the total voting power + valEConsAddr, _ := valE.GetConsAddr() + valEPubKey, _ := valE.TmConsPublicKey() + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, valEConsAddr).Return(valE, nil).AnyTimes() + + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 5, []stakingtypes.Validator{valA, valB, valC, valD, valE}, []int64{1, 3, 4, 8, 16}, -1) + + // add a consumer chain + providerKeeper.SetConsumerClientId(ctx, "chainID", "clientID") + + providerKeeper.SetTopN(ctx, "chainID", 50) // would opt in E + + // opt in all validators + providerKeeper.SetOptedIn(ctx, "chainID", providertypes.NewProviderConsAddress(valAConsAddr)) + providerKeeper.SetOptedIn(ctx, "chainID", providertypes.NewProviderConsAddress(valBConsAddr)) + providerKeeper.SetOptedIn(ctx, "chainID", providertypes.NewProviderConsAddress(valCConsAddr)) + providerKeeper.SetOptedIn(ctx, "chainID", providertypes.NewProviderConsAddress(valDConsAddr)) + + // denylist validator D + providerKeeper.SetDenylist(ctx, "chainID", providertypes.NewProviderConsAddress(valDConsAddr)) + + // set a power-capping of 40% + providerKeeper.SetValidatorsPowerCap(ctx, "chainID", 40) + + providerKeeper.QueueVSCPackets(ctx) + + actualQueuedVSCPackets := providerKeeper.GetPendingVSCPackets(ctx, "chainID") + expectedQueuedVSCPackets := []ccv.ValidatorSetChangePacketData{ + ccv.NewValidatorSetChangePacketData( + []abci.ValidatorUpdate{ + // validator D is not here because it was denylisted + // powers have changed because of power capping + { + PubKey: valEPubKey, + Power: 9, + }, + { + PubKey: valCPubKey, + Power: 6, + }, + { + PubKey: valBPubKey, + Power: 5, + }, + { + PubKey: valAPubKey, + Power: 4, + }, + }, + 1, + nil), + } + + require.Equal(t, expectedQueuedVSCPackets, actualQueuedVSCPackets) } diff --git a/x/ccv/provider/keeper/validator_set_update.go b/x/ccv/provider/keeper/validator_set_update.go index 8617d283cf..d7f764171e 100644 --- a/x/ccv/provider/keeper/validator_set_update.go +++ b/x/ccv/provider/keeper/validator_set_update.go @@ -10,6 +10,7 @@ import ( abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccv "github.com/cosmos/interchain-security/v5/x/ccv/types" ) // SetConsumerValidator sets provided consumer `validator` on the consumer chain with `chainID` @@ -27,6 +28,15 @@ func (k Keeper) SetConsumerValidator( store.Set(types.ConsumerValidatorKey(chainID, validator.ProviderConsAddr), bz) } +// SetConsumerValSet resets the current consumer validators with the `nextValidators` computed by +// `FilterValidators` and hence this method should only be called after `FilterValidators` has completed. +func (k Keeper) SetConsumerValSet(ctx sdk.Context, chainID string, nextValidators []types.ConsumerValidator) { + k.DeleteConsumerValSet(ctx, chainID) + for _, val := range nextValidators { + k.SetConsumerValidator(ctx, chainID, val) + } +} + // DeleteConsumerValidator removes consumer validator with `providerAddr` address func (k Keeper) DeleteConsumerValidator( ctx sdk.Context, @@ -58,15 +68,28 @@ func (k Keeper) DeleteConsumerValSet( // IsConsumerValidator returns `true` if the consumer validator with `providerAddr` exists for chain `chainID` // and `false` otherwise -func (k Keeper) IsConsumerValidator( - ctx sdk.Context, - chainID string, - providerAddr types.ProviderConsAddress, -) bool { +func (k Keeper) IsConsumerValidator(ctx sdk.Context, chainID string, providerAddr types.ProviderConsAddress) bool { store := ctx.KVStore(k.storeKey) return store.Get(types.ConsumerValidatorKey(chainID, providerAddr.ToSdkConsAddr())) != nil } +// GetConsumerValidator returns the consumer validator with `providerAddr` if it exists for chain `chainID` +func (k Keeper) GetConsumerValidator(ctx sdk.Context, chainID string, providerAddr types.ProviderConsAddress) (types.ConsumerValidator, bool) { + store := ctx.KVStore(k.storeKey) + marshalledConsumerValidator := store.Get(types.ConsumerValidatorKey(chainID, providerAddr.ToSdkConsAddr())) + + if marshalledConsumerValidator == nil { + return types.ConsumerValidator{}, false + } + + var validator types.ConsumerValidator + if err := validator.Unmarshal(marshalledConsumerValidator); err != nil { + panic(fmt.Errorf("failed to unmarshal ConsumerValidator: %w", err)) + } + + return validator, true +} + // GetConsumerValSet returns all the consumer validators for chain `chainID` func (k Keeper) GetConsumerValSet( ctx sdk.Context, @@ -89,58 +112,6 @@ func (k Keeper) GetConsumerValSet( return validators } -// ComputeNextEpochConsumerValSet returns the next validator set that is responsible for validating consumer -// chain `chainID`, based on the bonded validators. -func (k Keeper) ComputeNextEpochConsumerValSet( - ctx sdk.Context, - chainID string, - bondedValidators []stakingtypes.Validator, -) []types.ConsumerValidator { - var nextValidators []types.ConsumerValidator - for _, val := range bondedValidators { - valoper, err := k.ValidatorAddressCodec().StringToBytes(val.GetOperator()) - if err != nil { - panic(fmt.Errorf("could not decode validator operator: %w", err)) - } - // get next voting power and the next consumer public key - nextPower, err := k.stakingKeeper.GetLastValidatorPower(ctx, valoper) - if err != nil { - panic(fmt.Errorf("could not get last validator power: %w", err)) - } - consAddr, err := val.GetConsAddr() - if err != nil { - // this should never happen but is recoverable if we exclude this validator from the `nextValidators` - k.Logger(ctx).Error("could not get consensus address of validator", - "validator", val.GetOperator(), - "error", err) - continue - } - nextConsumerPublicKey, foundConsumerPublicKey := k.GetValidatorConsumerPubKey(ctx, chainID, types.NewProviderConsAddress(consAddr)) - if !foundConsumerPublicKey { - // if no consumer key assigned then use the validator's key itself - k.Logger(ctx).Info("could not retrieve public key for validator on consumer chain because"+ - " the validator did not assign a new consumer key", - "validator", val.GetOperator(), - "chainID", chainID) - nextConsumerPublicKey, err = val.CmtConsPublicKey() - if err != nil { - // this should never happen and might not be recoverable because without the public key - // we cannot generate a validator update - panic(fmt.Errorf("could not retrieve validator's (%+v) public key: %w", val, err)) - } - } - - nextValidator := types.ConsumerValidator{ - ProviderConsAddr: consAddr, - Power: nextPower, - ConsumerPublicKey: &nextConsumerPublicKey, - } - nextValidators = append(nextValidators, nextValidator) - } - - return nextValidators -} - // DiffValidators compares the current and the next epoch's consumer validators and returns the `ValidatorUpdate` diff // needed by CometBFT to update the validator set on a chain. func DiffValidators( @@ -149,12 +120,12 @@ func DiffValidators( ) []abci.ValidatorUpdate { var updates []abci.ValidatorUpdate - isCurrentValidator := make(map[string]types.ConsumerValidator) + isCurrentValidator := make(map[string]types.ConsumerValidator, len(currentValidators)) for _, val := range currentValidators { isCurrentValidator[val.ConsumerPublicKey.String()] = val } - isNextValidator := make(map[string]types.ConsumerValidator) + isNextValidator := make(map[string]types.ConsumerValidator, len(nextValidators)) for _, val := range nextValidators { isNextValidator[val.ConsumerPublicKey.String()] = val } @@ -182,11 +153,76 @@ func DiffValidators( return updates } -// SetConsumerValSet resets the current consumer validators with the `nextValidators` computed by -// `ComputeNextEpochConsumerValSet` and hence this method should only be called after `ComputeNextEpochConsumerValSet` has completed. -func (k Keeper) SetConsumerValSet(ctx sdk.Context, chainID string, nextValidators []types.ConsumerValidator) { - k.DeleteConsumerValSet(ctx, chainID) - for _, val := range nextValidators { - k.SetConsumerValidator(ctx, chainID, val) +// CreateConsumerValidator creates a consumer validator for `chainID` from the given staking `validator` +func (k Keeper) CreateConsumerValidator(ctx sdk.Context, chainID string, validator stakingtypes.Validator) (types.ConsumerValidator, error) { + valAddr, err := sdk.ValAddressFromBech32(validator.GetOperator()) + if err != nil { + return types.ConsumerValidator{}, err + } + power, err := k.stakingKeeper.GetLastValidatorPower(ctx, valAddr) + consAddr, err := validator.GetConsAddr() + if err != nil { + return types.ConsumerValidator{}, fmt.Errorf("could not retrieve validator's (%+v) consensus address: %w", + validator, err) } + + consumerPublicKey, foundConsumerPublicKey := k.GetValidatorConsumerPubKey(ctx, chainID, types.NewProviderConsAddress(consAddr)) + if !foundConsumerPublicKey { + consumerPublicKey, err = validator.TmConsPublicKey() + if err != nil { + return types.ConsumerValidator{}, fmt.Errorf("could not retrieve validator's (%+v) public key: %w", validator, err) + } + } + + height := ctx.BlockHeight() + if v, found := k.GetConsumerValidator(ctx, chainID, types.ProviderConsAddress{Address: consAddr}); found { + // if validator was already a consumer validator, then do not update the height set the first time + // the validator became a consumer validator + height = v.JoinHeight + } + + return types.ConsumerValidator{ + ProviderConsAddr: consAddr, + Power: power, + ConsumerPublicKey: &consumerPublicKey, + JoinHeight: height, + }, nil +} + +// FilterValidators filters the provided `bondedValidators` according to `predicate` and returns +// the filtered set. +func (k Keeper) FilterValidators( + ctx sdk.Context, + chainID string, + bondedValidators []stakingtypes.Validator, + predicate func(providerAddr types.ProviderConsAddress) bool, +) []types.ConsumerValidator { + var nextValidators []types.ConsumerValidator + for _, val := range bondedValidators { + consAddr, err := val.GetConsAddr() + if err != nil { + continue + } + + if predicate(types.NewProviderConsAddress(consAddr)) { + nextValidator, err := k.CreateConsumerValidator(ctx, chainID, val) + if err != nil { + // this should never happen but is recoverable if we exclude this validator from the next validator set + k.Logger(ctx).Error("could not create consumer validator", + "validator", val.GetOperator(), + "error", err) + continue + } + + nextValidators = append(nextValidators, nextValidator) + } + } + + return nextValidators +} + +// GetLastBondedValidators iterates the last validator powers in the staking module +// and returns the first MaxValidators many validators with the largest powers. +func (k Keeper) GetLastBondedValidators(ctx sdk.Context) ([]stakingtypes.Validator, error) { + return ccv.GetLastBondedValidatorsUtil(ctx, k.stakingKeeper, k.Logger(ctx)) } diff --git a/x/ccv/provider/keeper/validator_set_update_test.go b/x/ccv/provider/keeper/validator_set_update_test.go index 8808cf140d..43bc5a0370 100644 --- a/x/ccv/provider/keeper/validator_set_update_test.go +++ b/x/ccv/provider/keeper/validator_set_update_test.go @@ -13,7 +13,6 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" abci "github.com/cometbft/cometbft/abci/types" - "github.com/cometbft/cometbft/crypto/ed25519" "github.com/cometbft/cometbft/proto/tendermint/crypto" cryptotestutil "github.com/cosmos/interchain-security/v5/testutil/crypto" @@ -110,62 +109,23 @@ func createConsumerValidator(index int, power int64, seed int) (types.ConsumerVa }, publicKey } -func TestComputeNextEpochConsumerValSet(t *testing.T) { - providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - - chainID := "chainID" +// createStakingValidator helper function to generate a validator with the given power and with a provider address based on index +func createStakingValidator(ctx sdk.Context, mocks testkeeper.MockedKeepers, index int, power int64, seed int) stakingtypes.Validator { + providerConsPubKey := cryptotestutil.NewCryptoIdentityFromIntSeed(seed).TMProtoCryptoPublicKey() - // helper function to generate a validator with the given power and with a provider address based on index - createStakingValidator := func(ctx sdk.Context, mocks testkeeper.MockedKeepers, index int, power int64) stakingtypes.Validator { - providerConsPubKey := ed25519.GenPrivKeyFromSecret([]byte{byte(index)}).PubKey() - consAddr := sdk.ConsAddress(providerConsPubKey.Address()) - providerAddr := types.NewProviderConsAddress(consAddr) - pk, _ := cryptocodec.FromCmtPubKeyInterface(providerConsPubKey) - pkAny, _ := codectypes.NewAnyWithValue(pk) + pk, _ := cryptocodec.FromCmtProtoPublicKey(providerConsPubKey) + pkAny, _ := codectypes.NewAnyWithValue(pk) + consAddr := sdk.ConsAddress(pk.Address()) + providerAddr := types.NewProviderConsAddress(consAddr) + providerValidatorAddr := sdk.ValAddress(providerAddr.Address.Bytes()) - var providerValidatorAddr sdk.ValAddress = providerAddr.Address.Bytes() + mocks.MockStakingKeeper.EXPECT(). + GetLastValidatorPower(ctx, providerValidatorAddr).Return(power, nil).AnyTimes() - mocks.MockStakingKeeper.EXPECT(). - GetLastValidatorPower(ctx, providerValidatorAddr).Return(power, nil).AnyTimes() - - return stakingtypes.Validator{ - OperatorAddress: providerValidatorAddr.String(), - ConsensusPubkey: pkAny, - } + return stakingtypes.Validator{ + OperatorAddress: providerValidatorAddr.String(), + ConsensusPubkey: pkAny, } - - // no consumer validators returned if we have no bonded validators - require.Empty(t, providerKeeper.ComputeNextEpochConsumerValSet(ctx, chainID, []stakingtypes.Validator{})) - - var expectedValidators []types.ConsumerValidator - - // create a staking validator A that has not set a consumer public key - valA := createStakingValidator(ctx, mocks, 1, 1) - // because validator A has no consumer key set, the `ConsumerPublicKey` we expect is the key on the provider chain - valAConsAddr, _ := valA.GetConsAddr() - valAPublicKey, _ := valA.CmtConsPublicKey() - expectedValidators = append(expectedValidators, types.ConsumerValidator{ - ProviderConsAddr: types.NewProviderConsAddress(valAConsAddr).Address.Bytes(), - Power: 1, - ConsumerPublicKey: &valAPublicKey, - }) - - // create a staking validator B that has set a consumer public key - valB := createStakingValidator(ctx, mocks, 2, 2) - // validator B has set a consumer key, the `ConsumerPublicKey` we expect is the key set by `SetValidatorConsumerPubKey` - valBConsumerKey := cryptotestutil.NewCryptoIdentityFromIntSeed(1).TMProtoCryptoPublicKey() - valBConsAddr, _ := valB.GetConsAddr() - providerKeeper.SetValidatorConsumerPubKey(ctx, chainID, types.NewProviderConsAddress(valBConsAddr), valBConsumerKey) - expectedValidators = append(expectedValidators, types.ConsumerValidator{ - ProviderConsAddr: types.NewProviderConsAddress(valBConsAddr).Address.Bytes(), - Power: 2, - ConsumerPublicKey: &valBConsumerKey, - }) - - bondedValidators := []stakingtypes.Validator{valA, valB} - actualValidators := providerKeeper.ComputeNextEpochConsumerValSet(ctx, "chainID", bondedValidators) - require.Equal(t, expectedValidators, actualValidators) } func TestDiff(t *testing.T) { @@ -366,3 +326,153 @@ func TestSetConsumerValSet(t *testing.T) { sortValidators(nextCurrentValidators) require.Equal(t, nextValidators, nextCurrentValidators) } + +func TestFilterValidatorsConsiderAll(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + chainID := "chainID" + + // no consumer validators returned if we have no bonded validators + considerAll := func(providerAddr types.ProviderConsAddress) bool { return true } + require.Empty(t, providerKeeper.FilterValidators(ctx, chainID, []stakingtypes.Validator{}, considerAll)) + + var expectedValidators []types.ConsumerValidator + + // create a staking validator A that has not set a consumer public key + valA := createStakingValidator(ctx, mocks, 1, 1, 1) + // because validator A has no consumer key set, the `ConsumerPublicKey` we expect is the key on the provider chain + valAConsAddr, _ := valA.GetConsAddr() + valAPublicKey, _ := valA.TmConsPublicKey() + expectedValidators = append(expectedValidators, types.ConsumerValidator{ + ProviderConsAddr: types.NewProviderConsAddress(valAConsAddr).Address.Bytes(), + Power: 1, + ConsumerPublicKey: &valAPublicKey, + }) + + // create a staking validator B that has set a consumer public key + valB := createStakingValidator(ctx, mocks, 2, 2, 2) + // validator B has set a consumer key, the `ConsumerPublicKey` we expect is the key set by `SetValidatorConsumerPubKey` + valBConsumerKey := cryptotestutil.NewCryptoIdentityFromIntSeed(1).TMProtoCryptoPublicKey() + valBConsAddr, _ := valB.GetConsAddr() + providerKeeper.SetValidatorConsumerPubKey(ctx, chainID, types.NewProviderConsAddress(valBConsAddr), valBConsumerKey) + expectedValidators = append(expectedValidators, types.ConsumerValidator{ + ProviderConsAddr: types.NewProviderConsAddress(valBConsAddr).Address.Bytes(), + Power: 2, + ConsumerPublicKey: &valBConsumerKey, + }) + + bondedValidators := []stakingtypes.Validator{valA, valB} + actualValidators := providerKeeper.FilterValidators(ctx, chainID, bondedValidators, considerAll) + require.Equal(t, expectedValidators, actualValidators) +} + +func TestFilterValidatorsConsiderOnlyOptIn(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + chainID := "chainID" + + // no consumer validators returned if we have no opted-in validators + require.Empty(t, providerKeeper.FilterValidators(ctx, chainID, []stakingtypes.Validator{}, + func(providerAddr types.ProviderConsAddress) bool { + return providerKeeper.IsOptedIn(ctx, chainID, providerAddr) + })) + + var expectedValidators []types.ConsumerValidator + + // create a staking validator A that has not set a consumer public key + valA := createStakingValidator(ctx, mocks, 1, 1, 1) + // because validator A has no consumer key set, the `ConsumerPublicKey` we expect is the key on the provider chain + valAConsAddr, _ := valA.GetConsAddr() + valAPublicKey, _ := valA.TmConsPublicKey() + expectedValAConsumerValidator := types.ConsumerValidator{ + ProviderConsAddr: types.NewProviderConsAddress(valAConsAddr).Address.Bytes(), + Power: 1, + ConsumerPublicKey: &valAPublicKey, + } + expectedValidators = append(expectedValidators, expectedValAConsumerValidator) + + // create a staking validator B that has set a consumer public key + valB := createStakingValidator(ctx, mocks, 2, 2, 2) + // validator B has set a consumer key, the `ConsumerPublicKey` we expect is the key set by `SetValidatorConsumerPubKey` + valBConsumerKey := cryptotestutil.NewCryptoIdentityFromIntSeed(1).TMProtoCryptoPublicKey() + valBConsAddr, _ := valB.GetConsAddr() + providerKeeper.SetValidatorConsumerPubKey(ctx, chainID, types.NewProviderConsAddress(valBConsAddr), valBConsumerKey) + expectedValBConsumerValidator := types.ConsumerValidator{ + ProviderConsAddr: types.NewProviderConsAddress(valBConsAddr).Address.Bytes(), + Power: 2, + ConsumerPublicKey: &valBConsumerKey, + } + expectedValidators = append(expectedValidators, expectedValBConsumerValidator) + + // opt in validators A and B with 0 power and no consumer public keys + providerKeeper.SetOptedIn(ctx, chainID, types.NewProviderConsAddress(valAConsAddr)) + providerKeeper.SetOptedIn(ctx, chainID, types.NewProviderConsAddress(valBConsAddr)) + + // the expected actual validators are the opted-in validators but with the correct power and consumer public keys set + bondedValidators := []stakingtypes.Validator{valA, valB} + actualValidators := providerKeeper.FilterValidators(ctx, "chainID", bondedValidators, + func(providerAddr types.ProviderConsAddress) bool { + return providerKeeper.IsOptedIn(ctx, chainID, providerAddr) + }) + + // sort validators first to be able to compare + sortValidators := func(validators []types.ConsumerValidator) { + sort.Slice(validators, func(i, j int) bool { + return bytes.Compare(validators[i].ProviderConsAddr, validators[j].ProviderConsAddr) < 0 + }) + } + + sortValidators(actualValidators) + sortValidators(expectedValidators) + require.Equal(t, expectedValidators, actualValidators) + + // create a staking validator C that is not opted in, hence `expectedValidators` remains the same + valC := createStakingValidator(ctx, mocks, 3, 3, 3) + bondedValidators = []stakingtypes.Validator{valA, valB, valC} + actualValidators = providerKeeper.FilterValidators(ctx, "chainID", bondedValidators, + func(providerAddr types.ProviderConsAddress) bool { + return providerKeeper.IsOptedIn(ctx, chainID, providerAddr) + }) + + sortValidators(actualValidators) + sortValidators(expectedValidators) + require.Equal(t, expectedValidators, actualValidators) +} + +func TestCreateConsumerValidator(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + chainID := "chainID" + + // create a validator which has set a consumer public key + valA := createStakingValidator(ctx, mocks, 0, 1, 1) + valAConsumerKey := cryptotestutil.NewCryptoIdentityFromIntSeed(1).TMProtoCryptoPublicKey() + valAConsAddr, _ := valA.GetConsAddr() + valAProviderConsAddr := types.NewProviderConsAddress(valAConsAddr) + providerKeeper.SetValidatorConsumerPubKey(ctx, chainID, valAProviderConsAddr, valAConsumerKey) + actualConsumerValidatorA, err := providerKeeper.CreateConsumerValidator(ctx, chainID, valA) + expectedConsumerValidatorA := types.ConsumerValidator{ + ProviderConsAddr: valAProviderConsAddr.ToSdkConsAddr(), + Power: 1, + ConsumerPublicKey: &valAConsumerKey, + } + require.Equal(t, expectedConsumerValidatorA, actualConsumerValidatorA) + require.NoError(t, err) + + // create a validator which has not set a consumer public key + valB := createStakingValidator(ctx, mocks, 1, 2, 2) + valBConsAddr, _ := valB.GetConsAddr() + valBProviderConsAddr := types.NewProviderConsAddress(valBConsAddr) + valBPublicKey, _ := valB.TmConsPublicKey() + actualConsumerValidatorB, err := providerKeeper.CreateConsumerValidator(ctx, chainID, valB) + expectedConsumerValidatorB := types.ConsumerValidator{ + ProviderConsAddr: valBProviderConsAddr.ToSdkConsAddr(), + Power: 2, + ConsumerPublicKey: &valBPublicKey, + } + require.Equal(t, expectedConsumerValidatorB, actualConsumerValidatorB) + require.NoError(t, err) +} diff --git a/x/ccv/provider/migrations/migrator.go b/x/ccv/provider/migrations/migrator.go index 83812b6eb5..b031f9705b 100644 --- a/x/ccv/provider/migrations/migrator.go +++ b/x/ccv/provider/migrations/migrator.go @@ -10,6 +10,8 @@ import ( v3 "github.com/cosmos/interchain-security/v5/x/ccv/provider/migrations/v3" v4 "github.com/cosmos/interchain-security/v5/x/ccv/provider/migrations/v4" v5 "github.com/cosmos/interchain-security/v5/x/ccv/provider/migrations/v5" + v6 "github.com/cosmos/interchain-security/v5/x/ccv/provider/migrations/v6" + v7 "github.com/cosmos/interchain-security/v5/x/ccv/provider/migrations/v7" ) // Migrator is a struct for handling in-place store migrations. @@ -46,7 +48,22 @@ func (m Migrator) Migrate3to4(ctx sdktypes.Context) error { } // Migrate4to5 migrates x/ccvprovider state from consensus version 4 to 5. -// The migration consists of initializing new provider chain params using params from the legacy store. +// The migration consists of setting a top N of 95 for all registered consumer chains. func (m Migrator) Migrate4to5(ctx sdktypes.Context) error { - return v5.MigrateLegacyParams(ctx, m.providerKeeper, m.paramSpace) + v5.MigrateTopNForRegisteredChains(ctx, m.providerKeeper) + return nil +} + +// Migrate5to6 consists of setting the `NumberOfEpochsToStartReceivingRewards` param, as well as +// computing and storing the minimal power in the top N for all registered consumer chains. +func (m Migrator) Migrate5to6(ctx sdktypes.Context) error { + v6.MigrateParams(ctx, m.paramSpace) + v6.MigrateMinPowerInTopN(ctx, m.providerKeeper) + return nil +} + +// Migrate6to7 migrates x/ccvprovider state from consensus version 6 to 7. +// The migration consists of initializing new provider chain params using params from the legacy store. +func (m Migrator) Migrate6to7(ctx sdktypes.Context) error { + return v7.MigrateLegacyParams(ctx, m.providerKeeper, m.paramSpace) } diff --git a/x/ccv/provider/migrations/v3/migrations.go b/x/ccv/provider/migrations/v3/migrations.go index 2ffd1e6f25..8c17000b0b 100644 --- a/x/ccv/provider/migrations/v3/migrations.go +++ b/x/ccv/provider/migrations/v3/migrations.go @@ -11,15 +11,15 @@ import ( // MigrateQueuedPackets processes all queued packet data for all consumer chains that were stored // on the provider in the v2 consensus version (jail throttling v1). func MigrateQueuedPackets(ctx sdk.Context, k providerkeeper.Keeper) error { - for _, consumer := range k.GetAllConsumerChains(ctx) { - slashData, vscmData := k.LegacyGetAllThrottledPacketData(ctx, consumer.ChainId) + for _, consumerChainID := range k.GetAllRegisteredConsumerChainIDs(ctx) { + slashData, vscmData := k.LegacyGetAllThrottledPacketData(ctx, consumerChainID) if len(slashData) > 0 { k.Logger(ctx).Error(fmt.Sprintf("slash data being dropped: %v", slashData)) } for _, data := range vscmData { - k.HandleVSCMaturedPacket(ctx, consumer.ChainId, data) + k.HandleVSCMaturedPacket(ctx, consumerChainID, data) } - k.LegacyDeleteThrottledPacketDataForConsumer(ctx, consumer.ChainId) + k.LegacyDeleteThrottledPacketDataForConsumer(ctx, consumerChainID) } return nil } diff --git a/x/ccv/provider/migrations/v5/migrations.go b/x/ccv/provider/migrations/v5/migrations.go index f61428e48a..411efd49e1 100644 --- a/x/ccv/provider/migrations/v5/migrations.go +++ b/x/ccv/provider/migrations/v5/migrations.go @@ -4,19 +4,18 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" - ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) -// MigrateParams migrates the provider module's parameters from the x/params to self store. -func MigrateLegacyParams(ctx sdk.Context, keeper providerkeeper.Keeper, legacyParamspace ccvtypes.LegacyParamSubspace) error { - ctx.Logger().Info("starting provider legacy params migration") - params := GetParamsLegacy(ctx, legacyParamspace) - err := params.Validate() - if err != nil { - return err +// This migration only takes already registered chains into account. +// If a chain is in voting while the upgrade happens, this is not sufficient, +// and a migration to rewrite the proposal is needed. +func MigrateTopNForRegisteredChains(ctx sdk.Context, providerKeeper providerkeeper.Keeper) { + // Set the topN of each chain to 95 + for _, chainID := range providerKeeper.GetAllRegisteredConsumerChainIDs(ctx) { + providerKeeper.SetTopN(ctx, chainID, 95) } - - keeper.SetParams(ctx, params) - keeper.Logger(ctx).Info("successfully migrated legacy provider parameters") - return nil } + +// // If there are consumer addition proposals in the voting period at the upgrade time, they may need the topN value updated. +// func MigrateTopNForVotingPeriodChains(ctx sdk.Context, govKeeper govkeeper.Keeper, providerKeeper providerkeeper.Keeper) { +// } diff --git a/x/ccv/provider/migrations/v5/migrations_test.go b/x/ccv/provider/migrations/v5/migrations_test.go index a7705da8b0..907aa1b019 100644 --- a/x/ccv/provider/migrations/v5/migrations_test.go +++ b/x/ccv/provider/migrations/v5/migrations_test.go @@ -6,52 +6,25 @@ import ( "github.com/stretchr/testify/require" testutil "github.com/cosmos/interchain-security/v5/testutil/keeper" - providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" ) func TestMigrateParams(t *testing.T) { - t.Helper() inMemParams := testutil.NewInMemKeeperParams(t) - k, ctx, ctrl, _ := testutil.GetProviderKeeperAndCtx(t, inMemParams) + provKeeper, ctx, ctrl, _ := testutil.GetProviderKeeperAndCtx(t, inMemParams) defer ctrl.Finish() - if !inMemParams.ParamsSubspace.HasKeyTable() { - inMemParams.ParamsSubspace.WithKeyTable(providertypes.ParamKeyTable()) - } - - defaultParams := providertypes.DefaultParams() - inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyTemplateClient, defaultParams.TemplateClient) - inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyTrustingPeriodFraction, defaultParams.TrustingPeriodFraction) - inMemParams.ParamsSubspace.Set(ctx, ccvtypes.KeyCCVTimeoutPeriod, defaultParams.CcvTimeoutPeriod) - inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyInitTimeoutPeriod, defaultParams.InitTimeoutPeriod) - inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyVscTimeoutPeriod, defaultParams.VscTimeoutPeriod) - inMemParams.ParamsSubspace.Set(ctx, providertypes.KeySlashMeterReplenishPeriod, defaultParams.SlashMeterReplenishPeriod) - inMemParams.ParamsSubspace.Set(ctx, providertypes.KeySlashMeterReplenishFraction, defaultParams.SlashMeterReplenishFraction) - inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyConsumerRewardDenomRegistrationFee, defaultParams.ConsumerRewardDenomRegistrationFee) - inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyBlocksPerEpoch, defaultParams.BlocksPerEpoch) - - // confirms that inMemParams.ParamsSubspace works as expected - require.NotPanics(t, func() { - GetParamsLegacy(ctx, inMemParams.ParamsSubspace) - }) - - // no "new" params should be available before migration - // "new" params are stored under providertypes.ParametersKey() - emptyParams := k.GetParams(ctx) - require.Empty(t, emptyParams) - - // make sure that the legacy params are equal to the default params (they were set using inMemParams.ParamsSubspace.Set()) - legacyParams := GetParamsLegacy(ctx, inMemParams.ParamsSubspace) - require.NotNil(t, legacyParams) - require.Equal(t, defaultParams, legacyParams) - - err := MigrateLegacyParams(ctx, k, inMemParams.ParamsSubspace) - require.NoError(t, err) - - // check that "new" params are available after migration and equal to defaults - migratedParams := k.GetParams(ctx) - require.NotEmpty(t, migratedParams) - require.Equal(t, defaultParams, migratedParams) - require.NotEqual(t, emptyParams, migratedParams) + provKeeper.SetConsumerClientId(ctx, "chainID", "clientID") + + // initially top N should not exist + topN, found := provKeeper.GetTopN(ctx, "chainID") + require.False(t, found) + require.Zero(t, topN) + + // migrate + MigrateTopNForRegisteredChains(ctx, provKeeper) + + // after migration, top N should be 95 + topN, found = provKeeper.GetTopN(ctx, "chainID") + require.True(t, found) + require.Equal(t, uint32(95), topN) } diff --git a/x/ccv/provider/migrations/v6/migration_test.go b/x/ccv/provider/migrations/v6/migration_test.go new file mode 100644 index 0000000000..9396a3e05d --- /dev/null +++ b/x/ccv/provider/migrations/v6/migration_test.go @@ -0,0 +1,27 @@ +package v6 + +import ( + "testing" + + "github.com/stretchr/testify/require" + + testutil "github.com/cosmos/interchain-security/v5/testutil/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" +) + +func TestMigrateParams(t *testing.T) { + inMemParams := testutil.NewInMemKeeperParams(t) + _, ctx, ctrl, _ := testutil.GetProviderKeeperAndCtx(t, inMemParams) + defer ctrl.Finish() + + // initially number of epochs param does not exist + require.False(t, inMemParams.ParamsSubspace.Has(ctx, providertypes.KeyNumberOfEpochsToStartReceivingRewards)) + + MigrateParams(ctx, *inMemParams.ParamsSubspace) + + // after migration, number of epochs to start receiving rewards param should exist and be equal to default + require.True(t, inMemParams.ParamsSubspace.Has(ctx, providertypes.KeyNumberOfEpochsToStartReceivingRewards)) + var numberOfEpochsParam int64 + inMemParams.ParamsSubspace.Get(ctx, providertypes.KeyNumberOfEpochsToStartReceivingRewards, &numberOfEpochsParam) + require.Equal(t, providertypes.DefaultNumberOfEpochsToStartReceivingRewards, numberOfEpochsParam) +} diff --git a/x/ccv/provider/migrations/v6/migrations.go b/x/ccv/provider/migrations/v6/migrations.go new file mode 100644 index 0000000000..5829f29222 --- /dev/null +++ b/x/ccv/provider/migrations/v6/migrations.go @@ -0,0 +1,47 @@ +package v6 + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" +) + +// MigrateParams adds missing provider chain params to the param store. +func MigrateParams(ctx sdk.Context, paramsSubspace paramtypes.Subspace) { + if !paramsSubspace.HasKeyTable() { + paramsSubspace.WithKeyTable(providertypes.ParamKeyTable()) + } + paramsSubspace.Set(ctx, providertypes.KeyNumberOfEpochsToStartReceivingRewards, providertypes.DefaultNumberOfEpochsToStartReceivingRewards) +} + +func MigrateMinPowerInTopN(ctx sdk.Context, providerKeeper providerkeeper.Keeper) { + // we only get the registered consumer chains and not also the proposed consumer chains because + // the minimal power is first set when the consumer chain addition proposal passes + registeredConsumerChains := providerKeeper.GetAllRegisteredConsumerChainIDs(ctx) + + for _, chain := range registeredConsumerChains { + // get the top N + topN, found := providerKeeper.GetTopN(ctx, chain) + if !found { + providerKeeper.Logger(ctx).Error("failed to get top N", "chain", chain) + continue + } else if topN == 0 { + providerKeeper.Logger(ctx).Info("top N is 0, not setting minimal power", "chain", chain) + } else { + // set the minimal power in the top N + bondedValidators, err := providerKeeper.GetLastBondedValidators(ctx) + if err != nil { + providerKeeper.Logger(ctx).Error("failed to get last bonded validators", "chain", chain, "error", err) + continue + } + minPower, err := providerKeeper.ComputeMinPowerInTopN(ctx, bondedValidators, topN) + if err != nil { + providerKeeper.Logger(ctx).Error("failed to compute min power in top N", "chain", chain, "topN", topN, "error", err) + continue + } + providerKeeper.SetMinimumPowerInTopN(ctx, chain, minPower) + } + } +} diff --git a/x/ccv/provider/migrations/v5/legacy_params.go b/x/ccv/provider/migrations/v7/legacy_params.go similarity index 92% rename from x/ccv/provider/migrations/v5/legacy_params.go rename to x/ccv/provider/migrations/v7/legacy_params.go index 146339a131..a8c6d5218d 100644 --- a/x/ccv/provider/migrations/v5/legacy_params.go +++ b/x/ccv/provider/migrations/v7/legacy_params.go @@ -1,4 +1,4 @@ -package v5 +package v7 import ( "time" @@ -75,6 +75,12 @@ func getBlocksPerEpoch(ctx sdk.Context, paramSpace ccvtypes.LegacyParamSubspace) return b } +func getNumberOfEpochsToStartReceivingRewards(ctx sdk.Context, paramSpace ccvtypes.LegacyParamSubspace) int64 { + var b int64 + paramSpace.Get(ctx, types.KeyNumberOfEpochsToStartReceivingRewards, &b) + return b +} + // Legacy: Only for migration purposes. GetParamsLegacy returns the paramset for the provider // module from a given param subspace func GetParamsLegacy(ctx sdk.Context, paramspace ccvtypes.LegacyParamSubspace) types.Params { @@ -88,5 +94,6 @@ func GetParamsLegacy(ctx sdk.Context, paramspace ccvtypes.LegacyParamSubspace) t getSlashMeterReplenishFraction(ctx, paramspace), getConsumerRewardDenomRegistrationFee(ctx, paramspace), getBlocksPerEpoch(ctx, paramspace), + getNumberOfEpochsToStartReceivingRewards(ctx, paramspace), ) } diff --git a/x/ccv/provider/migrations/v7/migrations.go b/x/ccv/provider/migrations/v7/migrations.go new file mode 100644 index 0000000000..3c2f171dac --- /dev/null +++ b/x/ccv/provider/migrations/v7/migrations.go @@ -0,0 +1,21 @@ +package v7 + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + providerkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" +) + +// MigrateParams migrates the provider module's parameters from the x/params to self store. +func MigrateLegacyParams(ctx sdk.Context, keeper providerkeeper.Keeper, legacyParamspace ccvtypes.LegacyParamSubspace) error { + ctx.Logger().Info("starting provider legacy params migration") + params := GetParamsLegacy(ctx, legacyParamspace) + err := params.Validate() + if err != nil { + return err + } + + keeper.SetParams(ctx, params) + keeper.Logger(ctx).Info("successfully migrated legacy provider parameters") + return nil +} diff --git a/x/ccv/provider/migrations/v7/migrations_test.go b/x/ccv/provider/migrations/v7/migrations_test.go new file mode 100644 index 0000000000..f4ee763263 --- /dev/null +++ b/x/ccv/provider/migrations/v7/migrations_test.go @@ -0,0 +1,56 @@ +package v7 + +import ( + "testing" + + testutil "github.com/cosmos/interchain-security/v5/testutil/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" + "github.com/stretchr/testify/require" +) + +func TestMigrateParams(t *testing.T) { + t.Helper() + inMemParams := testutil.NewInMemKeeperParams(t) + k, ctx, ctrl, _ := testutil.GetProviderKeeperAndCtx(t, inMemParams) + defer ctrl.Finish() + + if !inMemParams.ParamsSubspace.HasKeyTable() { + inMemParams.ParamsSubspace.WithKeyTable(providertypes.ParamKeyTable()) + } + + defaultParams := providertypes.DefaultParams() + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyTemplateClient, defaultParams.TemplateClient) + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyTrustingPeriodFraction, defaultParams.TrustingPeriodFraction) + inMemParams.ParamsSubspace.Set(ctx, ccvtypes.KeyCCVTimeoutPeriod, defaultParams.CcvTimeoutPeriod) + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyInitTimeoutPeriod, defaultParams.InitTimeoutPeriod) + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyVscTimeoutPeriod, defaultParams.VscTimeoutPeriod) + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeySlashMeterReplenishPeriod, defaultParams.SlashMeterReplenishPeriod) + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeySlashMeterReplenishFraction, defaultParams.SlashMeterReplenishFraction) + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyConsumerRewardDenomRegistrationFee, defaultParams.ConsumerRewardDenomRegistrationFee) + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyBlocksPerEpoch, defaultParams.BlocksPerEpoch) + inMemParams.ParamsSubspace.Set(ctx, providertypes.KeyNumberOfEpochsToStartReceivingRewards, defaultParams.NumberOfEpochsToStartReceivingRewards) + + // confirms that inMemParams.ParamsSubspace works as expected + require.NotPanics(t, func() { + GetParamsLegacy(ctx, inMemParams.ParamsSubspace) + }) + + // no "new" params should be available before migration + // "new" params are stored under providertypes.ParametersKey() + emptyParams := k.GetParams(ctx) + require.Empty(t, emptyParams) + + // make sure that the legacy params are equal to the default params (they were set using inMemParams.ParamsSubspace.Set()) + legacyParams := GetParamsLegacy(ctx, inMemParams.ParamsSubspace) + require.NotNil(t, legacyParams) + require.Equal(t, defaultParams, legacyParams) + + err := MigrateLegacyParams(ctx, k, inMemParams.ParamsSubspace) + require.NoError(t, err) + + // check that "new" params are available after migration and equal to defaults + migratedParams := k.GetParams(ctx) + require.NotEmpty(t, migratedParams) + require.Equal(t, defaultParams, migratedParams) +} diff --git a/x/ccv/provider/module.go b/x/ccv/provider/module.go index 63e26431fc..8c87262640 100644 --- a/x/ccv/provider/module.go +++ b/x/ccv/provider/module.go @@ -131,6 +131,12 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { if err := cfg.RegisterMigration(providertypes.ModuleName, 4, migrator.Migrate4to5); err != nil { panic(fmt.Sprintf("failed to register migrator for %s: %s -- from 4 -> 5", providertypes.ModuleName, err)) } + if err := cfg.RegisterMigration(providertypes.ModuleName, 5, migrator.Migrate5to6); err != nil { + panic(fmt.Sprintf("failed to register migrator for %s: %s", providertypes.ModuleName, err)) + } + if err := cfg.RegisterMigration(providertypes.ModuleName, 6, migrator.Migrate6to7); err != nil { + panic(fmt.Sprintf("failed to register migrator for %s: %s", providertypes.ModuleName, err)) + } } // InitGenesis performs genesis initialization for the provider module. It returns no validator updates. @@ -151,7 +157,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 5 } +func (AppModule) ConsensusVersion() uint64 { return 7 } // BeginBlock implements the AppModule interface func (am AppModule) BeginBlock(ctx context.Context) error { @@ -162,6 +168,8 @@ func (am AppModule) BeginBlock(ctx context.Context) error { am.keeper.BeginBlockCCR(sdkCtx) // Check for replenishing slash meter before any slash packets are processed for this block am.keeper.BeginBlockCIS(sdkCtx) + // BeginBlock logic needed for the Reward Distribution sub-protocol + am.keeper.BeginBlockRD(sdkCtx) return nil } @@ -177,8 +185,6 @@ func (am AppModule) EndBlock(ctx context.Context) error { am.keeper.EndBlockCCR(sdkCtx) // EndBlock logic needed for the Validator Set Update sub-protocol am.keeper.EndBlockVSU(sdkCtx) - // EndBlock logic need for the Reward Distribution sub-protocol - am.keeper.EndBlockRD(sdkCtx) return nil } diff --git a/x/ccv/provider/proposal_handler.go b/x/ccv/provider/proposal_handler.go index 6c6f78b792..40a551d185 100644 --- a/x/ccv/provider/proposal_handler.go +++ b/x/ccv/provider/proposal_handler.go @@ -21,6 +21,8 @@ func NewProviderProposalHandler(k keeper.Keeper) govv1beta1.Handler { return k.HandleLegacyConsumerAdditionProposal(ctx, c) case *types.ConsumerRemovalProposal: return k.HandleLegacyConsumerRemovalProposal(ctx, c) + case *types.ConsumerModificationProposal: + return k.HandleLegacyConsumerModificationProposal(ctx, c) case *types.ChangeRewardDenomsProposal: return k.HandleLegacyConsumerRewardDenomProposal(ctx, c) default: diff --git a/x/ccv/provider/proposal_handler_test.go b/x/ccv/provider/proposal_handler_test.go index 2112bb8d33..2494da8c60 100644 --- a/x/ccv/provider/proposal_handler_test.go +++ b/x/ccv/provider/proposal_handler_test.go @@ -5,13 +5,14 @@ import ( "time" "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" - sdk "github.com/cosmos/cosmos-sdk/types" distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" testkeeper "github.com/cosmos/interchain-security/v5/testutil/keeper" "github.com/cosmos/interchain-security/v5/x/ccv/provider" @@ -45,6 +46,11 @@ func TestProviderProposalHandler(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, + 0, + 0, + nil, + nil, ), blockTime: hourFromNow, // ctx blocktime is after proposal's spawn time expValidConsumerAddition: true, @@ -92,6 +98,7 @@ func TestProviderProposalHandler(t *testing.T) { // Mock expectations depending on expected outcome switch { case tc.expValidConsumerAddition: + testkeeper.SetupMocksForLastBondedValidatorsExpectation(mocks.MockStakingKeeper, 1, []stakingtypes.Validator{}, []int64{}, 1) gomock.InOrder(testkeeper.GetMocksForCreateConsumerClient( ctx, &mocks, "chainID", clienttypes.NewHeight(2, 3), )...) diff --git a/x/ccv/provider/types/codec.go b/x/ccv/provider/types/codec.go index 2966cebf5d..1d75778bb1 100644 --- a/x/ccv/provider/types/codec.go +++ b/x/ccv/provider/types/codec.go @@ -23,6 +23,10 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { (*govv1beta1.Content)(nil), &ConsumerRemovalProposal{}, ) + registry.RegisterImplementations( + (*govv1beta1.Content)(nil), + &ConsumerModificationProposal{}, + ) registry.RegisterImplementations( (*sdk.Msg)(nil), &MsgAssignConsumerKey{}, @@ -48,10 +52,22 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { (*sdk.Msg)(nil), &MsgSubmitConsumerDoubleVoting{}, ) + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgOptIn{}, + ) + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgOptOut{}, + ) registry.RegisterImplementations( (*exported.ClientMessage)(nil), &tendermint.Misbehaviour{}, ) + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgSetConsumerCommissionRate{}, + ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } diff --git a/x/ccv/provider/types/errors.go b/x/ccv/provider/types/errors.go index 257ad037c0..7cee0716ba 100644 --- a/x/ccv/provider/types/errors.go +++ b/x/ccv/provider/types/errors.go @@ -6,27 +6,30 @@ import ( // Provider sentinel errors var ( - ErrInvalidConsumerAdditionProposal = errorsmod.Register(ModuleName, 1, "invalid consumer addition proposal") - ErrInvalidConsumerRemovalProp = errorsmod.Register(ModuleName, 2, "invalid consumer removal proposal") - ErrUnknownConsumerChainId = errorsmod.Register(ModuleName, 3, "no consumer chain with this chain id") - ErrUnknownConsumerChannelId = errorsmod.Register(ModuleName, 4, "no consumer chain with this channel id") - ErrInvalidConsumerConsensusPubKey = errorsmod.Register(ModuleName, 5, "empty consumer consensus public key") - ErrInvalidConsumerChainID = errorsmod.Register(ModuleName, 6, "invalid consumer chain id") - ErrConsumerKeyNotFound = errorsmod.Register(ModuleName, 7, "consumer key not found") - ErrNoValidatorConsumerAddress = errorsmod.Register(ModuleName, 8, "error getting validator consumer address") - ErrNoValidatorProviderAddress = errorsmod.Register(ModuleName, 9, "error getting validator provider address") - ErrConsumerKeyInUse = errorsmod.Register(ModuleName, 10, "consumer key is already in use by a validator") - ErrCannotAssignDefaultKeyAssignment = errorsmod.Register(ModuleName, 11, "cannot re-assign default key assignment") - ErrInvalidConsumerParams = errorsmod.Register(ModuleName, 12, "invalid consumer params") - ErrInvalidProviderAddress = errorsmod.Register(ModuleName, 13, "invalid provider address") - ErrInvalidConsumerRewardDenom = errorsmod.Register(ModuleName, 14, "invalid consumer reward denom") - ErrInvalidDepositorAddress = errorsmod.Register(ModuleName, 15, "invalid depositor address") - ErrInvalidConsumerClient = errorsmod.Register(ModuleName, 16, "ccv channel is not built on correct client") - ErrDuplicateConsumerChain = errorsmod.Register(ModuleName, 17, "consumer chain already exists") - ErrConsumerChainNotFound = errorsmod.Register(ModuleName, 18, "consumer chain not found") - ErrNoUnconfirmedVSCPacket = errorsmod.Register(ModuleName, 19, "no unconfirmed vsc packet for this chain id") - ErrNoUnbondingTime = errorsmod.Register(ModuleName, 20, "provider unbonding time not found") - ErrInvalidAddress = errorsmod.Register(ModuleName, 21, "invalid address") - ErrUnauthorized = errorsmod.Register(ModuleName, 22, "unauthorized") - ErrBlankConsumerChainID = errorsmod.Register(ModuleName, 23, "consumer chain id must not be blank") + ErrInvalidConsumerAdditionProposal = errorsmod.Register(ModuleName, 1, "invalid consumer addition proposal") + ErrInvalidConsumerRemovalProp = errorsmod.Register(ModuleName, 2, "invalid consumer removal proposal") + ErrUnknownConsumerChainId = errorsmod.Register(ModuleName, 3, "no consumer chain with this chain id") + ErrUnknownConsumerChannelId = errorsmod.Register(ModuleName, 4, "no consumer chain with this channel id") + ErrInvalidConsumerConsensusPubKey = errorsmod.Register(ModuleName, 5, "empty consumer consensus public key") + ErrInvalidConsumerChainID = errorsmod.Register(ModuleName, 6, "invalid consumer chain id") + ErrConsumerKeyNotFound = errorsmod.Register(ModuleName, 7, "consumer key not found") + ErrNoValidatorConsumerAddress = errorsmod.Register(ModuleName, 8, "error getting validator consumer address") + ErrNoValidatorProviderAddress = errorsmod.Register(ModuleName, 9, "error getting validator provider address") + ErrConsumerKeyInUse = errorsmod.Register(ModuleName, 10, "consumer key is already in use by a validator") + ErrCannotAssignDefaultKeyAssignment = errorsmod.Register(ModuleName, 11, "cannot re-assign default key assignment") + ErrInvalidConsumerParams = errorsmod.Register(ModuleName, 12, "invalid consumer params") + ErrInvalidProviderAddress = errorsmod.Register(ModuleName, 13, "invalid provider address") + ErrInvalidConsumerRewardDenom = errorsmod.Register(ModuleName, 14, "invalid consumer reward denom") + ErrInvalidDepositorAddress = errorsmod.Register(ModuleName, 15, "invalid depositor address") + ErrInvalidConsumerClient = errorsmod.Register(ModuleName, 16, "ccv channel is not built on correct client") + ErrDuplicateConsumerChain = errorsmod.Register(ModuleName, 17, "consumer chain already exists") + ErrConsumerChainNotFound = errorsmod.Register(ModuleName, 18, "consumer chain not found") + ErrInvalidConsumerCommissionRate = errorsmod.Register(ModuleName, 19, "consumer commission rate is invalid") + ErrCannotOptOutFromTopN = errorsmod.Register(ModuleName, 20, "cannot opt out from a Top N chain") + ErrNoUnconfirmedVSCPacket = errorsmod.Register(ModuleName, 21, "no unconfirmed vsc packet for this chain id") + ErrInvalidConsumerModificationProposal = errorsmod.Register(ModuleName, 23, "invalid consumer modification proposal") + ErrNoUnbondingTime = errorsmod.Register(ModuleName, 24, "provider unbonding time not found") + ErrInvalidAddress = errorsmod.Register(ModuleName, 25, "invalid address") + ErrUnauthorized = errorsmod.Register(ModuleName, 26, "unauthorized") + ErrBlankConsumerChainID = errorsmod.Register(ModuleName, 27, "consumer chain id must not be blank") ) diff --git a/x/ccv/provider/types/events.go b/x/ccv/provider/types/events.go index 58d686020f..8701821c52 100644 --- a/x/ccv/provider/types/events.go +++ b/x/ccv/provider/types/events.go @@ -7,6 +7,9 @@ const ( EventTypeAddConsumerRewardDenom = "add_consumer_reward_denom" EventTypeRemoveConsumerRewardDenom = "remove_consumer_reward_denom" EventTypeExecuteConsumerChainSlash = "execute_consumer_chain_slash" + EventTypeSetConsumerCommissionRate = "set_consumer_commission_rate" + EventTypeOptIn = "opt_in" + EventTypeOptOut = "opt_out" AttributeInfractionHeight = "infraction_height" AttributeInitialHeight = "initial_height" AttributeInitializationTimeout = "initialization_timeout" @@ -15,4 +18,6 @@ const ( AttributeProviderValidatorAddress = "provider_validator_address" AttributeConsumerConsensusPubKey = "consumer_consensus_pub_key" AttributeConsumerRewardDenom = "consumer_reward_denom" + AttributeConsumerCommissionRate = "consumer_commission_rate" + AttributeConsumerChainID = "consumer_chain_id" ) diff --git a/x/ccv/provider/types/genesis_test.go b/x/ccv/provider/types/genesis_test.go index f040a2ee08..6a9e5a7593 100644 --- a/x/ccv/provider/types/genesis_test.go +++ b/x/ccv/provider/types/genesis_test.go @@ -82,7 +82,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 24), nil, nil, nil, @@ -103,7 +103,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 24), nil, nil, nil, @@ -124,7 +124,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 24), nil, nil, nil, @@ -145,7 +145,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 24), nil, nil, nil, @@ -172,7 +172,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 24), nil, nil, nil, @@ -199,7 +199,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 24), nil, nil, nil, @@ -226,7 +226,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: math.NewInt(1000000)}, 600), + sdk.Coin{Denom: "stake", Amount: math.NewInt(1000000)}, 600, 24), nil, nil, nil, @@ -253,7 +253,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 24), nil, nil, nil, @@ -280,7 +280,7 @@ func TestValidateGenesisState(t *testing.T) { 0, // 0 vsc timeout here types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 24), nil, nil, nil, @@ -307,7 +307,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, 0, // 0 slash meter replenish period here types.DefaultSlashMeterReplenishFraction, - sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 24), nil, nil, nil, @@ -334,7 +334,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, "1.15", - sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600), + sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 600, 24), nil, nil, nil, @@ -686,7 +686,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: math.NewInt(10000000)}, 600), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: math.NewInt(10000000)}, 600, 24), nil, nil, nil, @@ -707,7 +707,7 @@ func TestValidateGenesisState(t *testing.T) { nil, types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(-1000000)}, 600), + types.DefaultTrustingPeriodFraction, time.Hour, time.Hour, 30*time.Minute, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(-1000000)}, 600, 24), nil, nil, nil, diff --git a/x/ccv/provider/types/keys.go b/x/ccv/provider/types/keys.go index 337638f55c..47231c219f 100644 --- a/x/ccv/provider/types/keys.go +++ b/x/ccv/provider/types/keys.go @@ -147,11 +147,46 @@ const ( // ProposedConsumerChainByteKey is the byte prefix storing the consumer chainId in consumerAddition gov proposal submitted before voting finishes ProposedConsumerChainByteKey - // ConsumerValidatorBytePrefix is the byte prefix used when storing for each consumer chain all the consumer validators in this epoch + // ConsumerValidatorBytePrefix is the byte prefix used when storing for each consumer chain all the consumer + // validators in this epoch that are validating the consumer chain ConsumerValidatorBytePrefix - // ParametersKey is the is the single byte key for storing provider's parameters. - ParametersByteKey + // OptedInBytePrefix is the byte prefix for storing whether a validator is opted in to validate on a consumer chain + OptedInBytePrefix + + // TopNBytePrefix is the byte prefix storing the mapping from a consumer chain to the N value of this chain, + // that corresponds to the N% of the top validators that have to validate this consumer chain + TopNBytePrefix + + // ValidatorsPowerCapPrefix is the byte prefix storing the mapping from a consumer chain to the power-cap value of this chain, + // that corresponds to p% such that no validator can have more than p% of the voting power on the consumer chain. + // Operates on a best-effort basis. + ValidatorsPowerCapPrefix + + // ValidatorSetCapPrefix is the byte prefix storing the mapping from a consumer chain to the validator-set cap value + // of this chain. + ValidatorSetCapPrefix + + // AllowlistPrefix is the byte prefix storing the mapping from a consumer chain to the set of validators that are + // allowlisted. + AllowlistPrefix + + // DenylistPrefix is the byte prefix storing the mapping from a consumer chain to the set of validators that are + // denylisted. + DenylistPrefix + + // ConsumerRewardsAllocationBytePrefix is the byte prefix for storing for each consumer the ICS rewards + // allocated to the consumer rewards pool + ConsumerRewardsAllocationBytePrefix + + // ConsumerCommissionRatePrefix is the byte prefix for storing the commission rate + // per validator per consumer chain + ConsumerCommissionRatePrefix + + // MinimumPowerInTopNBytePrefix is the byte prefix for storing the + // minimum power required to be in the top N per consumer chain. + MinimumPowerInTopNBytePrefix + // NOTE: DO NOT ADD NEW BYTE PREFIXES HERE WITHOUT ADDING THEM TO getAllKeyPrefixes() IN keys_test.go ) @@ -159,6 +194,13 @@ const ( // Fully defined key func section // +const ( + // ParametersKey is the is the single byte key for storing provider's parameters. + // note that this was set to the max uint8 type value 0xFF in order to protect + // from using the ICS v5.0.0 provider module by mistake + ParametersByteKey = byte(0xFF) +) + // ParametersKey returns the key for the parameters of the provider module in the store func ParametersKey() []byte { return []byte{ParametersByteKey} @@ -529,6 +571,56 @@ func ConsumerValidatorKey(chainID string, providerAddr []byte) []byte { return append(prefix, providerAddr...) } +// TopNKey returns the key used to store the Top N value per consumer chain. +// This value corresponds to the N% of the top validators that have to validate the consumer chain. +func TopNKey(chainID string) []byte { + return ChainIdWithLenKey(TopNBytePrefix, chainID) +} + +// ValidatorSetPowerKey returns the key of consumer chain `chainID` +func ValidatorsPowerCapKey(chainID string) []byte { + return ChainIdWithLenKey(ValidatorsPowerCapPrefix, chainID) +} + +// ValidatorSetCapKey returns the key of consumer chain `chainID` +func ValidatorSetCapKey(chainID string) []byte { + return ChainIdWithLenKey(ValidatorSetCapPrefix, chainID) +} + +// AllowlistCapKey returns the key to a validator's slash log +func AllowlistCapKey(chainID string, providerAddr ProviderConsAddress) []byte { + return append(ChainIdWithLenKey(AllowlistPrefix, chainID), providerAddr.ToSdkConsAddr().Bytes()...) +} + +// DenylistCapKey returns the key to a validator's slash log +func DenylistCapKey(chainID string, providerAddr ProviderConsAddress) []byte { + return append(ChainIdWithLenKey(DenylistPrefix, chainID), providerAddr.ToSdkConsAddr().Bytes()...) +} + +// OptedInKey returns the key used to store whether a validator is opted in on a consumer chain. +func OptedInKey(chainID string, providerAddr ProviderConsAddress) []byte { + prefix := ChainIdWithLenKey(OptedInBytePrefix, chainID) + return append(prefix, providerAddr.ToSdkConsAddr().Bytes()...) +} + +// ConsumerRewardsAllocationKey returns the key used to store the ICS rewards per consumer chain +func ConsumerRewardsAllocationKey(chainID string) []byte { + return append([]byte{ConsumerRewardsAllocationBytePrefix}, []byte(chainID)...) +} + +// ConsumerCommissionRateKey returns the key used to store the commission rate per validator per consumer chain. +func ConsumerCommissionRateKey(chainID string, providerAddr ProviderConsAddress) []byte { + return ChainIdAndConsAddrKey( + ConsumerCommissionRatePrefix, + chainID, + providerAddr.ToSdkConsAddr(), + ) +} + +func MinimumPowerInTopNKey(chainID string) []byte { + return ChainIdWithLenKey(MinimumPowerInTopNBytePrefix, chainID) +} + // // End of generic helpers section // diff --git a/x/ccv/provider/types/keys_test.go b/x/ccv/provider/types/keys_test.go index bfe4f55f61..3f6df5cb0a 100644 --- a/x/ccv/provider/types/keys_test.go +++ b/x/ccv/provider/types/keys_test.go @@ -57,6 +57,11 @@ func getAllKeyPrefixes() []byte { providertypes.EquivocationEvidenceMinHeightBytePrefix, providertypes.ProposedConsumerChainByteKey, providertypes.ConsumerValidatorBytePrefix, + providertypes.OptedInBytePrefix, + providertypes.TopNBytePrefix, + providertypes.ConsumerRewardsAllocationBytePrefix, + providertypes.ConsumerCommissionRatePrefix, + providertypes.MinimumPowerInTopNBytePrefix, providertypes.ParametersByteKey, } } diff --git a/x/ccv/provider/types/legacy_proposal.go b/x/ccv/provider/types/legacy_proposal.go index 4076e37ed7..37c068e1c2 100644 --- a/x/ccv/provider/types/legacy_proposal.go +++ b/x/ccv/provider/types/legacy_proposal.go @@ -19,15 +19,17 @@ import ( ) const ( - ProposalTypeConsumerAddition = "ConsumerAddition" - ProposalTypeConsumerRemoval = "ConsumerRemoval" - ProposalTypeEquivocation = "Equivocation" - ProposalTypeChangeRewardDenoms = "ChangeRewardDenoms" + ProposalTypeConsumerAddition = "ConsumerAddition" + ProposalTypeConsumerRemoval = "ConsumerRemoval" + ProposalTypeConsumerModification = "ConsumerModification" + ProposalTypeEquivocation = "Equivocation" + ProposalTypeChangeRewardDenoms = "ChangeRewardDenoms" ) var ( _ govv1beta1.Content = &ConsumerAdditionProposal{} _ govv1beta1.Content = &ConsumerRemovalProposal{} + _ govv1beta1.Content = &ConsumerModificationProposal{} _ govv1beta1.Content = &ChangeRewardDenomsProposal{} _ govv1beta1.Content = &EquivocationProposal{} ) @@ -35,6 +37,7 @@ var ( func init() { govv1beta1.RegisterProposalType(ProposalTypeConsumerAddition) govv1beta1.RegisterProposalType(ProposalTypeConsumerRemoval) + govv1beta1.RegisterProposalType(ProposalTypeConsumerModification) govv1beta1.RegisterProposalType(ProposalTypeChangeRewardDenoms) govv1beta1.RegisterProposalType(ProposalTypeEquivocation) } @@ -50,6 +53,11 @@ func NewConsumerAdditionProposal(title, description, chainID string, ccvTimeoutPeriod time.Duration, transferTimeoutPeriod time.Duration, unbondingPeriod time.Duration, + topN uint32, + validatorsPowerCap uint32, + validatorSetCap uint32, + allowlist []string, + denylist []string, ) govv1beta1.Content { return &ConsumerAdditionProposal{ Title: title, @@ -66,6 +74,11 @@ func NewConsumerAdditionProposal(title, description, chainID string, CcvTimeoutPeriod: ccvTimeoutPeriod, TransferTimeoutPeriod: transferTimeoutPeriod, UnbondingPeriod: unbondingPeriod, + Top_N: topN, + ValidatorsPowerCap: validatorsPowerCap, + ValidatorSetCap: validatorSetCap, + Allowlist: allowlist, + Denylist: denylist, } } @@ -83,6 +96,21 @@ func (cccp *ConsumerAdditionProposal) ProposalType() string { return ProposalTypeConsumerAddition } +// ValidatePSSFeatures returns an error if the `topN` and `validatorsPowerCap` parameters are no in the correct ranges +func ValidatePSSFeatures(topN uint32, validatorsPowerCap uint32) error { + // Top N corresponds to the top N% of validators that have to validate the consumer chain and can only be 0 (for an + // Opt In chain) or in the range [50, 100] (for a Top N chain). + if topN != 0 && (topN < 50 || topN > 100) { + return fmt.Errorf("Top N can either be 0 or in the range [50, 100]") + } + + if validatorsPowerCap != 0 && validatorsPowerCap > 100 { + return fmt.Errorf("validators' power cap has to be in the range [1, 100]") + } + + return nil +} + // ValidateBasic runs basic stateless validity checks func (cccp *ConsumerAdditionProposal) ValidateBasic() error { if err := govv1beta1.ValidateAbstract(cccp); err != nil { @@ -136,6 +164,10 @@ func (cccp *ConsumerAdditionProposal) ValidateBasic() error { return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "unbonding period cannot be zero") } + err := ValidatePSSFeatures(cccp.Top_N, cccp.ValidatorsPowerCap) + if err != nil { + return errorsmod.Wrapf(ErrInvalidConsumerAdditionProposal, "invalid PSS features: %s", err.Error()) + } return nil } @@ -204,6 +236,51 @@ func (sccp *ConsumerRemovalProposal) ValidateBasic() error { return nil } +// NewConsumerModificationProposal creates a new consumer modification proposal. +func NewConsumerModificationProposal(title, description, chainID string, + topN uint32, + validatorsPowerCap uint32, + validatorSetCap uint32, + allowlist []string, + denylist []string, +) govv1beta1.Content { + return &ConsumerModificationProposal{ + Title: title, + Description: description, + ChainId: chainID, + Top_N: topN, + ValidatorsPowerCap: validatorsPowerCap, + ValidatorSetCap: validatorSetCap, + Allowlist: allowlist, + Denylist: denylist, + } +} + +// ProposalRoute returns the routing key of a consumer modification proposal. +func (cccp *ConsumerModificationProposal) ProposalRoute() string { return RouterKey } + +// ProposalType returns the type of the consumer modification proposal. +func (cccp *ConsumerModificationProposal) ProposalType() string { + return ProposalTypeConsumerModification +} + +// ValidateBasic runs basic stateless validity checks +func (cccp *ConsumerModificationProposal) ValidateBasic() error { + if err := govv1beta1.ValidateAbstract(cccp); err != nil { + return err + } + + if strings.TrimSpace(cccp.ChainId) == "" { + return errorsmod.Wrap(ErrInvalidConsumerModificationProposal, "consumer chain id must not be blank") + } + + err := ValidatePSSFeatures(cccp.Top_N, cccp.ValidatorsPowerCap) + if err != nil { + return errorsmod.Wrapf(ErrInvalidConsumerModificationProposal, "invalid PSS features: %s", err.Error()) + } + return nil +} + // NewEquivocationProposal creates a new equivocation proposal. // [DEPRECATED]: do not use because equivocations can be submitted // and verified automatically on the provider. diff --git a/x/ccv/provider/types/legacy_proposal_test.go b/x/ccv/provider/types/legacy_proposal_test.go index 8253af35cf..729a4318ca 100644 --- a/x/ccv/provider/types/legacy_proposal_test.go +++ b/x/ccv/provider/types/legacy_proposal_test.go @@ -36,6 +36,11 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 100000000000, 100000000000, + 0, + 0, + 0, + nil, + nil, ), true, }, @@ -48,7 +53,13 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0, + 0, + 0, + nil, + nil, + ), true, }, { @@ -60,7 +71,13 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0, + 0, + 0, + nil, + nil, + ), false, }, { @@ -72,7 +89,13 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0, + 0, + 0, + nil, + nil, + ), false, }, { @@ -104,7 +127,13 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0, + 0, + 0, + nil, + nil, + ), false, }, { @@ -116,7 +145,12 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0, + 0, + 0, + nil, + nil), false, }, { @@ -128,7 +162,13 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0, + 0, + 0, + nil, + nil, + ), false, }, { @@ -140,7 +180,13 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0, + 0, + 0, + nil, + nil, + ), false, }, { @@ -152,7 +198,13 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 100000000000, 10000, 100000000000, - 100000000000), + 100000000000, + 0, + 0, + 0, + nil, + nil, + ), false, }, { @@ -164,7 +216,13 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0, + 0, + 0, + nil, + nil, + ), false, }, { @@ -176,7 +234,13 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { -2, 100000000000, 100000000000, - 100000000000), + 100000000000, + 0, + 0, + 0, + nil, + nil, + ), false, }, { @@ -188,7 +252,13 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 0, 100000000000, - 100000000000), + 100000000000, + 0, + 0, + 0, + nil, + nil, + ), false, }, { @@ -200,7 +270,13 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 0, - 100000000000), + 100000000000, + 0, + 0, + 0, + nil, + nil, + ), false, }, { @@ -212,9 +288,69 @@ func TestConsumerAdditionProposalValidateBasic(t *testing.T) { 10000, 100000000000, 100000000000, - 0), + 0, + 0, + 0, + 0, + nil, + nil, + ), + false, + }, + { + "top N is invalid", + types.NewConsumerAdditionProposal("title", "description", "chainID", initialHeight, []byte("gen_hash"), []byte("bin_hash"), time.Now(), + "0.75", + 10, + "", + 10000, + 100000000000, + 100000000000, + 100000000000, + 10, + 0, + 0, + nil, + nil, + ), + false, + }, + { + "validators power cap is invalid", + types.NewConsumerAdditionProposal("title", "description", "chainID", initialHeight, []byte("gen_hash"), []byte("bin_hash"), time.Now(), + "0.75", + 10, + "", + 10000, + 100000000000, + 100000000000, + 100000000000, + 50, + 101, + 0, + nil, + nil, + ), false, }, + { + "valid proposal with PSS features", + types.NewConsumerAdditionProposal("title", "description", "chainID", initialHeight, []byte("gen_hash"), []byte("bin_hash"), time.Now(), + "0.75", + 10, + "", + 10000, + 100000000000, + 100000000000, + 100000000000, + 0, + 34, + 101, + []string{"addr1"}, + []string{"addr2", "addr3"}, + ), + true, + }, } for _, tc := range testCases { @@ -236,7 +372,12 @@ func TestMarshalConsumerAdditionProposal(t *testing.T) { 10000, 100000000000, 100000000000, - 100000000000) + 100000000000, + 0, + 0, + 0, + nil, + nil) cccp, ok := content.(*types.ConsumerAdditionProposal) require.True(t, ok) @@ -278,7 +419,12 @@ func TestConsumerAdditionProposalString(t *testing.T) { 500000, 100000000000, 10000000000, - 100000000000) + 100000000000, + 0, + 0, + 0, + []string{}, + []string{}) expect := fmt.Sprintf(`CreateConsumerChain Proposal Title: title @@ -354,3 +500,91 @@ func TestChangeRewardDenomsProposalValidateBasic(t *testing.T) { }) } } + +func TestConsumerModificationProposalValidateBasic(t *testing.T) { + testCases := []struct { + name string + proposal govv1beta1.Content + expPass bool + }{ + { + "success", + types.NewConsumerModificationProposal("title", "description", "chainID", + 50, + 100, + 34, + []string{"addr1"}, + nil, + ), + true, + }, + { + "invalid chain id", + types.NewConsumerModificationProposal("title", "description", " ", + 0, + 0, + 0, + nil, + nil, + ), + false, + }, + { + "top N is invalid", + types.NewConsumerModificationProposal("title", "description", "chainID", + 10, + 0, + 0, + nil, + nil, + ), + false, + }, + { + "validators power cap is invalid", + types.NewConsumerModificationProposal("title", "description", "chainID", + 50, + 101, + 0, + nil, + nil, + ), + false, + }, + { + "valid proposal", + types.NewConsumerModificationProposal("title", "description", "chainID", + 0, + 34, + 101, + []string{"addr1"}, + []string{"addr2", "addr3"}, + ), + true, + }, + } + + for _, tc := range testCases { + + err := tc.proposal.ValidateBasic() + if tc.expPass { + require.NoError(t, err, "valid case: %s should not return error. got %w", tc.name, err) + } else { + require.Error(t, err, "invalid case: '%s' must return error but got none", tc.name) + } + } +} + +func TestValidatePSSFeatures(t *testing.T) { + require.NoError(t, types.ValidatePSSFeatures(0, 0)) + require.NoError(t, types.ValidatePSSFeatures(50, 0)) + require.NoError(t, types.ValidatePSSFeatures(100, 0)) + require.NoError(t, types.ValidatePSSFeatures(0, 10)) + require.NoError(t, types.ValidatePSSFeatures(0, 100)) + require.NoError(t, types.ValidatePSSFeatures(50, 100)) + + require.Error(t, types.ValidatePSSFeatures(10, 0)) + require.Error(t, types.ValidatePSSFeatures(49, 0)) + require.Error(t, types.ValidatePSSFeatures(101, 0)) + require.Error(t, types.ValidatePSSFeatures(50, 101)) +} diff --git a/x/ccv/provider/types/msg.go b/x/ccv/provider/types/msg.go index d7b9d14c12..058ee1d2e5 100644 --- a/x/ccv/provider/types/msg.go +++ b/x/ccv/provider/types/msg.go @@ -23,6 +23,9 @@ const ( TypeMsgAssignConsumerKey = "assign_consumer_key" TypeMsgSubmitConsumerMisbehaviour = "submit_consumer_misbehaviour" TypeMsgSubmitConsumerDoubleVoting = "submit_consumer_double_vote" + TypeMsgOptIn = "opt_in" + TypeMsgOptOut = "opt_out" + TypeMsgSetConsumerCommissionRate = "set_consumer_commission_rate" ) var ( @@ -32,6 +35,9 @@ var ( _ sdk.Msg = (*MsgChangeRewardDenoms)(nil) _ sdk.Msg = (*MsgSubmitConsumerMisbehaviour)(nil) _ sdk.Msg = (*MsgSubmitConsumerDoubleVoting)(nil) + _ sdk.Msg = (*MsgOptIn)(nil) + _ sdk.Msg = (*MsgOptOut)(nil) + _ sdk.Msg = (*MsgSetConsumerCommissionRate)(nil) _ sdk.HasValidateBasic = (*MsgAssignConsumerKey)(nil) _ sdk.HasValidateBasic = (*MsgConsumerAddition)(nil) @@ -39,6 +45,9 @@ var ( _ sdk.HasValidateBasic = (*MsgChangeRewardDenoms)(nil) _ sdk.HasValidateBasic = (*MsgSubmitConsumerMisbehaviour)(nil) _ sdk.HasValidateBasic = (*MsgSubmitConsumerDoubleVoting)(nil) + _ sdk.HasValidateBasic = (*MsgOptIn)(nil) + _ sdk.HasValidateBasic = (*MsgOptOut)(nil) + _ sdk.HasValidateBasic = (*MsgSetConsumerCommissionRate)(nil) ) // NewMsgAssignConsumerKey creates a new MsgAssignConsumerKey instance. @@ -297,6 +306,148 @@ func (msg *MsgConsumerRemoval) ValidateBasic() error { return nil } +// NewMsgOptIn creates a new NewMsgOptIn instance. +func NewMsgOptIn(chainID string, providerValidatorAddress sdk.ValAddress, consumerConsensusPubKey, signer string) (*MsgOptIn, error) { + return &MsgOptIn{ + ChainId: chainID, + ProviderAddr: providerValidatorAddress.String(), + ConsumerKey: consumerConsensusPubKey, + Signer: signer, + }, nil +} + +// Type implements the sdk.Msg interface. +func (msg MsgOptIn) Type() string { + return TypeMsgOptIn +} + +// Route implements the sdk.Msg interface. +func (msg MsgOptIn) Route() string { return RouterKey } + +// GetSigners implements the sdk.Msg interface. It returns the address(es) that +// must sign over msg.GetSignBytes(). +func (msg MsgOptIn) GetSigners() []sdk.AccAddress { + valAddr, err := sdk.ValAddressFromBech32(msg.ProviderAddr) + if err != nil { + // same behavior as in cosmos-sdk + panic(err) + } + return []sdk.AccAddress{valAddr.Bytes()} +} + +// ValidateBasic implements the sdk.Msg interface. +func (msg MsgOptIn) ValidateBasic() error { + if strings.TrimSpace(msg.ChainId) == "" { + return errorsmod.Wrapf(ErrInvalidConsumerChainID, "chainId cannot be blank") + } + // It is possible to opt in to validate on consumer chains that are not yet approved. + // This can only be done by a signing validator, but it is still sensible + // to limit the chainID size to prevent abuse. + if 128 < len(msg.ChainId) { + return errorsmod.Wrapf(ErrInvalidConsumerChainID, "chainId cannot exceed 128 length") + } + _, err := sdk.ValAddressFromBech32(msg.ProviderAddr) + if err != nil { + return ErrInvalidProviderAddress + } + + if msg.ConsumerKey != "" { + if _, _, err := ParseConsumerKeyFromJson(msg.ConsumerKey); err != nil { + return ErrInvalidConsumerConsensusPubKey + } + } + return nil +} + +// NewMsgOptOut creates a new NewMsgOptIn instance. +func NewMsgOptOut(chainID string, providerValidatorAddress sdk.ValAddress, signer string) (*MsgOptOut, error) { + return &MsgOptOut{ + ChainId: chainID, + ProviderAddr: providerValidatorAddress.String(), + Signer: signer, + }, nil +} + +// Type implements the sdk.Msg interface. +func (msg MsgOptOut) Type() string { + return TypeMsgOptOut +} + +// Route implements the sdk.Msg interface. +func (msg MsgOptOut) Route() string { return RouterKey } + +// GetSigners implements the sdk.Msg interface. It returns the address(es) that +// must sign over msg.GetSignBytes(). +func (msg MsgOptOut) GetSigners() []sdk.AccAddress { + valAddr, err := sdk.ValAddressFromBech32(msg.ProviderAddr) + if err != nil { + // same behavior as in cosmos-sdk + panic(err) + } + return []sdk.AccAddress{valAddr.Bytes()} +} + +// GetSignBytes returns the message bytes to sign over. +func (msg MsgOptOut) GetSignBytes() []byte { + bz := ccvtypes.ModuleCdc.MustMarshalJSON(&msg) + return sdk.MustSortJSON(bz) +} + +// ValidateBasic implements the sdk.Msg interface. +func (msg MsgOptOut) ValidateBasic() error { + if strings.TrimSpace(msg.ChainId) == "" { + return errorsmod.Wrapf(ErrInvalidConsumerChainID, "chainId cannot be blank") + } + // It is possible to assign keys for consumer chains that are not yet approved. + // This can only be done by a signing validator, but it is still sensible + // to limit the chainID size to prevent abuse. + if 128 < len(msg.ChainId) { + return errorsmod.Wrapf(ErrInvalidConsumerChainID, "chainId cannot exceed 128 length") + } + _, err := sdk.ValAddressFromBech32(msg.ProviderAddr) + if err != nil { + return ErrInvalidProviderAddress + } + return nil +} + +// NewMsgSetConsumerCommissionRate creates a new MsgSetConsumerCommissionRate msg instance. +func NewMsgSetConsumerCommissionRate(chainID string, commission math.LegacyDec, providerValidatorAddress sdk.ValAddress) *MsgSetConsumerCommissionRate { + return &MsgSetConsumerCommissionRate{ + ChainId: chainID, + Rate: commission, + ProviderAddr: providerValidatorAddress.String(), + } +} + +func (msg MsgSetConsumerCommissionRate) Route() string { + return RouterKey +} + +func (msg MsgSetConsumerCommissionRate) Type() string { + return TypeMsgSetConsumerCommissionRate +} + +func (msg MsgSetConsumerCommissionRate) ValidateBasic() error { + if strings.TrimSpace(msg.ChainId) == "" { + return errorsmod.Wrapf(ErrInvalidConsumerChainID, "chainId cannot be blank") + } + + if 128 < len(msg.ChainId) { + return errorsmod.Wrapf(ErrInvalidConsumerChainID, "chainId cannot exceed 128 length") + } + _, err := sdk.ValAddressFromBech32(msg.ProviderAddr) + if err != nil { + return ErrInvalidProviderAddress + } + + if msg.Rate.IsNegative() || msg.Rate.GT(math.LegacyOneDec()) { + return errorsmod.Wrapf(ErrInvalidConsumerCommissionRate, "consumer commission rate should be in the range [0, 1]") + } + + return nil +} + func (msg *MsgChangeRewardDenoms) ValidateBasic() error { emptyDenomsToAdd := len(msg.DenomsToAdd) == 0 emptyDenomsToRemove := len(msg.DenomsToRemove) == 0 @@ -330,3 +481,17 @@ func (msg *MsgChangeRewardDenoms) ValidateBasic() error { return nil } + +func (msg MsgSetConsumerCommissionRate) GetSigners() []sdk.AccAddress { + valAddr, err := sdk.ValAddressFromBech32(msg.ProviderAddr) + if err != nil { + // same behavior as in cosmos-sdk + panic(err) + } + return []sdk.AccAddress{valAddr.Bytes()} +} + +func (msg MsgSetConsumerCommissionRate) GetSignBytes() []byte { + bz := ccvtypes.ModuleCdc.MustMarshalJSON(&msg) + return sdk.MustSortJSON(bz) +} diff --git a/x/ccv/provider/types/params.go b/x/ccv/provider/types/params.go index ac677004bc..81d69cd7eb 100644 --- a/x/ccv/provider/types/params.go +++ b/x/ccv/provider/types/params.go @@ -42,6 +42,17 @@ const ( // an epoch corresponds to 1 hour (6 * 600 = 3600 seconds). // forcing int64 as the Params KeyTable expects an int64 and not int. DefaultBlocksPerEpoch = int64(600) + + // DefaultNumberOfEpochsToStartReceivingRewards defines the default minimum number of epochs required by a validator to validate + // during so that the validator can start receiving rewards. This would mean that a validator has to be a consumer validator for at least + // `DefaultNumberOfEpochsToStartReceivingRewards * DefaultBlocksPerEpoch` on a consumer chain to start receiving rewards from the chain. + // Note that after a validator starts receiving rewards, the validator would keep receiving rewards every time the + // consumer chain sends an IBC transfer over to the provider. This value only sets a constraint on when a validator + // can first start receiving rewards to avoid cases where a validator just opts in to receive rewards and then opts out + // immediately afterward. + // Current default values for blocks per epoch corresponds to about 1 hour, so with 24 being the + // minimum amount of epochs, this would imply that a validator has to validate at least for 1 day to receive rewards. + DefaultNumberOfEpochsToStartReceivingRewards = int64(24) ) // Reflection based keys for params subspace @@ -49,14 +60,15 @@ const ( // Use x/ccv/provider/keeper/params instead // [DEPRECATED] var ( - KeyTemplateClient = []byte("TemplateClient") - KeyTrustingPeriodFraction = []byte("TrustingPeriodFraction") - KeyInitTimeoutPeriod = []byte("InitTimeoutPeriod") - KeyVscTimeoutPeriod = []byte("VscTimeoutPeriod") - KeySlashMeterReplenishPeriod = []byte("SlashMeterReplenishPeriod") - KeySlashMeterReplenishFraction = []byte("SlashMeterReplenishFraction") - KeyConsumerRewardDenomRegistrationFee = []byte("ConsumerRewardDenomRegistrationFee") - KeyBlocksPerEpoch = []byte("BlocksPerEpoch") + KeyTemplateClient = []byte("TemplateClient") + KeyTrustingPeriodFraction = []byte("TrustingPeriodFraction") + KeyInitTimeoutPeriod = []byte("InitTimeoutPeriod") + KeyVscTimeoutPeriod = []byte("VscTimeoutPeriod") + KeySlashMeterReplenishPeriod = []byte("SlashMeterReplenishPeriod") + KeySlashMeterReplenishFraction = []byte("SlashMeterReplenishFraction") + KeyConsumerRewardDenomRegistrationFee = []byte("ConsumerRewardDenomRegistrationFee") + KeyBlocksPerEpoch = []byte("BlocksPerEpoch") + KeyNumberOfEpochsToStartReceivingRewards = []byte("NumberOfEpochsToStartReceivingRewards") ) // ParamKeyTable returns a key table with the necessary registered provider params @@ -75,17 +87,19 @@ func NewParams( slashMeterReplenishFraction string, consumerRewardDenomRegistrationFee sdk.Coin, blocksPerEpoch int64, + numberOfEpochsToStartReceivingRewards int64, ) Params { return Params{ - TemplateClient: cs, - TrustingPeriodFraction: trustingPeriodFraction, - CcvTimeoutPeriod: ccvTimeoutPeriod, - InitTimeoutPeriod: initTimeoutPeriod, - VscTimeoutPeriod: vscTimeoutPeriod, - SlashMeterReplenishPeriod: slashMeterReplenishPeriod, - SlashMeterReplenishFraction: slashMeterReplenishFraction, - ConsumerRewardDenomRegistrationFee: consumerRewardDenomRegistrationFee, - BlocksPerEpoch: blocksPerEpoch, + TemplateClient: cs, + TrustingPeriodFraction: trustingPeriodFraction, + CcvTimeoutPeriod: ccvTimeoutPeriod, + InitTimeoutPeriod: initTimeoutPeriod, + VscTimeoutPeriod: vscTimeoutPeriod, + SlashMeterReplenishPeriod: slashMeterReplenishPeriod, + SlashMeterReplenishFraction: slashMeterReplenishFraction, + ConsumerRewardDenomRegistrationFee: consumerRewardDenomRegistrationFee, + BlocksPerEpoch: blocksPerEpoch, + NumberOfEpochsToStartReceivingRewards: numberOfEpochsToStartReceivingRewards, } } @@ -117,6 +131,7 @@ func DefaultParams() Params { Amount: math.NewInt(10000000), }, DefaultBlocksPerEpoch, + DefaultNumberOfEpochsToStartReceivingRewards, ) } @@ -149,9 +164,12 @@ func (p Params) Validate() error { if err := ValidateCoin(p.ConsumerRewardDenomRegistrationFee); err != nil { return fmt.Errorf("consumer reward denom registration fee is invalid: %s", err) } - if err := ccvtypes.ValidateInt64(p.BlocksPerEpoch); err != nil { + if err := ccvtypes.ValidatePositiveInt64(p.BlocksPerEpoch); err != nil { return fmt.Errorf("blocks per epoch is invalid: %s", err) } + if err := ccvtypes.ValidatePositiveInt64(p.NumberOfEpochsToStartReceivingRewards); err != nil { + return fmt.Errorf("number of epochs to start receiving rewards is invalid: %s", err) + } return nil } @@ -167,6 +185,7 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { paramtypes.NewParamSetPair(KeySlashMeterReplenishFraction, p.SlashMeterReplenishFraction, ccvtypes.ValidateStringFraction), paramtypes.NewParamSetPair(KeyConsumerRewardDenomRegistrationFee, p.ConsumerRewardDenomRegistrationFee, ValidateCoin), paramtypes.NewParamSetPair(KeyBlocksPerEpoch, p.BlocksPerEpoch, ccvtypes.ValidatePositiveInt64), + paramtypes.NewParamSetPair(KeyNumberOfEpochsToStartReceivingRewards, p.NumberOfEpochsToStartReceivingRewards, ccvtypes.ValidatePositiveInt64), } } diff --git a/x/ccv/provider/types/params_test.go b/x/ccv/provider/types/params_test.go index 675ddd0bc5..8ff8da58f1 100644 --- a/x/ccv/provider/types/params_test.go +++ b/x/ccv/provider/types/params_test.go @@ -25,39 +25,43 @@ func TestValidateParams(t *testing.T) { {"custom valid params", types.NewParams( ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), true}, + "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 24), true}, {"custom invalid params", types.NewParams( ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, 0, clienttypes.Height{}, nil, []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, + "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 24), false}, {"blank client", types.NewParams(&ibctmtypes.ClientState{}, - "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, - {"nil client", types.NewParams(nil, "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, + "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 24), false}, + {"nil client", types.NewParams(nil, "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 24), false}, // Check if "0.00" is valid or if a zero dec TrustFraction needs to return an error {"0 trusting period fraction", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.00", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), true}, + "0.00", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 24), true}, {"0 ccv timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", 0, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, + "0.33", 0, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 24), false}, {"0 init timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, 0, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, + "0.33", time.Hour, 0, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 24), false}, {"0 vsc timeout period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 0, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, + "0.33", time.Hour, time.Hour, 0, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 24), false}, {"0 slash meter replenish period", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 24*time.Hour, 0, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, + "0.33", time.Hour, time.Hour, 24*time.Hour, 0, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 24), false}, {"slash meter replenish fraction over 1", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "1.5", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000), false}, + "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "1.5", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 24), false}, {"invalid consumer reward denom registration fee denom", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: math.NewInt(10000000)}, 1000), false}, + "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "st", Amount: math.NewInt(10000000)}, 1000, 24), false}, {"invalid consumer reward denom registration fee amount", types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(-10000000)}, 1000), false}, + "0.33", time.Hour, time.Hour, 24*time.Hour, time.Hour, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(-10000000)}, 1000, 24), false}, + {"invalid number of epochs to start receiving rewards", types.NewParams( + ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, + time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), + "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", sdk.Coin{Denom: "stake", Amount: math.NewInt(10000000)}, 1000, 0), false}, } for _, tc := range testCases { diff --git a/x/ccv/provider/types/provider.pb.go b/x/ccv/provider/types/provider.pb.go index 2c9514c712..e602595797 100644 --- a/x/ccv/provider/types/provider.pb.go +++ b/x/ccv/provider/types/provider.pb.go @@ -8,7 +8,9 @@ import ( fmt "fmt" crypto "github.com/cometbft/cometbft/proto/tendermint/crypto" _ "github.com/cosmos/cosmos-proto" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" types2 "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" @@ -92,6 +94,25 @@ type ConsumerAdditionProposal struct { // chain. it is most relevant for chains performing a sovereign to consumer // changeover in order to maintain the existing ibc transfer channel DistributionTransmissionChannel string `protobuf:"bytes,14,opt,name=distribution_transmission_channel,json=distributionTransmissionChannel,proto3" json:"distribution_transmission_channel,omitempty"` + // Corresponds to the percentage of validators that have to validate the chain under the Top N case. + // For example, 53 corresponds to a Top 53% chain, meaning that the top 53% provider validators by voting power + // have to validate the proposed consumer chain. top_N can either be 0 or any value in [50, 100]. + // A chain can join with top_N == 0 as an Opt In chain, or with top_N ∈ [50, 100] as a Top N chain. + Top_N uint32 `protobuf:"varint,15,opt,name=top_N,json=topN,proto3" json:"top_N,omitempty"` + // Corresponds to the maximum power (percentage-wise) a validator can have on the consumer chain. For instance, if + // `validators_power_cap` is set to 32, it means that no validator can have more than 32% of the voting power on the + // consumer chain. Note that this might not be feasible. For example, think of a consumer chain with only + // 5 validators and with `validators_power_cap` set to 10%. In such a scenario, at least one validator would need + // to have more than 20% of the total voting power. Therefore, `validators_power_cap` operates on a best-effort basis. + ValidatorsPowerCap uint32 `protobuf:"varint,16,opt,name=validators_power_cap,json=validatorsPowerCap,proto3" json:"validators_power_cap,omitempty"` + // Corresponds to the maximum number of validators that can validate a consumer chain. + // Only applicable to Opt In chains. Setting `validator_set_cap` on a Top N chain is a no-op. + ValidatorSetCap uint32 `protobuf:"varint,17,opt,name=validator_set_cap,json=validatorSetCap,proto3" json:"validator_set_cap,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that are the ONLY ones that can validate + // the consumer chain. + Allowlist []string `protobuf:"bytes,18,rep,name=allowlist,proto3" json:"allowlist,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that CANNOT validate the consumer chain. + Denylist []string `protobuf:"bytes,19,rep,name=denylist,proto3" json:"denylist,omitempty"` } func (m *ConsumerAdditionProposal) Reset() { *m = ConsumerAdditionProposal{} } @@ -204,6 +225,125 @@ func (m *ConsumerRemovalProposal) GetStopTime() time.Time { return time.Time{} } +// ConsumerModificationProposal is a governance proposal on the provider chain to modify parameters of a running +// consumer chain. If it passes, the consumer chain's state is updated to take into account the newest params. +type ConsumerModificationProposal struct { + // the title of the proposal + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + // the description of the proposal + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + // the chain-id of the consumer chain to be modified + ChainId string `protobuf:"bytes,3,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // Corresponds to the percentage of validators that have to validate the chain under the Top N case. + // For example, 53 corresponds to a Top 53% chain, meaning that the top 53% provider validators by voting power + // have to validate the proposed consumer chain. top_N can either be 0 or any value in [50, 100]. + // A chain can join with top_N == 0 as an Opt In chain, or with top_N ∈ [50, 100] as a Top N chain. + Top_N uint32 `protobuf:"varint,4,opt,name=top_N,json=topN,proto3" json:"top_N,omitempty"` + // Corresponds to the maximum power (percentage-wise) a validator can have on the consumer chain. For instance, if + // `validators_power_cap` is set to 32, it means that no validator can have more than 32% of the voting power on the + // consumer chain. Note that this might not be feasible. For example, think of a consumer chain with only + // 5 validators and with `validators_power_cap` set to 10%. In such a scenario, at least one validator would need + // to have more than 20% of the total voting power. Therefore, `validators_power_cap` operates on a best-effort basis. + ValidatorsPowerCap uint32 `protobuf:"varint,5,opt,name=validators_power_cap,json=validatorsPowerCap,proto3" json:"validators_power_cap,omitempty"` + // Corresponds to the maximum number of validators that can validate a consumer chain. + // Only applicable to Opt In chains. Setting `validator_set_cap` on a Top N chain is a no-op. + ValidatorSetCap uint32 `protobuf:"varint,6,opt,name=validator_set_cap,json=validatorSetCap,proto3" json:"validator_set_cap,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that are the ONLY ones that can validate + // the consumer chain. + Allowlist []string `protobuf:"bytes,7,rep,name=allowlist,proto3" json:"allowlist,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that CANNOT validate the consumer chain. + Denylist []string `protobuf:"bytes,8,rep,name=denylist,proto3" json:"denylist,omitempty"` +} + +func (m *ConsumerModificationProposal) Reset() { *m = ConsumerModificationProposal{} } +func (m *ConsumerModificationProposal) String() string { return proto.CompactTextString(m) } +func (*ConsumerModificationProposal) ProtoMessage() {} +func (*ConsumerModificationProposal) Descriptor() ([]byte, []int) { + return fileDescriptor_f22ec409a72b7b72, []int{2} +} +func (m *ConsumerModificationProposal) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ConsumerModificationProposal) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ConsumerModificationProposal.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ConsumerModificationProposal) XXX_Merge(src proto.Message) { + xxx_messageInfo_ConsumerModificationProposal.Merge(m, src) +} +func (m *ConsumerModificationProposal) XXX_Size() int { + return m.Size() +} +func (m *ConsumerModificationProposal) XXX_DiscardUnknown() { + xxx_messageInfo_ConsumerModificationProposal.DiscardUnknown(m) +} + +var xxx_messageInfo_ConsumerModificationProposal proto.InternalMessageInfo + +func (m *ConsumerModificationProposal) GetTitle() string { + if m != nil { + return m.Title + } + return "" +} + +func (m *ConsumerModificationProposal) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *ConsumerModificationProposal) GetChainId() string { + if m != nil { + return m.ChainId + } + return "" +} + +func (m *ConsumerModificationProposal) GetTop_N() uint32 { + if m != nil { + return m.Top_N + } + return 0 +} + +func (m *ConsumerModificationProposal) GetValidatorsPowerCap() uint32 { + if m != nil { + return m.ValidatorsPowerCap + } + return 0 +} + +func (m *ConsumerModificationProposal) GetValidatorSetCap() uint32 { + if m != nil { + return m.ValidatorSetCap + } + return 0 +} + +func (m *ConsumerModificationProposal) GetAllowlist() []string { + if m != nil { + return m.Allowlist + } + return nil +} + +func (m *ConsumerModificationProposal) GetDenylist() []string { + if m != nil { + return m.Denylist + } + return nil +} + // EquivocationProposal is a governance proposal on the provider chain to // punish a validator for equivocation on a consumer chain. // @@ -225,7 +365,7 @@ func (m *EquivocationProposal) Reset() { *m = EquivocationProposal{} } func (m *EquivocationProposal) String() string { return proto.CompactTextString(m) } func (*EquivocationProposal) ProtoMessage() {} func (*EquivocationProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{2} + return fileDescriptor_f22ec409a72b7b72, []int{3} } func (m *EquivocationProposal) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -293,7 +433,7 @@ func (m *ChangeRewardDenomsProposal) Reset() { *m = ChangeRewardDenomsPr func (m *ChangeRewardDenomsProposal) String() string { return proto.CompactTextString(m) } func (*ChangeRewardDenomsProposal) ProtoMessage() {} func (*ChangeRewardDenomsProposal) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{3} + return fileDescriptor_f22ec409a72b7b72, []int{4} } func (m *ChangeRewardDenomsProposal) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -374,7 +514,7 @@ func (m *GlobalSlashEntry) Reset() { *m = GlobalSlashEntry{} } func (m *GlobalSlashEntry) String() string { return proto.CompactTextString(m) } func (*GlobalSlashEntry) ProtoMessage() {} func (*GlobalSlashEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{4} + return fileDescriptor_f22ec409a72b7b72, []int{5} } func (m *GlobalSlashEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -457,13 +597,15 @@ type Params struct { ConsumerRewardDenomRegistrationFee types2.Coin `protobuf:"bytes,9,opt,name=consumer_reward_denom_registration_fee,json=consumerRewardDenomRegistrationFee,proto3" json:"consumer_reward_denom_registration_fee"` // The number of blocks that comprise an epoch. BlocksPerEpoch int64 `protobuf:"varint,10,opt,name=blocks_per_epoch,json=blocksPerEpoch,proto3" json:"blocks_per_epoch,omitempty"` + // The number of epochs a validator has to validate a consumer chain in order to start receiving rewards from that chain. + NumberOfEpochsToStartReceivingRewards int64 `protobuf:"varint,11,opt,name=number_of_epochs_to_start_receiving_rewards,json=numberOfEpochsToStartReceivingRewards,proto3" json:"number_of_epochs_to_start_receiving_rewards,omitempty"` } func (m *Params) Reset() { *m = Params{} } func (m *Params) String() string { return proto.CompactTextString(m) } func (*Params) ProtoMessage() {} func (*Params) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{5} + return fileDescriptor_f22ec409a72b7b72, []int{6} } func (m *Params) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -555,6 +697,13 @@ func (m *Params) GetBlocksPerEpoch() int64 { return 0 } +func (m *Params) GetNumberOfEpochsToStartReceivingRewards() int64 { + if m != nil { + return m.NumberOfEpochsToStartReceivingRewards + } + return 0 +} + // SlashAcks contains cons addresses of consumer chain validators // successfully slashed on the provider chain. type SlashAcks struct { @@ -565,7 +714,7 @@ func (m *SlashAcks) Reset() { *m = SlashAcks{} } func (m *SlashAcks) String() string { return proto.CompactTextString(m) } func (*SlashAcks) ProtoMessage() {} func (*SlashAcks) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{6} + return fileDescriptor_f22ec409a72b7b72, []int{7} } func (m *SlashAcks) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -612,7 +761,7 @@ func (m *ConsumerAdditionProposals) Reset() { *m = ConsumerAdditionPropo func (m *ConsumerAdditionProposals) String() string { return proto.CompactTextString(m) } func (*ConsumerAdditionProposals) ProtoMessage() {} func (*ConsumerAdditionProposals) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{7} + return fileDescriptor_f22ec409a72b7b72, []int{8} } func (m *ConsumerAdditionProposals) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -659,7 +808,7 @@ func (m *ConsumerRemovalProposals) Reset() { *m = ConsumerRemovalProposa func (m *ConsumerRemovalProposals) String() string { return proto.CompactTextString(m) } func (*ConsumerRemovalProposals) ProtoMessage() {} func (*ConsumerRemovalProposals) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{8} + return fileDescriptor_f22ec409a72b7b72, []int{9} } func (m *ConsumerRemovalProposals) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -704,7 +853,7 @@ func (m *AddressList) Reset() { *m = AddressList{} } func (m *AddressList) String() string { return proto.CompactTextString(m) } func (*AddressList) ProtoMessage() {} func (*AddressList) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{9} + return fileDescriptor_f22ec409a72b7b72, []int{10} } func (m *AddressList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -750,7 +899,7 @@ func (m *ChannelToChain) Reset() { *m = ChannelToChain{} } func (m *ChannelToChain) String() string { return proto.CompactTextString(m) } func (*ChannelToChain) ProtoMessage() {} func (*ChannelToChain) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{10} + return fileDescriptor_f22ec409a72b7b72, []int{11} } func (m *ChannelToChain) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -804,7 +953,7 @@ func (m *VscUnbondingOps) Reset() { *m = VscUnbondingOps{} } func (m *VscUnbondingOps) String() string { return proto.CompactTextString(m) } func (*VscUnbondingOps) ProtoMessage() {} func (*VscUnbondingOps) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{11} + return fileDescriptor_f22ec409a72b7b72, []int{12} } func (m *VscUnbondingOps) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -859,7 +1008,7 @@ func (m *UnbondingOp) Reset() { *m = UnbondingOp{} } func (m *UnbondingOp) String() string { return proto.CompactTextString(m) } func (*UnbondingOp) ProtoMessage() {} func (*UnbondingOp) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{12} + return fileDescriptor_f22ec409a72b7b72, []int{13} } func (m *UnbondingOp) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -911,7 +1060,7 @@ func (m *InitTimeoutTimestamp) Reset() { *m = InitTimeoutTimestamp{} } func (m *InitTimeoutTimestamp) String() string { return proto.CompactTextString(m) } func (*InitTimeoutTimestamp) ProtoMessage() {} func (*InitTimeoutTimestamp) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{13} + return fileDescriptor_f22ec409a72b7b72, []int{14} } func (m *InitTimeoutTimestamp) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -963,7 +1112,7 @@ func (m *VscSendTimestamp) Reset() { *m = VscSendTimestamp{} } func (m *VscSendTimestamp) String() string { return proto.CompactTextString(m) } func (*VscSendTimestamp) ProtoMessage() {} func (*VscSendTimestamp) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{14} + return fileDescriptor_f22ec409a72b7b72, []int{15} } func (m *VscSendTimestamp) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1015,7 +1164,7 @@ func (m *ValidatorSetChangePackets) Reset() { *m = ValidatorSetChangePac func (m *ValidatorSetChangePackets) String() string { return proto.CompactTextString(m) } func (*ValidatorSetChangePackets) ProtoMessage() {} func (*ValidatorSetChangePackets) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{15} + return fileDescriptor_f22ec409a72b7b72, []int{16} } func (m *ValidatorSetChangePackets) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1061,7 +1210,7 @@ func (m *MaturedUnbondingOps) Reset() { *m = MaturedUnbondingOps{} } func (m *MaturedUnbondingOps) String() string { return proto.CompactTextString(m) } func (*MaturedUnbondingOps) ProtoMessage() {} func (*MaturedUnbondingOps) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{16} + return fileDescriptor_f22ec409a72b7b72, []int{17} } func (m *MaturedUnbondingOps) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1107,7 +1256,7 @@ func (m *ExportedVscSendTimestamp) Reset() { *m = ExportedVscSendTimesta func (m *ExportedVscSendTimestamp) String() string { return proto.CompactTextString(m) } func (*ExportedVscSendTimestamp) ProtoMessage() {} func (*ExportedVscSendTimestamp) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{17} + return fileDescriptor_f22ec409a72b7b72, []int{18} } func (m *ExportedVscSendTimestamp) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1160,7 +1309,7 @@ func (m *KeyAssignmentReplacement) Reset() { *m = KeyAssignmentReplaceme func (m *KeyAssignmentReplacement) String() string { return proto.CompactTextString(m) } func (*KeyAssignmentReplacement) ProtoMessage() {} func (*KeyAssignmentReplacement) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{18} + return fileDescriptor_f22ec409a72b7b72, []int{19} } func (m *KeyAssignmentReplacement) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1223,7 +1372,7 @@ func (m *ValidatorConsumerPubKey) Reset() { *m = ValidatorConsumerPubKey func (m *ValidatorConsumerPubKey) String() string { return proto.CompactTextString(m) } func (*ValidatorConsumerPubKey) ProtoMessage() {} func (*ValidatorConsumerPubKey) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{19} + return fileDescriptor_f22ec409a72b7b72, []int{20} } func (m *ValidatorConsumerPubKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1286,7 +1435,7 @@ func (m *ValidatorByConsumerAddr) Reset() { *m = ValidatorByConsumerAddr func (m *ValidatorByConsumerAddr) String() string { return proto.CompactTextString(m) } func (*ValidatorByConsumerAddr) ProtoMessage() {} func (*ValidatorByConsumerAddr) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{20} + return fileDescriptor_f22ec409a72b7b72, []int{21} } func (m *ValidatorByConsumerAddr) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1348,7 +1497,7 @@ func (m *ConsumerAddrsToPrune) Reset() { *m = ConsumerAddrsToPrune{} } func (m *ConsumerAddrsToPrune) String() string { return proto.CompactTextString(m) } func (*ConsumerAddrsToPrune) ProtoMessage() {} func (*ConsumerAddrsToPrune) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{21} + return fileDescriptor_f22ec409a72b7b72, []int{22} } func (m *ConsumerAddrsToPrune) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1407,13 +1556,18 @@ type ConsumerValidator struct { Power int64 `protobuf:"varint,2,opt,name=power,proto3" json:"power,omitempty"` // public key the validator uses on the consumer chain during this epoch ConsumerPublicKey *crypto.PublicKey `protobuf:"bytes,3,opt,name=consumer_public_key,json=consumerPublicKey,proto3" json:"consumer_public_key,omitempty"` + // height the validator had when it FIRST became a consumer validator + // If a validator becomes a consumer validator at height `H` and is continuously a consumer validator for all the upcoming + // epochs, then the height of the validator SHOULD remain `H`. This height only resets to a different height if a validator + // stops being a consumer validator during an epoch and later becomes again a consumer validator. + JoinHeight int64 `protobuf:"varint,4,opt,name=join_height,json=joinHeight,proto3" json:"join_height,omitempty"` } func (m *ConsumerValidator) Reset() { *m = ConsumerValidator{} } func (m *ConsumerValidator) String() string { return proto.CompactTextString(m) } func (*ConsumerValidator) ProtoMessage() {} func (*ConsumerValidator) Descriptor() ([]byte, []int) { - return fileDescriptor_f22ec409a72b7b72, []int{22} + return fileDescriptor_f22ec409a72b7b72, []int{23} } func (m *ConsumerValidator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1463,9 +1617,64 @@ func (m *ConsumerValidator) GetConsumerPublicKey() *crypto.PublicKey { return nil } +func (m *ConsumerValidator) GetJoinHeight() int64 { + if m != nil { + return m.JoinHeight + } + return 0 +} + +// ConsumerRewardsAllocation stores the rewards allocated by a consumer chain +// to the consumer rewards pool. It is used to allocate the tokens to the consumer +// opted-in validators and the community pool during BeginBlock. +type ConsumerRewardsAllocation struct { + Rewards github_com_cosmos_cosmos_sdk_types.DecCoins `protobuf:"bytes,1,rep,name=rewards,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.DecCoins" json:"rewards"` +} + +func (m *ConsumerRewardsAllocation) Reset() { *m = ConsumerRewardsAllocation{} } +func (m *ConsumerRewardsAllocation) String() string { return proto.CompactTextString(m) } +func (*ConsumerRewardsAllocation) ProtoMessage() {} +func (*ConsumerRewardsAllocation) Descriptor() ([]byte, []int) { + return fileDescriptor_f22ec409a72b7b72, []int{24} +} +func (m *ConsumerRewardsAllocation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ConsumerRewardsAllocation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ConsumerRewardsAllocation.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ConsumerRewardsAllocation) XXX_Merge(src proto.Message) { + xxx_messageInfo_ConsumerRewardsAllocation.Merge(m, src) +} +func (m *ConsumerRewardsAllocation) XXX_Size() int { + return m.Size() +} +func (m *ConsumerRewardsAllocation) XXX_DiscardUnknown() { + xxx_messageInfo_ConsumerRewardsAllocation.DiscardUnknown(m) +} + +var xxx_messageInfo_ConsumerRewardsAllocation proto.InternalMessageInfo + +func (m *ConsumerRewardsAllocation) GetRewards() github_com_cosmos_cosmos_sdk_types.DecCoins { + if m != nil { + return m.Rewards + } + return nil +} + func init() { proto.RegisterType((*ConsumerAdditionProposal)(nil), "interchain_security.ccv.provider.v1.ConsumerAdditionProposal") proto.RegisterType((*ConsumerRemovalProposal)(nil), "interchain_security.ccv.provider.v1.ConsumerRemovalProposal") + proto.RegisterType((*ConsumerModificationProposal)(nil), "interchain_security.ccv.provider.v1.ConsumerModificationProposal") proto.RegisterType((*EquivocationProposal)(nil), "interchain_security.ccv.provider.v1.EquivocationProposal") proto.RegisterType((*ChangeRewardDenomsProposal)(nil), "interchain_security.ccv.provider.v1.ChangeRewardDenomsProposal") proto.RegisterType((*GlobalSlashEntry)(nil), "interchain_security.ccv.provider.v1.GlobalSlashEntry") @@ -1487,6 +1696,7 @@ func init() { proto.RegisterType((*ValidatorByConsumerAddr)(nil), "interchain_security.ccv.provider.v1.ValidatorByConsumerAddr") proto.RegisterType((*ConsumerAddrsToPrune)(nil), "interchain_security.ccv.provider.v1.ConsumerAddrsToPrune") proto.RegisterType((*ConsumerValidator)(nil), "interchain_security.ccv.provider.v1.ConsumerValidator") + proto.RegisterType((*ConsumerRewardsAllocation)(nil), "interchain_security.ccv.provider.v1.ConsumerRewardsAllocation") } func init() { @@ -1494,119 +1704,136 @@ func init() { } var fileDescriptor_f22ec409a72b7b72 = []byte{ - // 1790 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0x4f, 0x6f, 0x1b, 0xc7, - 0x15, 0xd7, 0x92, 0x94, 0x2c, 0x3e, 0x4a, 0x94, 0xb4, 0x52, 0x62, 0x4a, 0x55, 0x29, 0x79, 0xd3, - 0xb8, 0x2a, 0x52, 0x2f, 0x2b, 0x05, 0x01, 0x02, 0xa1, 0x41, 0x20, 0x51, 0x4e, 0x2c, 0x2b, 0x89, - 0x95, 0x95, 0x2a, 0xa3, 0xed, 0x61, 0x31, 0x9c, 0x1d, 0x93, 0x03, 0x2d, 0x77, 0xd6, 0x33, 0xb3, - 0xeb, 0xf0, 0xd2, 0x73, 0x8f, 0xe9, 0x2d, 0xe8, 0xa5, 0x69, 0x81, 0x7e, 0x83, 0x7e, 0x82, 0x9e, - 0x82, 0x5e, 0x9a, 0x63, 0x4f, 0x69, 0x61, 0x1f, 0xfb, 0x19, 0x0a, 0x14, 0x33, 0xfb, 0x97, 0x94, - 0x64, 0xd3, 0x48, 0x7b, 0xdb, 0x79, 0xf3, 0xde, 0xef, 0xfd, 0x7f, 0x6f, 0x48, 0xd8, 0xa3, 0x81, - 0x24, 0x1c, 0x0f, 0x10, 0x0d, 0x5c, 0x41, 0x70, 0xc4, 0xa9, 0x1c, 0x75, 0x30, 0x8e, 0x3b, 0x21, - 0x67, 0x31, 0xf5, 0x08, 0xef, 0xc4, 0xbb, 0xf9, 0xb7, 0x1d, 0x72, 0x26, 0x99, 0xf9, 0xd6, 0x35, - 0x32, 0x36, 0xc6, 0xb1, 0x9d, 0xf3, 0xc5, 0xbb, 0x1b, 0x6f, 0xdf, 0x04, 0x1c, 0xef, 0x76, 0x9e, - 0x51, 0x4e, 0x12, 0xac, 0x8d, 0xb5, 0x3e, 0xeb, 0x33, 0xfd, 0xd9, 0x51, 0x5f, 0x29, 0x75, 0xab, - 0xcf, 0x58, 0xdf, 0x27, 0x1d, 0x7d, 0xea, 0x45, 0x4f, 0x3a, 0x92, 0x0e, 0x89, 0x90, 0x68, 0x18, - 0xa6, 0x0c, 0xed, 0x49, 0x06, 0x2f, 0xe2, 0x48, 0x52, 0x16, 0x64, 0x00, 0xb4, 0x87, 0x3b, 0x98, - 0x71, 0xd2, 0xc1, 0x3e, 0x25, 0x81, 0x54, 0x5a, 0x93, 0xaf, 0x94, 0xa1, 0xa3, 0x18, 0x7c, 0xda, - 0x1f, 0xc8, 0x84, 0x2c, 0x3a, 0x92, 0x04, 0x1e, 0xe1, 0x43, 0x9a, 0x30, 0x17, 0xa7, 0x54, 0x60, - 0xb3, 0x74, 0x8f, 0xf9, 0x28, 0x94, 0xac, 0x73, 0x49, 0x46, 0x22, 0xbd, 0xbd, 0x8b, 0x99, 0x18, - 0x32, 0xd1, 0x21, 0xca, 0xff, 0x00, 0x93, 0x4e, 0xbc, 0xdb, 0x23, 0x12, 0xed, 0xe6, 0x84, 0xcc, - 0xee, 0x94, 0xaf, 0x87, 0x44, 0xc1, 0x83, 0x19, 0xcd, 0xec, 0x5e, 0x4f, 0xee, 0xdd, 0x24, 0x22, - 0xc9, 0x21, 0xb9, 0xb2, 0xfe, 0x33, 0x07, 0xad, 0x2e, 0x0b, 0x44, 0x34, 0x24, 0xfc, 0xc0, 0xf3, - 0xa8, 0xf2, 0xf6, 0x94, 0xb3, 0x90, 0x09, 0xe4, 0x9b, 0x6b, 0x30, 0x2b, 0xa9, 0xf4, 0x49, 0xcb, - 0xd8, 0x36, 0x76, 0xea, 0x4e, 0x72, 0x30, 0xb7, 0xa1, 0xe1, 0x11, 0x81, 0x39, 0x0d, 0x15, 0x73, - 0xab, 0xa2, 0xef, 0xca, 0x24, 0x73, 0x1d, 0xe6, 0x93, 0x14, 0x51, 0xaf, 0x55, 0xd5, 0xd7, 0xb7, - 0xf4, 0xf9, 0xd8, 0x33, 0x3f, 0x86, 0x26, 0x0d, 0xa8, 0xa4, 0xc8, 0x77, 0x07, 0x44, 0x05, 0xaa, - 0x55, 0xdb, 0x36, 0x76, 0x1a, 0x7b, 0x1b, 0x36, 0xed, 0x61, 0x5b, 0xc5, 0xd6, 0x4e, 0x23, 0x1a, - 0xef, 0xda, 0x0f, 0x34, 0xc7, 0x61, 0xed, 0x9b, 0xef, 0xb6, 0x66, 0x9c, 0xc5, 0x54, 0x2e, 0x21, - 0x9a, 0x77, 0x60, 0xa1, 0x4f, 0x02, 0x22, 0xa8, 0x70, 0x07, 0x48, 0x0c, 0x5a, 0xb3, 0xdb, 0xc6, - 0xce, 0x82, 0xd3, 0x48, 0x69, 0x0f, 0x90, 0x18, 0x98, 0x5b, 0xd0, 0xe8, 0xd1, 0x00, 0xf1, 0x51, - 0xc2, 0x31, 0xa7, 0x39, 0x20, 0x21, 0x69, 0x86, 0x2e, 0x80, 0x08, 0xd1, 0xb3, 0xc0, 0x55, 0x85, - 0xd0, 0xba, 0x95, 0x1a, 0x92, 0x14, 0x81, 0x9d, 0x15, 0x81, 0x7d, 0x9e, 0x55, 0xc9, 0xe1, 0xbc, - 0x32, 0xe4, 0xcb, 0x7f, 0x6e, 0x19, 0x4e, 0x5d, 0xcb, 0xa9, 0x1b, 0xf3, 0x33, 0x58, 0x8e, 0x82, - 0x1e, 0x0b, 0x3c, 0x1a, 0xf4, 0xdd, 0x90, 0x70, 0xca, 0xbc, 0xd6, 0xbc, 0x86, 0x5a, 0xbf, 0x02, - 0x75, 0x94, 0xd6, 0x53, 0x82, 0xf4, 0x95, 0x42, 0x5a, 0xca, 0x85, 0x4f, 0xb5, 0xac, 0xf9, 0x39, - 0x98, 0x18, 0xc7, 0xda, 0x24, 0x16, 0xc9, 0x0c, 0xb1, 0x3e, 0x3d, 0xe2, 0x32, 0xc6, 0xf1, 0x79, - 0x22, 0x9d, 0x42, 0xfe, 0x1a, 0x6e, 0x4b, 0x8e, 0x02, 0xf1, 0x84, 0xf0, 0x49, 0x5c, 0x98, 0x1e, - 0xf7, 0x8d, 0x0c, 0x63, 0x1c, 0xfc, 0x01, 0x6c, 0xe3, 0xb4, 0x80, 0x5c, 0x4e, 0x3c, 0x2a, 0x24, - 0xa7, 0xbd, 0x48, 0xc9, 0xba, 0x4f, 0x38, 0xc2, 0xba, 0x46, 0x1a, 0xba, 0x08, 0xda, 0x19, 0x9f, - 0x33, 0xc6, 0xf6, 0x51, 0xca, 0x65, 0x3e, 0x82, 0x1f, 0xf5, 0x7c, 0x86, 0x2f, 0x85, 0x32, 0xce, - 0x1d, 0x43, 0xd2, 0xaa, 0x87, 0x54, 0x08, 0x85, 0xb6, 0xb0, 0x6d, 0xec, 0x54, 0x9d, 0x3b, 0x09, - 0xef, 0x29, 0xe1, 0x47, 0x25, 0xce, 0xf3, 0x12, 0xa3, 0x79, 0x0f, 0xcc, 0x01, 0x15, 0x92, 0x71, - 0x8a, 0x91, 0xef, 0x92, 0x40, 0x72, 0x4a, 0x44, 0x6b, 0x51, 0x8b, 0xaf, 0x14, 0x37, 0xf7, 0x93, - 0x0b, 0xf3, 0x21, 0xdc, 0xb9, 0x51, 0xa9, 0x8b, 0x07, 0x28, 0x08, 0x88, 0xdf, 0x6a, 0x6a, 0x57, - 0xb6, 0xbc, 0x1b, 0x74, 0x76, 0x13, 0xb6, 0xfd, 0xbb, 0xbf, 0xfd, 0x7a, 0x6b, 0xe6, 0xab, 0xaf, - 0xb7, 0x66, 0xfe, 0xf6, 0x97, 0x7b, 0x1b, 0x69, 0xc7, 0xf5, 0x59, 0x6c, 0xa7, 0xdd, 0x69, 0x77, - 0x59, 0x20, 0x49, 0x20, 0xad, 0xbf, 0x1b, 0x70, 0xbb, 0x9b, 0x87, 0x65, 0xc8, 0x62, 0xe4, 0xff, - 0x3f, 0xdb, 0xef, 0x00, 0xea, 0x42, 0xb2, 0x30, 0x29, 0xf8, 0xda, 0x6b, 0x14, 0xfc, 0xbc, 0x12, - 0x53, 0x17, 0xfb, 0xed, 0x57, 0x78, 0xf4, 0x07, 0x03, 0xd6, 0xee, 0x3f, 0x8d, 0x68, 0xcc, 0x30, - 0xfa, 0x9f, 0x4c, 0x93, 0x13, 0x58, 0x24, 0x25, 0x3c, 0xd1, 0xaa, 0x6e, 0x57, 0x77, 0x1a, 0x7b, - 0x6f, 0xdb, 0xa9, 0x11, 0xf9, 0x30, 0xcc, 0x2c, 0x29, 0x6b, 0x77, 0xc6, 0x65, 0xf7, 0x2b, 0x2d, - 0xc3, 0xfa, 0xab, 0x01, 0x1b, 0x2a, 0x4f, 0x7d, 0xe2, 0x90, 0x67, 0x88, 0x7b, 0x47, 0x24, 0x60, - 0x43, 0xf1, 0xbd, 0xed, 0xb4, 0x60, 0xd1, 0xd3, 0x48, 0xae, 0x64, 0x2e, 0xf2, 0x3c, 0x6d, 0xa7, - 0xe6, 0x51, 0xc4, 0x73, 0x76, 0xe0, 0x79, 0xe6, 0x0e, 0x2c, 0x17, 0x3c, 0x5c, 0xe5, 0x5b, 0xa5, - 0x41, 0xb1, 0x35, 0x33, 0x36, 0x5d, 0x05, 0xaf, 0x0e, 0xf3, 0xbf, 0x0d, 0x58, 0xfe, 0xd8, 0x67, - 0x3d, 0xe4, 0x9f, 0xf9, 0x48, 0x0c, 0x54, 0x0d, 0x8f, 0x54, 0x7a, 0x39, 0x49, 0x87, 0x87, 0x36, - 0x7f, 0xea, 0xf4, 0x2a, 0x31, 0x3d, 0xce, 0x3e, 0x84, 0x95, 0xbc, 0x9d, 0xf3, 0x2a, 0xd2, 0xde, - 0x1e, 0xae, 0x3e, 0xff, 0x6e, 0x6b, 0x29, 0x2b, 0xd6, 0xae, 0xae, 0xa8, 0x23, 0x67, 0x09, 0x8f, - 0x11, 0x3c, 0xb3, 0x0d, 0x0d, 0xda, 0xc3, 0xae, 0x20, 0x4f, 0xdd, 0x20, 0x1a, 0xea, 0x02, 0xac, - 0x39, 0x75, 0xda, 0xc3, 0x67, 0xe4, 0xe9, 0x67, 0xd1, 0xd0, 0x7c, 0x17, 0xde, 0xcc, 0x36, 0xba, - 0x1b, 0x23, 0xdf, 0x55, 0xf2, 0x2a, 0x5c, 0x5c, 0xd7, 0xe3, 0x82, 0xb3, 0x9a, 0xdd, 0x5e, 0x20, - 0x5f, 0x29, 0x3b, 0xf0, 0x3c, 0x6e, 0xbd, 0x98, 0x85, 0xb9, 0x53, 0xc4, 0xd1, 0x50, 0x98, 0xe7, - 0xb0, 0x24, 0xc9, 0x30, 0xf4, 0x91, 0x24, 0x6e, 0xb2, 0x2a, 0x52, 0x4f, 0xdf, 0xd1, 0x2b, 0xa4, - 0xbc, 0x7d, 0xed, 0xd2, 0xbe, 0x8d, 0x77, 0xed, 0xae, 0xa6, 0x9e, 0x49, 0x24, 0x89, 0xd3, 0xcc, - 0x30, 0x12, 0xa2, 0xf9, 0x3e, 0xb4, 0x24, 0x8f, 0x84, 0x2c, 0x86, 0x78, 0x31, 0xbd, 0x92, 0x5c, - 0xbf, 0x99, 0xdd, 0x27, 0x73, 0x2f, 0x9f, 0x5a, 0xd7, 0xcf, 0xeb, 0xea, 0xf7, 0x99, 0xd7, 0x67, - 0xb0, 0xaa, 0x96, 0xdd, 0x24, 0x66, 0x6d, 0x7a, 0xcc, 0x15, 0x25, 0x3f, 0x0e, 0xfa, 0x39, 0x98, - 0xb1, 0xc0, 0x93, 0x98, 0xb3, 0xaf, 0x61, 0x67, 0x2c, 0xf0, 0x38, 0xa4, 0x07, 0x9b, 0x42, 0x15, - 0x9f, 0x3b, 0x24, 0x52, 0x4f, 0xff, 0xd0, 0x27, 0x01, 0x15, 0x83, 0x0c, 0x7c, 0x6e, 0x7a, 0xf0, - 0x75, 0x0d, 0xf4, 0xa9, 0xc2, 0x71, 0x32, 0x98, 0x54, 0x4b, 0x17, 0xda, 0xd7, 0x6b, 0xc9, 0x13, - 0x74, 0x4b, 0x27, 0xe8, 0x07, 0xd7, 0x40, 0xe4, 0x59, 0x12, 0x70, 0xb7, 0xb4, 0xa5, 0x54, 0xd7, - 0xbb, 0xba, 0xe1, 0x5c, 0x4e, 0xfa, 0x6a, 0x94, 0xa3, 0x64, 0x61, 0x11, 0x92, 0x6f, 0xda, 0xb4, - 0xf7, 0xd4, 0x9b, 0xaa, 0xd4, 0x7c, 0x34, 0x48, 0x9f, 0x23, 0x56, 0xb1, 0xcc, 0xf2, 0x19, 0xe2, - 0x94, 0xb0, 0x3e, 0x22, 0x44, 0x75, 0x7b, 0x69, 0xa1, 0x91, 0x90, 0xe1, 0x81, 0x5e, 0xb8, 0x55, - 0xa7, 0x99, 0x2f, 0xaf, 0xfb, 0x8a, 0xfa, 0xb0, 0x36, 0x3f, 0xbf, 0x5c, 0xb7, 0x7e, 0x02, 0x75, - 0xdd, 0xcc, 0x07, 0xf8, 0x52, 0x98, 0x9b, 0x50, 0x57, 0x5d, 0x41, 0x84, 0x20, 0xa2, 0x65, 0xe8, - 0x19, 0x51, 0x10, 0x2c, 0x09, 0xeb, 0x37, 0x3d, 0xdb, 0x84, 0xf9, 0x18, 0x6e, 0x85, 0x44, 0xbf, - 0x29, 0xb4, 0x60, 0x63, 0xef, 0x03, 0x7b, 0x8a, 0xc7, 0xb5, 0x7d, 0x13, 0xa0, 0x93, 0xa1, 0x59, - 0xbc, 0x78, 0x2c, 0x4e, 0x2c, 0x2b, 0x61, 0x5e, 0x4c, 0x2a, 0xfd, 0xf9, 0x6b, 0x29, 0x9d, 0xc0, - 0x2b, 0x74, 0xbe, 0x03, 0x8d, 0x83, 0xc4, 0xed, 0x4f, 0xa8, 0x90, 0x57, 0xc3, 0xb2, 0x50, 0x0e, - 0xcb, 0x43, 0x68, 0xa6, 0x1b, 0xf8, 0x9c, 0xe9, 0x81, 0x64, 0xfe, 0x10, 0x20, 0x5d, 0xdd, 0x6a, - 0x90, 0x25, 0x23, 0xbd, 0x9e, 0x52, 0x8e, 0xbd, 0xb1, 0x5d, 0x59, 0x19, 0xdb, 0x95, 0x96, 0x03, - 0x4b, 0x17, 0x02, 0xff, 0x22, 0x7b, 0x9e, 0x3d, 0x0a, 0x85, 0xf9, 0x06, 0xcc, 0xa9, 0x1e, 0x4a, - 0x81, 0x6a, 0xce, 0x6c, 0x2c, 0xf0, 0xb1, 0x9e, 0xea, 0xc5, 0x13, 0x90, 0x85, 0x2e, 0xf5, 0x44, - 0xab, 0xb2, 0x5d, 0xdd, 0xa9, 0x39, 0xcd, 0xa8, 0x10, 0x3f, 0xf6, 0x84, 0xf5, 0x4b, 0x68, 0x94, - 0x00, 0xcd, 0x26, 0x54, 0x72, 0xac, 0x0a, 0xf5, 0xcc, 0x7d, 0x58, 0x2f, 0x80, 0xc6, 0xc7, 0x70, - 0x82, 0x58, 0x77, 0x6e, 0xe7, 0x0c, 0x63, 0x93, 0x58, 0x58, 0x8f, 0x60, 0xed, 0xb8, 0x68, 0xfa, - 0x7c, 0xc8, 0x8f, 0x79, 0x68, 0x8c, 0xbf, 0x06, 0x36, 0xa1, 0x9e, 0xff, 0x04, 0xd2, 0xde, 0xd7, - 0x9c, 0x82, 0x60, 0x0d, 0x61, 0xf9, 0x42, 0xe0, 0x33, 0x12, 0x78, 0x05, 0xd8, 0x0d, 0x01, 0x38, - 0x9c, 0x04, 0x9a, 0xfa, 0x1d, 0x5d, 0xa8, 0x63, 0xb0, 0x7e, 0x81, 0x7c, 0xea, 0x21, 0xc9, 0xf8, - 0x19, 0x91, 0xc9, 0x82, 0x3e, 0x45, 0xf8, 0x92, 0x48, 0x61, 0x3a, 0x50, 0xf3, 0xa9, 0x90, 0x69, - 0x65, 0xbd, 0x7f, 0x63, 0x65, 0xc5, 0xbb, 0xf6, 0x4d, 0x20, 0x47, 0x48, 0xa2, 0xb4, 0x77, 0x35, - 0x96, 0xf5, 0x63, 0x58, 0xfd, 0x14, 0xc9, 0x88, 0x13, 0x6f, 0x2c, 0xc7, 0xcb, 0x50, 0x55, 0xf9, - 0x33, 0x74, 0xfe, 0xd4, 0xa7, 0xf5, 0x27, 0x03, 0x5a, 0xf7, 0xbf, 0x08, 0x19, 0x97, 0xc4, 0xbb, - 0x12, 0x91, 0x97, 0x84, 0xf7, 0x12, 0x56, 0x55, 0xb0, 0x04, 0x09, 0x3c, 0x37, 0xf7, 0x33, 0xc9, - 0x63, 0x63, 0xef, 0xbd, 0xa9, 0xba, 0x63, 0x52, 0x5d, 0xea, 0xc0, 0x4a, 0x3c, 0x41, 0x17, 0xd6, - 0xef, 0x0c, 0x68, 0x9d, 0x90, 0xd1, 0x81, 0x10, 0xb4, 0x1f, 0x0c, 0x49, 0x20, 0xd5, 0x0c, 0x44, - 0x98, 0xa8, 0x4f, 0xf3, 0x2d, 0x58, 0xcc, 0x77, 0xae, 0x5e, 0xb5, 0x86, 0x5e, 0xb5, 0x0b, 0x19, - 0x51, 0x35, 0x98, 0xb9, 0x0f, 0x10, 0x72, 0x12, 0xbb, 0xd8, 0xbd, 0x24, 0xa3, 0x34, 0x8b, 0x9b, - 0xe5, 0x15, 0x9a, 0xfc, 0x40, 0xb5, 0x4f, 0xa3, 0x9e, 0x4f, 0xf1, 0x09, 0x19, 0x39, 0xf3, 0x8a, - 0xbf, 0x7b, 0x42, 0x46, 0xea, 0xcd, 0x14, 0xb2, 0x67, 0x84, 0xeb, 0xbd, 0x57, 0x75, 0x92, 0x83, - 0xf5, 0x7b, 0x03, 0x6e, 0xe7, 0xe9, 0xc8, 0xca, 0xf5, 0x34, 0xea, 0x29, 0x89, 0x97, 0xc4, 0xed, - 0x8a, 0xb5, 0x95, 0x6b, 0xac, 0xfd, 0x10, 0x16, 0xf2, 0x06, 0x51, 0xf6, 0x56, 0xa7, 0xb0, 0xb7, - 0x91, 0x49, 0x9c, 0x90, 0x91, 0xf5, 0x9b, 0x92, 0x6d, 0x87, 0xa3, 0xd2, 0xec, 0xe3, 0xaf, 0xb0, - 0x2d, 0x57, 0x5b, 0xb6, 0x0d, 0x97, 0xe5, 0xaf, 0x38, 0x50, 0xbd, 0xea, 0x80, 0xf5, 0x47, 0x03, - 0xd6, 0xca, 0x5a, 0xc5, 0x39, 0x3b, 0xe5, 0x51, 0x40, 0x5e, 0xa6, 0xbd, 0x68, 0xbf, 0x4a, 0xb9, - 0xfd, 0x1e, 0x43, 0x73, 0xcc, 0x28, 0x91, 0x46, 0xe3, 0x67, 0x53, 0xd5, 0x58, 0x69, 0xba, 0x3a, - 0x8b, 0x65, 0x3f, 0x84, 0xf5, 0x67, 0x03, 0x56, 0x32, 0x1b, 0xf3, 0x60, 0x99, 0x3f, 0x05, 0x33, - 0x77, 0xaf, 0x78, 0xbd, 0x25, 0x25, 0xb5, 0x9c, 0xdd, 0x64, 0x4f, 0xb7, 0xa2, 0x34, 0x2a, 0xa5, - 0xd2, 0x30, 0x3f, 0x81, 0xd5, 0xdc, 0xe4, 0x50, 0x27, 0x68, 0xea, 0x2c, 0xe6, 0xef, 0xd3, 0x9c, - 0x74, 0xf8, 0xf8, 0x9b, 0xe7, 0x6d, 0xe3, 0xdb, 0xe7, 0x6d, 0xe3, 0x5f, 0xcf, 0xdb, 0xc6, 0x97, - 0x2f, 0xda, 0x33, 0xdf, 0xbe, 0x68, 0xcf, 0xfc, 0xe3, 0x45, 0x7b, 0xe6, 0x57, 0x1f, 0xf4, 0xa9, - 0x1c, 0x44, 0x3d, 0x1b, 0xb3, 0x61, 0xfa, 0xc7, 0x47, 0xa7, 0x88, 0xc9, 0xbd, 0xfc, 0x2f, 0xa4, - 0xf8, 0xbd, 0xce, 0x17, 0xe3, 0x7f, 0x50, 0xc9, 0x51, 0x48, 0x44, 0x6f, 0x4e, 0x4f, 0xaf, 0x77, - 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xad, 0xbf, 0x18, 0xd1, 0x12, 0x00, 0x00, + // 2052 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xbb, 0x6f, 0x1c, 0xc7, + 0x19, 0xe7, 0xf2, 0x8e, 0x8f, 0xfb, 0x8e, 0xcf, 0x21, 0x6d, 0x2d, 0x19, 0xe6, 0x48, 0xad, 0x23, + 0x85, 0xb1, 0xa2, 0x3b, 0x53, 0x86, 0x01, 0x41, 0x88, 0x61, 0xf0, 0x21, 0x5b, 0x0f, 0x4b, 0xa2, + 0x97, 0x8c, 0x84, 0x38, 0xc5, 0x62, 0x6e, 0x76, 0x78, 0x37, 0xe1, 0xde, 0xce, 0x6a, 0x66, 0x6e, + 0xe9, 0x6b, 0x52, 0xa7, 0x09, 0xe0, 0x74, 0x46, 0x8a, 0xc4, 0x49, 0x15, 0xb8, 0x4a, 0x91, 0x3e, + 0x40, 0x8a, 0xc0, 0x48, 0x13, 0x97, 0xa9, 0xec, 0x40, 0x2a, 0x52, 0xe4, 0x9f, 0x08, 0x66, 0xf6, + 0x79, 0x7c, 0x48, 0x27, 0x38, 0x6e, 0xc8, 0xdb, 0xef, 0xf1, 0xfb, 0xbe, 0x99, 0xef, 0xb9, 0x0b, + 0x37, 0x58, 0xa8, 0xa8, 0x20, 0x5d, 0xcc, 0x42, 0x4f, 0x52, 0xd2, 0x17, 0x4c, 0x0d, 0x5a, 0x84, + 0xc4, 0xad, 0x48, 0xf0, 0x98, 0xf9, 0x54, 0xb4, 0xe2, 0xad, 0xfc, 0x77, 0x33, 0x12, 0x5c, 0x71, + 0xf4, 0xc6, 0x39, 0x3a, 0x4d, 0x42, 0xe2, 0x66, 0x2e, 0x17, 0x6f, 0xad, 0x5e, 0xb9, 0x08, 0x38, + 0xde, 0x6a, 0x9d, 0x30, 0x41, 0x13, 0xac, 0xd5, 0xe5, 0x0e, 0xef, 0x70, 0xf3, 0xb3, 0xa5, 0x7f, + 0xa5, 0xd4, 0xf5, 0x0e, 0xe7, 0x9d, 0x80, 0xb6, 0xcc, 0x53, 0xbb, 0x7f, 0xd4, 0x52, 0xac, 0x47, + 0xa5, 0xc2, 0xbd, 0x28, 0x15, 0x68, 0x9c, 0x16, 0xf0, 0xfb, 0x02, 0x2b, 0xc6, 0xc3, 0x0c, 0x80, + 0xb5, 0x49, 0x8b, 0x70, 0x41, 0x5b, 0x24, 0x60, 0x34, 0x54, 0xda, 0x6a, 0xf2, 0x2b, 0x15, 0x68, + 0x69, 0x81, 0x80, 0x75, 0xba, 0x2a, 0x21, 0xcb, 0x96, 0xa2, 0xa1, 0x4f, 0x45, 0x8f, 0x25, 0xc2, + 0xc5, 0x53, 0xaa, 0xb0, 0x56, 0xe2, 0x13, 0x31, 0x88, 0x14, 0x6f, 0x1d, 0xd3, 0x81, 0x4c, 0xb9, + 0x57, 0x09, 0x97, 0x3d, 0x2e, 0x5b, 0x54, 0x9f, 0x3f, 0x24, 0xb4, 0x15, 0x6f, 0xb5, 0xa9, 0xc2, + 0x5b, 0x39, 0x21, 0xf3, 0x3b, 0x95, 0x6b, 0x63, 0x59, 0xc8, 0x10, 0xce, 0x32, 0xbf, 0x57, 0x12, + 0xbe, 0x97, 0xdc, 0x48, 0xf2, 0x90, 0xb2, 0x16, 0x71, 0x8f, 0x85, 0xbc, 0x65, 0xfe, 0x26, 0x24, + 0xe7, 0x8b, 0x69, 0xb0, 0x77, 0x79, 0x28, 0xfb, 0x3d, 0x2a, 0xb6, 0x7d, 0x9f, 0xe9, 0x0b, 0xd8, + 0x17, 0x3c, 0xe2, 0x12, 0x07, 0x68, 0x19, 0x26, 0x14, 0x53, 0x01, 0xb5, 0xad, 0x0d, 0x6b, 0xb3, + 0xe6, 0x26, 0x0f, 0x68, 0x03, 0xea, 0x3e, 0x95, 0x44, 0xb0, 0x48, 0x0b, 0xdb, 0xe3, 0x86, 0x57, + 0x26, 0xa1, 0x15, 0x98, 0x4e, 0xa2, 0xc6, 0x7c, 0xbb, 0x62, 0xd8, 0x53, 0xe6, 0xf9, 0xae, 0x8f, + 0x3e, 0x80, 0x39, 0x16, 0x32, 0xc5, 0x70, 0xe0, 0x75, 0xa9, 0xbe, 0x3b, 0xbb, 0xba, 0x61, 0x6d, + 0xd6, 0x6f, 0xac, 0x36, 0x59, 0x9b, 0x34, 0xf5, 0x75, 0x37, 0xd3, 0x4b, 0x8e, 0xb7, 0x9a, 0x77, + 0x8c, 0xc4, 0x4e, 0xf5, 0xcb, 0xaf, 0xd7, 0xc7, 0xdc, 0xd9, 0x54, 0x2f, 0x21, 0xa2, 0xcb, 0x30, + 0xd3, 0xa1, 0x21, 0x95, 0x4c, 0x7a, 0x5d, 0x2c, 0xbb, 0xf6, 0xc4, 0x86, 0xb5, 0x39, 0xe3, 0xd6, + 0x53, 0xda, 0x1d, 0x2c, 0xbb, 0x68, 0x1d, 0xea, 0x6d, 0x16, 0x62, 0x31, 0x48, 0x24, 0x26, 0x8d, + 0x04, 0x24, 0x24, 0x23, 0xb0, 0x0b, 0x20, 0x23, 0x7c, 0x12, 0x7a, 0x3a, 0x37, 0xec, 0xa9, 0xd4, + 0x91, 0x24, 0x2f, 0x9a, 0x59, 0x5e, 0x34, 0x0f, 0xb3, 0xc4, 0xd9, 0x99, 0xd6, 0x8e, 0x7c, 0xfa, + 0xcd, 0xba, 0xe5, 0xd6, 0x8c, 0x9e, 0xe6, 0xa0, 0x87, 0xb0, 0xd0, 0x0f, 0xdb, 0x3c, 0xf4, 0x59, + 0xd8, 0xf1, 0x22, 0x2a, 0x18, 0xf7, 0xed, 0x69, 0x03, 0xb5, 0x72, 0x06, 0x6a, 0x2f, 0x4d, 0xb1, + 0x04, 0xe9, 0x33, 0x8d, 0x34, 0x9f, 0x2b, 0xef, 0x1b, 0x5d, 0xf4, 0x11, 0x20, 0x42, 0x62, 0xe3, + 0x12, 0xef, 0xab, 0x0c, 0xb1, 0x36, 0x3a, 0xe2, 0x02, 0x21, 0xf1, 0x61, 0xa2, 0x9d, 0x42, 0xfe, + 0x1c, 0x2e, 0x29, 0x81, 0x43, 0x79, 0x44, 0xc5, 0x69, 0x5c, 0x18, 0x1d, 0xf7, 0xb5, 0x0c, 0x63, + 0x18, 0xfc, 0x0e, 0x6c, 0x90, 0x34, 0x81, 0x3c, 0x41, 0x7d, 0x26, 0x95, 0x60, 0xed, 0xbe, 0xd6, + 0xf5, 0x8e, 0x04, 0x26, 0x26, 0x47, 0xea, 0x26, 0x09, 0x1a, 0x99, 0x9c, 0x3b, 0x24, 0xf6, 0x7e, + 0x2a, 0x85, 0x1e, 0xc1, 0x0f, 0xda, 0x01, 0x27, 0xc7, 0x52, 0x3b, 0xe7, 0x0d, 0x21, 0x19, 0xd3, + 0x3d, 0x26, 0xa5, 0x46, 0x9b, 0xd9, 0xb0, 0x36, 0x2b, 0xee, 0xe5, 0x44, 0x76, 0x9f, 0x8a, 0xbd, + 0x92, 0xe4, 0x61, 0x49, 0x10, 0x5d, 0x07, 0xd4, 0x65, 0x52, 0x71, 0xc1, 0x08, 0x0e, 0x3c, 0x1a, + 0x2a, 0xc1, 0xa8, 0xb4, 0x67, 0x8d, 0xfa, 0x62, 0xc1, 0xb9, 0x9d, 0x30, 0xd0, 0x3d, 0xb8, 0x7c, + 0xa1, 0x51, 0x8f, 0x74, 0x71, 0x18, 0xd2, 0xc0, 0x9e, 0x33, 0x47, 0x59, 0xf7, 0x2f, 0xb0, 0xb9, + 0x9b, 0x88, 0xa1, 0x25, 0x98, 0x50, 0x3c, 0xf2, 0x1e, 0xda, 0xf3, 0x1b, 0xd6, 0xe6, 0xac, 0x5b, + 0x55, 0x3c, 0x7a, 0x88, 0xde, 0x82, 0xe5, 0x18, 0x07, 0xcc, 0xc7, 0x8a, 0x0b, 0xe9, 0x45, 0xfc, + 0x84, 0x0a, 0x8f, 0xe0, 0xc8, 0x5e, 0x30, 0x32, 0xa8, 0xe0, 0xed, 0x6b, 0xd6, 0x2e, 0x8e, 0xd0, + 0x9b, 0xb0, 0x98, 0x53, 0x3d, 0x49, 0x95, 0x11, 0x5f, 0x34, 0xe2, 0xf3, 0x39, 0xe3, 0x80, 0x2a, + 0x2d, 0xbb, 0x06, 0x35, 0x1c, 0x04, 0xfc, 0x24, 0x60, 0x52, 0xd9, 0x68, 0xa3, 0xb2, 0x59, 0x73, + 0x0b, 0x02, 0x5a, 0x85, 0x69, 0x9f, 0x86, 0x03, 0xc3, 0x5c, 0x32, 0xcc, 0xfc, 0xf9, 0xd6, 0xd5, + 0x5f, 0x7d, 0xbe, 0x3e, 0xf6, 0xd9, 0xe7, 0xeb, 0x63, 0xff, 0xf8, 0xcb, 0xf5, 0xd5, 0xb4, 0x63, + 0x74, 0x78, 0xdc, 0x4c, 0xbb, 0x4b, 0x73, 0x97, 0x87, 0x8a, 0x86, 0xca, 0xf9, 0xa7, 0x05, 0x97, + 0x76, 0xf3, 0x18, 0xf6, 0x78, 0x8c, 0x83, 0xef, 0xb2, 0x57, 0x6c, 0x43, 0x4d, 0xea, 0x4b, 0x34, + 0xd5, 0x59, 0x7d, 0x85, 0xea, 0x9c, 0xd6, 0x6a, 0x9a, 0x71, 0xab, 0xf1, 0x92, 0x13, 0xfd, 0x6e, + 0x1c, 0xd6, 0xb2, 0x13, 0x3d, 0xe0, 0x3e, 0x3b, 0x62, 0x04, 0x7f, 0xd7, 0x2d, 0x30, 0x4f, 0x8d, + 0xea, 0x08, 0xa9, 0x31, 0xf1, 0x6a, 0xa9, 0x31, 0x39, 0x42, 0x6a, 0x4c, 0xbd, 0x28, 0x35, 0xa6, + 0x87, 0x53, 0xc3, 0xf9, 0xbd, 0x05, 0xcb, 0xb7, 0x9f, 0xf6, 0x59, 0xcc, 0xff, 0x4f, 0x17, 0x73, + 0x1f, 0x66, 0x69, 0x09, 0x4f, 0xda, 0x95, 0x8d, 0xca, 0x66, 0xfd, 0xc6, 0x95, 0x66, 0x1a, 0xa5, + 0x7c, 0xda, 0x65, 0xa1, 0x2a, 0x5b, 0x77, 0x87, 0x75, 0x6f, 0x8d, 0xdb, 0x96, 0xf3, 0x37, 0x0b, + 0x56, 0x75, 0xd5, 0x75, 0xa8, 0x4b, 0x4f, 0xb0, 0xf0, 0xf7, 0x68, 0xc8, 0x7b, 0xf2, 0x5b, 0xfb, + 0xe9, 0xc0, 0xac, 0x6f, 0x90, 0x3c, 0xc5, 0x3d, 0xec, 0xfb, 0xc6, 0x4f, 0x23, 0xa3, 0x89, 0x87, + 0x7c, 0xdb, 0xf7, 0xd1, 0x26, 0x2c, 0x14, 0x32, 0x42, 0x17, 0x84, 0xce, 0x53, 0x2d, 0x36, 0x97, + 0x89, 0x99, 0x32, 0x79, 0x79, 0x1e, 0xfe, 0xd7, 0x82, 0x85, 0x0f, 0x02, 0xde, 0xc6, 0xc1, 0x41, + 0x80, 0x65, 0x57, 0x77, 0xa4, 0x81, 0xce, 0x7f, 0x41, 0xd3, 0x51, 0x60, 0xdc, 0x1f, 0x39, 0xff, + 0xb5, 0x9a, 0x19, 0x4e, 0xef, 0xc1, 0x62, 0xde, 0x9c, 0xf3, 0x7c, 0x34, 0xa7, 0xdd, 0x59, 0x7a, + 0xf6, 0xf5, 0xfa, 0x7c, 0x96, 0xfb, 0xbb, 0x26, 0x37, 0xf7, 0xdc, 0x79, 0x32, 0x44, 0xf0, 0x51, + 0x03, 0xea, 0xac, 0x4d, 0x3c, 0x49, 0x9f, 0x7a, 0x61, 0xbf, 0x67, 0x52, 0xb9, 0xea, 0xd6, 0x58, + 0x9b, 0x1c, 0xd0, 0xa7, 0x0f, 0xfb, 0x3d, 0xf4, 0x36, 0xbc, 0x9e, 0xad, 0x6c, 0x5e, 0x8c, 0x03, + 0x4f, 0xeb, 0xeb, 0xeb, 0x12, 0x26, 0xbb, 0x67, 0xdc, 0xa5, 0x8c, 0xfb, 0x18, 0x07, 0xda, 0xd8, + 0xb6, 0xef, 0x0b, 0xe7, 0xaf, 0x93, 0x30, 0xb9, 0x8f, 0x05, 0xee, 0x49, 0x74, 0x08, 0xf3, 0x8a, + 0xf6, 0xa2, 0x00, 0x2b, 0xea, 0x25, 0x83, 0x3f, 0x3d, 0xe9, 0x35, 0xb3, 0x10, 0x94, 0xd7, 0xab, + 0x66, 0x69, 0xa1, 0x8a, 0xb7, 0x9a, 0xbb, 0x86, 0x7a, 0xa0, 0xb0, 0xa2, 0xee, 0x5c, 0x86, 0x91, + 0x10, 0xd1, 0x4d, 0xb0, 0x95, 0xe8, 0x4b, 0x55, 0x8c, 0xe4, 0x62, 0x16, 0x25, 0xb1, 0x7e, 0x3d, + 0xe3, 0x27, 0x53, 0x2c, 0x9f, 0x41, 0xe7, 0x4f, 0xdf, 0xca, 0xb7, 0x99, 0xbe, 0x07, 0xb0, 0xa4, + 0x57, 0x97, 0xd3, 0x98, 0xd5, 0xd1, 0x31, 0x17, 0xb5, 0xfe, 0x30, 0xe8, 0x47, 0x80, 0x62, 0x49, + 0x4e, 0x63, 0x4e, 0xbc, 0x82, 0x9f, 0xb1, 0x24, 0xc3, 0x90, 0x3e, 0xac, 0x49, 0x9d, 0x7c, 0x5e, + 0x8f, 0x2a, 0x33, 0xcb, 0xa3, 0x80, 0x86, 0x4c, 0x76, 0x33, 0xf0, 0xc9, 0xd1, 0xc1, 0x57, 0x0c, + 0xd0, 0x03, 0x8d, 0xe3, 0x66, 0x30, 0xa9, 0x95, 0x5d, 0x68, 0x9c, 0x6f, 0x25, 0x0f, 0xd0, 0x94, + 0x09, 0xd0, 0xf7, 0xce, 0x81, 0xc8, 0xa3, 0x24, 0xe1, 0x6a, 0x69, 0xe7, 0xd0, 0x55, 0xef, 0x99, + 0x82, 0xf3, 0x04, 0xed, 0xe8, 0xc1, 0x8c, 0x93, 0xf5, 0x83, 0xd2, 0x7c, 0x6f, 0x4a, 0x6b, 0x4f, + 0x2f, 0xcd, 0xa5, 0xe2, 0x63, 0x61, 0xba, 0x5c, 0x3a, 0xc5, 0x6a, 0x92, 0xf7, 0x10, 0xb7, 0x84, + 0xf5, 0x3e, 0xa5, 0xba, 0xda, 0x4b, 0xeb, 0x09, 0x8d, 0x38, 0xe9, 0x9a, 0xf5, 0xa9, 0xe2, 0xce, + 0xe5, 0xab, 0xc8, 0x6d, 0x4d, 0x45, 0x1f, 0xc3, 0xb5, 0xb0, 0xdf, 0x6b, 0x53, 0xe1, 0xf1, 0xa3, + 0x44, 0xd0, 0x74, 0x08, 0xa9, 0xb0, 0x50, 0x9e, 0xa0, 0x84, 0xb2, 0x58, 0x67, 0x66, 0xe2, 0xb9, + 0x34, 0xdb, 0x51, 0xc5, 0xbd, 0x92, 0xa8, 0x3c, 0x3a, 0x32, 0x18, 0xf2, 0x90, 0x1f, 0x68, 0x71, + 0x37, 0x93, 0x4e, 0x1c, 0x93, 0xf7, 0xaa, 0xd3, 0xd3, 0x0b, 0x35, 0xe7, 0x47, 0x50, 0x33, 0x8d, + 0x62, 0x9b, 0x1c, 0x4b, 0xd3, 0xdd, 0x7d, 0x5f, 0x50, 0x29, 0xa9, 0xb4, 0xad, 0xb4, 0xbb, 0x67, + 0x04, 0x47, 0xc1, 0xca, 0x45, 0x0b, 0xbe, 0x44, 0x4f, 0x60, 0x2a, 0xa2, 0x66, 0xfb, 0x34, 0x8a, + 0xf5, 0x1b, 0xef, 0x36, 0x47, 0x78, 0x33, 0x6b, 0x5e, 0x04, 0xe8, 0x66, 0x68, 0x8e, 0x28, 0x5e, + 0x2b, 0x4e, 0x6d, 0x0a, 0x12, 0x3d, 0x3e, 0x6d, 0xf4, 0x27, 0xaf, 0x64, 0xf4, 0x14, 0x5e, 0x61, + 0xf3, 0x1a, 0xd4, 0xb7, 0x93, 0x63, 0x7f, 0xa8, 0xc7, 0xda, 0x99, 0x6b, 0x99, 0x29, 0x5f, 0xcb, + 0x3d, 0x98, 0x4b, 0x77, 0xb5, 0x43, 0x6e, 0x9a, 0x1d, 0xfa, 0x3e, 0x40, 0xba, 0xe4, 0xe9, 0x26, + 0x99, 0x8c, 0x8b, 0x5a, 0x4a, 0xb9, 0xeb, 0x0f, 0x4d, 0xf4, 0xf1, 0xa1, 0x89, 0xee, 0xb8, 0x30, + 0xff, 0x58, 0x92, 0x9f, 0x66, 0x8b, 0xfc, 0xa3, 0x48, 0xa2, 0xd7, 0x60, 0x52, 0xd7, 0x67, 0x0a, + 0x54, 0x75, 0x27, 0x62, 0x49, 0xee, 0x9a, 0x89, 0x51, 0xbc, 0x2c, 0xf0, 0xc8, 0x63, 0xbe, 0xb4, + 0xc7, 0x37, 0x2a, 0x9b, 0x55, 0x77, 0xae, 0x5f, 0xa8, 0xdf, 0xf5, 0xa5, 0xf3, 0x33, 0xa8, 0x97, + 0x00, 0xd1, 0x1c, 0x8c, 0xe7, 0x58, 0xe3, 0xcc, 0x47, 0xb7, 0x60, 0xa5, 0x00, 0x1a, 0x6e, 0xf1, + 0x09, 0x62, 0xcd, 0xbd, 0x94, 0x0b, 0x0c, 0x75, 0x79, 0xe9, 0x3c, 0x82, 0xe5, 0xbb, 0x45, 0x43, + 0xc9, 0x07, 0xc8, 0xd0, 0x09, 0xad, 0xe1, 0x9d, 0x65, 0x0d, 0x6a, 0xf9, 0xfb, 0xb3, 0x39, 0x7d, + 0xd5, 0x2d, 0x08, 0x4e, 0x0f, 0x16, 0x1e, 0x4b, 0x72, 0x40, 0x43, 0xbf, 0x00, 0xbb, 0xe0, 0x02, + 0x76, 0x4e, 0x03, 0x8d, 0xfc, 0xc6, 0x55, 0x98, 0xe3, 0xb0, 0xf2, 0xb8, 0xbc, 0xe0, 0x98, 0xe1, + 0xbf, 0x8f, 0xc9, 0x31, 0x55, 0x12, 0xb9, 0x50, 0x35, 0x8b, 0x4c, 0x92, 0x59, 0x37, 0x2f, 0xcc, + 0xac, 0x78, 0xab, 0x79, 0x11, 0xc8, 0x1e, 0x56, 0x38, 0xed, 0x0b, 0x06, 0xcb, 0xf9, 0x21, 0x2c, + 0x3d, 0xc0, 0xaa, 0x2f, 0xa8, 0x3f, 0x14, 0xe3, 0x05, 0xa8, 0xe8, 0xf8, 0x59, 0x26, 0x7e, 0xfa, + 0xa7, 0xf3, 0x47, 0x0b, 0xec, 0xdb, 0x9f, 0x44, 0x5c, 0x28, 0xea, 0x9f, 0xb9, 0x91, 0x17, 0x5c, + 0xef, 0x31, 0x2c, 0xe9, 0xcb, 0x92, 0x34, 0xf4, 0xbd, 0xfc, 0x9c, 0x49, 0x1c, 0xeb, 0x37, 0xde, + 0x19, 0xa9, 0x3a, 0x4e, 0x9b, 0x4b, 0x0f, 0xb0, 0x18, 0x9f, 0xa2, 0x4b, 0xe7, 0x37, 0x16, 0xd8, + 0xf7, 0xe9, 0x60, 0x5b, 0x4a, 0xd6, 0x09, 0x7b, 0x34, 0x54, 0xba, 0xbf, 0x62, 0x42, 0xf5, 0x4f, + 0xf4, 0x06, 0xcc, 0xe6, 0xf3, 0xdc, 0x8c, 0x71, 0xcb, 0x8c, 0xf1, 0x99, 0x8c, 0xa8, 0x0b, 0x0c, + 0xdd, 0x02, 0x88, 0x04, 0x8d, 0x3d, 0xe2, 0x1d, 0xd3, 0x41, 0x1a, 0xc5, 0xb5, 0xf2, 0x78, 0x4e, + 0xbe, 0x6e, 0x34, 0xf7, 0xfb, 0xed, 0x80, 0x91, 0xfb, 0x74, 0xe0, 0x4e, 0x6b, 0xf9, 0xdd, 0xfb, + 0x74, 0xa0, 0xf7, 0x31, 0xb3, 0xdd, 0x9a, 0x99, 0x5a, 0x71, 0x93, 0x07, 0xe7, 0xb7, 0x16, 0x5c, + 0xca, 0xc3, 0x91, 0xa5, 0xeb, 0x7e, 0xbf, 0xad, 0x35, 0x5e, 0x70, 0x6f, 0x67, 0xbc, 0x1d, 0x3f, + 0xc7, 0xdb, 0xf7, 0x60, 0x26, 0x2f, 0x10, 0xed, 0x6f, 0x65, 0x04, 0x7f, 0xeb, 0x99, 0xc6, 0x7d, + 0x3a, 0x70, 0x7e, 0x59, 0xf2, 0x6d, 0x67, 0x50, 0xea, 0x7d, 0xe2, 0x25, 0xbe, 0xe5, 0x66, 0xcb, + 0xbe, 0x91, 0xb2, 0xfe, 0x99, 0x03, 0x54, 0xce, 0x1e, 0xc0, 0xf9, 0x83, 0x05, 0xcb, 0x65, 0xab, + 0xf2, 0x90, 0xef, 0x8b, 0x7e, 0x48, 0x5f, 0x64, 0xbd, 0x28, 0xbf, 0xf1, 0x72, 0xf9, 0x3d, 0x81, + 0xb9, 0x21, 0xa7, 0x64, 0x7a, 0x1b, 0x6f, 0x8d, 0x94, 0x63, 0xa5, 0xee, 0xea, 0xce, 0x96, 0xcf, + 0x21, 0x9d, 0xbf, 0x5b, 0xb0, 0x98, 0xf9, 0x98, 0x5f, 0x16, 0xfa, 0x31, 0xa0, 0xfc, 0x78, 0xc5, + 0x66, 0x98, 0xa4, 0xd4, 0x42, 0xc6, 0xc9, 0xd6, 0xc2, 0x22, 0x35, 0xc6, 0x4b, 0xa9, 0x81, 0x3e, + 0x84, 0xa5, 0xdc, 0xe5, 0xc8, 0x04, 0x68, 0xe4, 0x28, 0xe6, 0xbb, 0x6f, 0x4e, 0x42, 0xeb, 0x50, + 0xff, 0x05, 0x67, 0x61, 0xf9, 0xe3, 0x53, 0xc5, 0x05, 0x4d, 0x4a, 0xbe, 0x2b, 0x39, 0xbf, 0xb6, + 0x8a, 0x79, 0x99, 0xce, 0xdc, 0xed, 0x20, 0x48, 0xdf, 0x38, 0x50, 0x04, 0x53, 0xd9, 0xd4, 0x4e, + 0x1a, 0xcc, 0xda, 0xb9, 0x9b, 0xc5, 0x1e, 0x25, 0x66, 0xb9, 0xb8, 0xa9, 0x6b, 0xf0, 0x8b, 0x6f, + 0xd6, 0xaf, 0x75, 0x98, 0xea, 0xf6, 0xdb, 0x4d, 0xc2, 0x7b, 0xe9, 0x17, 0xb9, 0xf4, 0xdf, 0x75, + 0xe9, 0x1f, 0xb7, 0xd4, 0x20, 0xa2, 0x32, 0xd3, 0x91, 0x7f, 0xfa, 0xcf, 0x9f, 0xdf, 0xb4, 0xdc, + 0xcc, 0xcc, 0xce, 0x93, 0x2f, 0x9f, 0x35, 0xac, 0xaf, 0x9e, 0x35, 0xac, 0x7f, 0x3f, 0x6b, 0x58, + 0x9f, 0x3e, 0x6f, 0x8c, 0x7d, 0xf5, 0xbc, 0x31, 0xf6, 0xaf, 0xe7, 0x8d, 0xb1, 0x8f, 0xdf, 0x3d, + 0x0b, 0x5a, 0x04, 0xf1, 0x7a, 0xfe, 0xc1, 0x34, 0x7e, 0xa7, 0xf5, 0xc9, 0xf0, 0xe7, 0x58, 0x63, + 0xaf, 0x3d, 0x69, 0xda, 0xed, 0xdb, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x5f, 0xaa, 0x2b, 0x22, + 0xbf, 0x15, 0x00, 0x00, } func (m *ConsumerAdditionProposal) Marshal() (dAtA []byte, err error) { @@ -1629,6 +1856,47 @@ func (m *ConsumerAdditionProposal) MarshalToSizedBuffer(dAtA []byte) (int, error _ = i var l int _ = l + if len(m.Denylist) > 0 { + for iNdEx := len(m.Denylist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Denylist[iNdEx]) + copy(dAtA[i:], m.Denylist[iNdEx]) + i = encodeVarintProvider(dAtA, i, uint64(len(m.Denylist[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x9a + } + } + if len(m.Allowlist) > 0 { + for iNdEx := len(m.Allowlist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Allowlist[iNdEx]) + copy(dAtA[i:], m.Allowlist[iNdEx]) + i = encodeVarintProvider(dAtA, i, uint64(len(m.Allowlist[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x92 + } + } + if m.ValidatorSetCap != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.ValidatorSetCap)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x88 + } + if m.ValidatorsPowerCap != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.ValidatorsPowerCap)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x80 + } + if m.Top_N != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.Top_N)) + i-- + dAtA[i] = 0x78 + } if len(m.DistributionTransmissionChannel) > 0 { i -= len(m.DistributionTransmissionChannel) copy(dAtA[i:], m.DistributionTransmissionChannel) @@ -1785,6 +2053,83 @@ func (m *ConsumerRemovalProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *ConsumerModificationProposal) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ConsumerModificationProposal) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ConsumerModificationProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Denylist) > 0 { + for iNdEx := len(m.Denylist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Denylist[iNdEx]) + copy(dAtA[i:], m.Denylist[iNdEx]) + i = encodeVarintProvider(dAtA, i, uint64(len(m.Denylist[iNdEx]))) + i-- + dAtA[i] = 0x42 + } + } + if len(m.Allowlist) > 0 { + for iNdEx := len(m.Allowlist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Allowlist[iNdEx]) + copy(dAtA[i:], m.Allowlist[iNdEx]) + i = encodeVarintProvider(dAtA, i, uint64(len(m.Allowlist[iNdEx]))) + i-- + dAtA[i] = 0x3a + } + } + if m.ValidatorSetCap != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.ValidatorSetCap)) + i-- + dAtA[i] = 0x30 + } + if m.ValidatorsPowerCap != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.ValidatorsPowerCap)) + i-- + dAtA[i] = 0x28 + } + if m.Top_N != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.Top_N)) + i-- + dAtA[i] = 0x20 + } + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintProvider(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0x1a + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintProvider(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if len(m.Title) > 0 { + i -= len(m.Title) + copy(dAtA[i:], m.Title) + i = encodeVarintProvider(dAtA, i, uint64(len(m.Title))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *EquivocationProposal) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1961,6 +2306,11 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.NumberOfEpochsToStartReceivingRewards != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.NumberOfEpochsToStartReceivingRewards)) + i-- + dAtA[i] = 0x58 + } if m.BlocksPerEpoch != 0 { i = encodeVarintProvider(dAtA, i, uint64(m.BlocksPerEpoch)) i-- @@ -2695,6 +3045,11 @@ func (m *ConsumerValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.JoinHeight != 0 { + i = encodeVarintProvider(dAtA, i, uint64(m.JoinHeight)) + i-- + dAtA[i] = 0x20 + } if m.ConsumerPublicKey != nil { { size, err := m.ConsumerPublicKey.MarshalToSizedBuffer(dAtA[:i]) @@ -2722,6 +3077,43 @@ func (m *ConsumerValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ConsumerRewardsAllocation) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ConsumerRewardsAllocation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ConsumerRewardsAllocation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Rewards) > 0 { + for iNdEx := len(m.Rewards) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Rewards[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintProvider(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func encodeVarintProvider(dAtA []byte, offset int, v uint64) int { offset -= sovProvider(v) base := offset @@ -2783,14 +3175,35 @@ func (m *ConsumerAdditionProposal) Size() (n int) { if l > 0 { n += 1 + l + sovProvider(uint64(l)) } - return n -} - -func (m *ConsumerRemovalProposal) Size() (n int) { - if m == nil { - return 0 + if m.Top_N != 0 { + n += 1 + sovProvider(uint64(m.Top_N)) } - var l int + if m.ValidatorsPowerCap != 0 { + n += 2 + sovProvider(uint64(m.ValidatorsPowerCap)) + } + if m.ValidatorSetCap != 0 { + n += 2 + sovProvider(uint64(m.ValidatorSetCap)) + } + if len(m.Allowlist) > 0 { + for _, s := range m.Allowlist { + l = len(s) + n += 2 + l + sovProvider(uint64(l)) + } + } + if len(m.Denylist) > 0 { + for _, s := range m.Denylist { + l = len(s) + n += 2 + l + sovProvider(uint64(l)) + } + } + return n +} + +func (m *ConsumerRemovalProposal) Size() (n int) { + if m == nil { + return 0 + } + var l int _ = l l = len(m.Title) if l > 0 { @@ -2809,6 +3222,48 @@ func (m *ConsumerRemovalProposal) Size() (n int) { return n } +func (m *ConsumerModificationProposal) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Title) + if l > 0 { + n += 1 + l + sovProvider(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovProvider(uint64(l)) + } + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovProvider(uint64(l)) + } + if m.Top_N != 0 { + n += 1 + sovProvider(uint64(m.Top_N)) + } + if m.ValidatorsPowerCap != 0 { + n += 1 + sovProvider(uint64(m.ValidatorsPowerCap)) + } + if m.ValidatorSetCap != 0 { + n += 1 + sovProvider(uint64(m.ValidatorSetCap)) + } + if len(m.Allowlist) > 0 { + for _, s := range m.Allowlist { + l = len(s) + n += 1 + l + sovProvider(uint64(l)) + } + } + if len(m.Denylist) > 0 { + for _, s := range m.Denylist { + l = len(s) + n += 1 + l + sovProvider(uint64(l)) + } + } + return n +} + func (m *EquivocationProposal) Size() (n int) { if m == nil { return 0 @@ -2914,6 +3369,9 @@ func (m *Params) Size() (n int) { if m.BlocksPerEpoch != 0 { n += 1 + sovProvider(uint64(m.BlocksPerEpoch)) } + if m.NumberOfEpochsToStartReceivingRewards != 0 { + n += 1 + sovProvider(uint64(m.NumberOfEpochsToStartReceivingRewards)) + } return n } @@ -3210,6 +3668,24 @@ func (m *ConsumerValidator) Size() (n int) { l = m.ConsumerPublicKey.Size() n += 1 + l + sovProvider(uint64(l)) } + if m.JoinHeight != 0 { + n += 1 + sovProvider(uint64(m.JoinHeight)) + } + return n +} + +func (m *ConsumerRewardsAllocation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Rewards) > 0 { + for _, e := range m.Rewards { + l = e.Size() + n += 1 + l + sovProvider(uint64(l)) + } + } return n } @@ -3642,14 +4118,281 @@ func (m *ConsumerAdditionProposal) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.HistoricalEntries |= int64(b&0x7F) << shift + m.HistoricalEntries |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DistributionTransmissionChannel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProvider + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProvider + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DistributionTransmissionChannel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Top_N", wireType) + } + m.Top_N = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Top_N |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 16: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorsPowerCap", wireType) + } + m.ValidatorsPowerCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorsPowerCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 17: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorSetCap", wireType) + } + m.ValidatorSetCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorSetCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 18: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Allowlist", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProvider + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProvider + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Allowlist = append(m.Allowlist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 19: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denylist", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProvider + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProvider + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Denylist = append(m.Denylist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipProvider(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthProvider + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ConsumerRemovalProposal) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ConsumerRemovalProposal: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConsumerRemovalProposal: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Title", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProvider + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProvider + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Title = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - case 14: + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProvider + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProvider + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DistributionTransmissionChannel", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3677,7 +4420,40 @@ func (m *ConsumerAdditionProposal) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DistributionTransmissionChannel = string(dAtA[iNdEx:postIndex]) + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StopTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthProvider + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthProvider + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.StopTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -3700,7 +4476,7 @@ func (m *ConsumerAdditionProposal) Unmarshal(dAtA []byte) error { } return nil } -func (m *ConsumerRemovalProposal) Unmarshal(dAtA []byte) error { +func (m *ConsumerModificationProposal) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3723,10 +4499,10 @@ func (m *ConsumerRemovalProposal) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ConsumerRemovalProposal: wiretype end group for non-group") + return fmt.Errorf("proto: ConsumerModificationProposal: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ConsumerRemovalProposal: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ConsumerModificationProposal: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -3826,10 +4602,67 @@ func (m *ConsumerRemovalProposal) Unmarshal(dAtA []byte) error { m.ChainId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Top_N", wireType) + } + m.Top_N = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Top_N |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorsPowerCap", wireType) + } + m.ValidatorsPowerCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorsPowerCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorSetCap", wireType) + } + m.ValidatorSetCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorSetCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StopTime", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Allowlist", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowProvider @@ -3839,24 +4672,55 @@ func (m *ConsumerRemovalProposal) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthProvider } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthProvider } if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.StopTime, dAtA[iNdEx:postIndex]); err != nil { - return err + m.Allowlist = append(m.Allowlist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denylist", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthProvider + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthProvider + } + if postIndex > l { + return io.ErrUnexpectedEOF } + m.Denylist = append(m.Denylist, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -4686,6 +5550,25 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumberOfEpochsToStartReceivingRewards", wireType) + } + m.NumberOfEpochsToStartReceivingRewards = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumberOfEpochsToStartReceivingRewards |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipProvider(dAtA[iNdEx:]) @@ -6624,6 +7507,109 @@ func (m *ConsumerValidator) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field JoinHeight", wireType) + } + m.JoinHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.JoinHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipProvider(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthProvider + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ConsumerRewardsAllocation) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ConsumerRewardsAllocation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConsumerRewardsAllocation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Rewards", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProvider + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthProvider + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthProvider + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Rewards = append(m.Rewards, types2.DecCoin{}) + if err := m.Rewards[len(m.Rewards)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipProvider(dAtA[iNdEx:]) diff --git a/x/ccv/provider/types/query.pb.go b/x/ccv/provider/types/query.pb.go index 949934e025..e8c13f7d3c 100644 --- a/x/ccv/provider/types/query.pb.go +++ b/x/ccv/provider/types/query.pb.go @@ -5,8 +5,11 @@ package types import ( context "context" + cosmossdk_io_math "cosmossdk.io/math" fmt "fmt" crypto "github.com/cometbft/cometbft/proto/tendermint/crypto" + _ "github.com/cosmos/cosmos-proto" + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" @@ -374,6 +377,21 @@ func (m *QueryConsumerChainStopProposalsResponse) GetProposals() *ConsumerRemova type Chain struct { ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` ClientId string `protobuf:"bytes,2,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + // If chain with `chainID` is a Top-N chain, i.e., enforces at least one validator to validate chain `chainID` + Top_N uint32 `protobuf:"varint,3,opt,name=top_N,json=topN,proto3" json:"top_N,omitempty"` + // If the chain is a Top-N chain, this is the minimum power required to be in the top N. + // Otherwise, this is -1. + MinPowerInTop_N int64 `protobuf:"varint,4,opt,name=min_power_in_top_N,json=minPowerInTopN,proto3" json:"min_power_in_top_N,omitempty"` + // Corresponds to the maximum power (percentage-wise) a validator can have on the consumer chain. + ValidatorsPowerCap uint32 `protobuf:"varint,5,opt,name=validators_power_cap,json=validatorsPowerCap,proto3" json:"validators_power_cap,omitempty"` + // Corresponds to the maximum number of validators that can validate a consumer chain. + // Only applicable to Opt In chains. Setting `validator_set_cap` on a Top N chain is a no-op. + ValidatorSetCap uint32 `protobuf:"varint,6,opt,name=validator_set_cap,json=validatorSetCap,proto3" json:"validator_set_cap,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that are the ONLY ones that can validate + // the consumer chain. + Allowlist []string `protobuf:"bytes,7,rep,name=allowlist,proto3" json:"allowlist,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that CANNOT validate the consumer chain. + Denylist []string `protobuf:"bytes,8,rep,name=denylist,proto3" json:"denylist,omitempty"` } func (m *Chain) Reset() { *m = Chain{} } @@ -423,6 +441,48 @@ func (m *Chain) GetClientId() string { return "" } +func (m *Chain) GetTop_N() uint32 { + if m != nil { + return m.Top_N + } + return 0 +} + +func (m *Chain) GetMinPowerInTop_N() int64 { + if m != nil { + return m.MinPowerInTop_N + } + return 0 +} + +func (m *Chain) GetValidatorsPowerCap() uint32 { + if m != nil { + return m.ValidatorsPowerCap + } + return 0 +} + +func (m *Chain) GetValidatorSetCap() uint32 { + if m != nil { + return m.ValidatorSetCap + } + return 0 +} + +func (m *Chain) GetAllowlist() []string { + if m != nil { + return m.Allowlist + } + return nil +} + +func (m *Chain) GetDenylist() []string { + if m != nil { + return m.Denylist + } + return nil +} + type QueryValidatorConsumerAddrRequest struct { // The id of the consumer chain ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` @@ -1153,22 +1213,26 @@ func (m *QueryParamsResponse) GetParams() Params { return Params{} } -type QueryOldestUnconfirmedVscRequest struct { +type QueryConsumerChainOptedInValidatorsRequest struct { ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` } -func (m *QueryOldestUnconfirmedVscRequest) Reset() { *m = QueryOldestUnconfirmedVscRequest{} } -func (m *QueryOldestUnconfirmedVscRequest) String() string { return proto.CompactTextString(m) } -func (*QueryOldestUnconfirmedVscRequest) ProtoMessage() {} -func (*QueryOldestUnconfirmedVscRequest) Descriptor() ([]byte, []int) { +func (m *QueryConsumerChainOptedInValidatorsRequest) Reset() { + *m = QueryConsumerChainOptedInValidatorsRequest{} +} +func (m *QueryConsumerChainOptedInValidatorsRequest) String() string { + return proto.CompactTextString(m) +} +func (*QueryConsumerChainOptedInValidatorsRequest) ProtoMessage() {} +func (*QueryConsumerChainOptedInValidatorsRequest) Descriptor() ([]byte, []int) { return fileDescriptor_422512d7b7586cd7, []int{25} } -func (m *QueryOldestUnconfirmedVscRequest) XXX_Unmarshal(b []byte) error { +func (m *QueryConsumerChainOptedInValidatorsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryOldestUnconfirmedVscRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryConsumerChainOptedInValidatorsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryOldestUnconfirmedVscRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryConsumerChainOptedInValidatorsRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1178,41 +1242,46 @@ func (m *QueryOldestUnconfirmedVscRequest) XXX_Marshal(b []byte, deterministic b return b[:n], nil } } -func (m *QueryOldestUnconfirmedVscRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryOldestUnconfirmedVscRequest.Merge(m, src) +func (m *QueryConsumerChainOptedInValidatorsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryConsumerChainOptedInValidatorsRequest.Merge(m, src) } -func (m *QueryOldestUnconfirmedVscRequest) XXX_Size() int { +func (m *QueryConsumerChainOptedInValidatorsRequest) XXX_Size() int { return m.Size() } -func (m *QueryOldestUnconfirmedVscRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryOldestUnconfirmedVscRequest.DiscardUnknown(m) +func (m *QueryConsumerChainOptedInValidatorsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryConsumerChainOptedInValidatorsRequest.DiscardUnknown(m) } -var xxx_messageInfo_QueryOldestUnconfirmedVscRequest proto.InternalMessageInfo +var xxx_messageInfo_QueryConsumerChainOptedInValidatorsRequest proto.InternalMessageInfo -func (m *QueryOldestUnconfirmedVscRequest) GetChainId() string { +func (m *QueryConsumerChainOptedInValidatorsRequest) GetChainId() string { if m != nil { return m.ChainId } return "" } -type QueryOldestUnconfirmedVscResponse struct { - VscSendTimestamp VscSendTimestamp `protobuf:"bytes,1,opt,name=vsc_send_timestamp,json=vscSendTimestamp,proto3" json:"vsc_send_timestamp"` +type QueryConsumerChainOptedInValidatorsResponse struct { + // The consensus addresses of the validators on the provider chain + ValidatorsProviderAddresses []string `protobuf:"bytes,1,rep,name=validators_provider_addresses,json=validatorsProviderAddresses,proto3" json:"validators_provider_addresses,omitempty"` } -func (m *QueryOldestUnconfirmedVscResponse) Reset() { *m = QueryOldestUnconfirmedVscResponse{} } -func (m *QueryOldestUnconfirmedVscResponse) String() string { return proto.CompactTextString(m) } -func (*QueryOldestUnconfirmedVscResponse) ProtoMessage() {} -func (*QueryOldestUnconfirmedVscResponse) Descriptor() ([]byte, []int) { +func (m *QueryConsumerChainOptedInValidatorsResponse) Reset() { + *m = QueryConsumerChainOptedInValidatorsResponse{} +} +func (m *QueryConsumerChainOptedInValidatorsResponse) String() string { + return proto.CompactTextString(m) +} +func (*QueryConsumerChainOptedInValidatorsResponse) ProtoMessage() {} +func (*QueryConsumerChainOptedInValidatorsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_422512d7b7586cd7, []int{26} } -func (m *QueryOldestUnconfirmedVscResponse) XXX_Unmarshal(b []byte) error { +func (m *QueryConsumerChainOptedInValidatorsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryOldestUnconfirmedVscResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryConsumerChainOptedInValidatorsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryOldestUnconfirmedVscResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryConsumerChainOptedInValidatorsResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1222,1472 +1291,1314 @@ func (m *QueryOldestUnconfirmedVscResponse) XXX_Marshal(b []byte, deterministic return b[:n], nil } } -func (m *QueryOldestUnconfirmedVscResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryOldestUnconfirmedVscResponse.Merge(m, src) +func (m *QueryConsumerChainOptedInValidatorsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryConsumerChainOptedInValidatorsResponse.Merge(m, src) } -func (m *QueryOldestUnconfirmedVscResponse) XXX_Size() int { +func (m *QueryConsumerChainOptedInValidatorsResponse) XXX_Size() int { return m.Size() } -func (m *QueryOldestUnconfirmedVscResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryOldestUnconfirmedVscResponse.DiscardUnknown(m) +func (m *QueryConsumerChainOptedInValidatorsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryConsumerChainOptedInValidatorsResponse.DiscardUnknown(m) } -var xxx_messageInfo_QueryOldestUnconfirmedVscResponse proto.InternalMessageInfo +var xxx_messageInfo_QueryConsumerChainOptedInValidatorsResponse proto.InternalMessageInfo -func (m *QueryOldestUnconfirmedVscResponse) GetVscSendTimestamp() VscSendTimestamp { +func (m *QueryConsumerChainOptedInValidatorsResponse) GetValidatorsProviderAddresses() []string { if m != nil { - return m.VscSendTimestamp + return m.ValidatorsProviderAddresses } - return VscSendTimestamp{} + return nil } -func init() { - proto.RegisterType((*QueryConsumerGenesisRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerGenesisRequest") - proto.RegisterType((*QueryConsumerGenesisResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerGenesisResponse") - proto.RegisterType((*QueryConsumerChainsRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainsRequest") - proto.RegisterType((*QueryConsumerChainsResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainsResponse") - proto.RegisterType((*QueryConsumerChainStartProposalsRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainStartProposalsRequest") - proto.RegisterType((*QueryConsumerChainStartProposalsResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainStartProposalsResponse") - proto.RegisterType((*QueryConsumerChainStopProposalsRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainStopProposalsRequest") - proto.RegisterType((*QueryConsumerChainStopProposalsResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainStopProposalsResponse") - proto.RegisterType((*Chain)(nil), "interchain_security.ccv.provider.v1.Chain") - proto.RegisterType((*QueryValidatorConsumerAddrRequest)(nil), "interchain_security.ccv.provider.v1.QueryValidatorConsumerAddrRequest") - proto.RegisterType((*QueryValidatorConsumerAddrResponse)(nil), "interchain_security.ccv.provider.v1.QueryValidatorConsumerAddrResponse") - proto.RegisterType((*QueryValidatorProviderAddrRequest)(nil), "interchain_security.ccv.provider.v1.QueryValidatorProviderAddrRequest") - proto.RegisterType((*QueryValidatorProviderAddrResponse)(nil), "interchain_security.ccv.provider.v1.QueryValidatorProviderAddrResponse") - proto.RegisterType((*QueryThrottleStateRequest)(nil), "interchain_security.ccv.provider.v1.QueryThrottleStateRequest") - proto.RegisterType((*QueryThrottleStateResponse)(nil), "interchain_security.ccv.provider.v1.QueryThrottleStateResponse") - proto.RegisterType((*QueryRegisteredConsumerRewardDenomsRequest)(nil), "interchain_security.ccv.provider.v1.QueryRegisteredConsumerRewardDenomsRequest") - proto.RegisterType((*QueryRegisteredConsumerRewardDenomsResponse)(nil), "interchain_security.ccv.provider.v1.QueryRegisteredConsumerRewardDenomsResponse") - proto.RegisterType((*QueryProposedChainIDsRequest)(nil), "interchain_security.ccv.provider.v1.QueryProposedChainIDsRequest") - proto.RegisterType((*QueryProposedChainIDsResponse)(nil), "interchain_security.ccv.provider.v1.QueryProposedChainIDsResponse") - proto.RegisterType((*ProposedChain)(nil), "interchain_security.ccv.provider.v1.ProposedChain") - proto.RegisterType((*QueryAllPairsValConAddrByConsumerChainIDRequest)(nil), "interchain_security.ccv.provider.v1.QueryAllPairsValConAddrByConsumerChainIDRequest") - proto.RegisterType((*QueryAllPairsValConAddrByConsumerChainIDResponse)(nil), "interchain_security.ccv.provider.v1.QueryAllPairsValConAddrByConsumerChainIDResponse") - proto.RegisterType((*PairValConAddrProviderAndConsumer)(nil), "interchain_security.ccv.provider.v1.PairValConAddrProviderAndConsumer") - proto.RegisterType((*QueryParamsRequest)(nil), "interchain_security.ccv.provider.v1.QueryParamsRequest") - proto.RegisterType((*QueryParamsResponse)(nil), "interchain_security.ccv.provider.v1.QueryParamsResponse") - proto.RegisterType((*QueryOldestUnconfirmedVscRequest)(nil), "interchain_security.ccv.provider.v1.QueryOldestUnconfirmedVscRequest") - proto.RegisterType((*QueryOldestUnconfirmedVscResponse)(nil), "interchain_security.ccv.provider.v1.QueryOldestUnconfirmedVscResponse") +type QueryConsumerValidatorsRequest struct { + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` } -func init() { - proto.RegisterFile("interchain_security/ccv/provider/v1/query.proto", fileDescriptor_422512d7b7586cd7) +func (m *QueryConsumerValidatorsRequest) Reset() { *m = QueryConsumerValidatorsRequest{} } +func (m *QueryConsumerValidatorsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryConsumerValidatorsRequest) ProtoMessage() {} +func (*QueryConsumerValidatorsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_422512d7b7586cd7, []int{27} } - -var fileDescriptor_422512d7b7586cd7 = []byte{ - // 1525 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0xcf, 0x6f, 0xd4, 0x46, - 0x1b, 0x8e, 0x13, 0xc8, 0x97, 0x4c, 0xf8, 0xf5, 0x0d, 0x7c, 0x10, 0x9c, 0x7c, 0xbb, 0x60, 0xd4, - 0x36, 0x40, 0x6b, 0x27, 0x8b, 0x50, 0xf9, 0xd1, 0x10, 0x76, 0xf3, 0x83, 0xae, 0x02, 0x22, 0x35, - 0x90, 0x4a, 0x6d, 0x55, 0xe3, 0xd8, 0xc3, 0xc6, 0xc2, 0xeb, 0x31, 0x33, 0xde, 0x85, 0x15, 0xea, - 0x81, 0x1e, 0x5a, 0x4e, 0x15, 0x52, 0xdb, 0x3b, 0x97, 0xfe, 0x03, 0xfd, 0x2b, 0xe8, 0xa9, 0x54, - 0x5c, 0x7a, 0xa2, 0x55, 0xe8, 0xa1, 0xea, 0xa9, 0x42, 0x95, 0x7a, 0xaa, 0x54, 0x79, 0x3c, 0xf6, - 0xda, 0xbb, 0xde, 0x5d, 0xef, 0x26, 0xb7, 0x64, 0x3c, 0xef, 0xf3, 0x3e, 0xcf, 0xeb, 0x77, 0xde, - 0x79, 0xbc, 0x40, 0xb1, 0x1c, 0x0f, 0x11, 0x63, 0x53, 0xb7, 0x1c, 0x8d, 0x22, 0xa3, 0x46, 0x2c, - 0xaf, 0xa1, 0x18, 0x46, 0x5d, 0x71, 0x09, 0xae, 0x5b, 0x26, 0x22, 0x4a, 0x7d, 0x4e, 0xb9, 0x57, - 0x43, 0xa4, 0x21, 0xbb, 0x04, 0x7b, 0x18, 0x9e, 0x48, 0x09, 0x90, 0x0d, 0xa3, 0x2e, 0x87, 0x01, - 0x72, 0x7d, 0x4e, 0x9c, 0xae, 0x60, 0x5c, 0xb1, 0x91, 0xa2, 0xbb, 0x96, 0xa2, 0x3b, 0x0e, 0xf6, - 0x74, 0xcf, 0xc2, 0x0e, 0x0d, 0x20, 0xc4, 0x43, 0x15, 0x5c, 0xc1, 0xec, 0x4f, 0xc5, 0xff, 0x8b, - 0xaf, 0xe6, 0x79, 0x0c, 0xfb, 0x6f, 0xa3, 0x76, 0x47, 0xf1, 0xac, 0x2a, 0xa2, 0x9e, 0x5e, 0x75, - 0xf9, 0x86, 0x42, 0x16, 0xaa, 0x11, 0x8b, 0x20, 0x66, 0xb6, 0x53, 0x4c, 0x7d, 0x4e, 0xa1, 0x9b, - 0x3a, 0x41, 0xa6, 0x66, 0x60, 0x87, 0xd6, 0xaa, 0x51, 0xc4, 0x1b, 0x5d, 0x22, 0xee, 0x5b, 0x04, - 0xf1, 0x6d, 0xd3, 0x1e, 0x72, 0x4c, 0x44, 0xaa, 0x96, 0xe3, 0x29, 0x06, 0x69, 0xb8, 0x1e, 0x56, - 0xee, 0xa2, 0x06, 0x57, 0x28, 0x9d, 0x03, 0x53, 0x1f, 0xf8, 0x35, 0x5b, 0xe4, 0xd8, 0x57, 0x90, - 0x83, 0xa8, 0x45, 0x55, 0x74, 0xaf, 0x86, 0xa8, 0x07, 0x8f, 0x82, 0xb1, 0x20, 0x81, 0x65, 0x4e, - 0x0a, 0xc7, 0x84, 0x99, 0x71, 0xf5, 0x3f, 0xec, 0xff, 0xb2, 0x29, 0x3d, 0x04, 0xd3, 0xe9, 0x91, - 0xd4, 0xc5, 0x0e, 0x45, 0xf0, 0x63, 0xb0, 0xb7, 0x12, 0x2c, 0x69, 0xd4, 0xd3, 0x3d, 0xc4, 0xe2, - 0x27, 0x0a, 0xb3, 0x72, 0xa7, 0xd7, 0x52, 0x9f, 0x93, 0x5b, 0xb0, 0x6e, 0xf8, 0x71, 0xa5, 0x5d, - 0xcf, 0x5e, 0xe6, 0x87, 0xd4, 0x3d, 0x95, 0xd8, 0x9a, 0x34, 0x0d, 0xc4, 0x44, 0xf2, 0x45, 0x1f, - 0x2e, 0x64, 0x2d, 0xe9, 0x2d, 0xa2, 0xc2, 0xa7, 0x9c, 0x59, 0x09, 0x8c, 0xb2, 0xf4, 0x74, 0x52, - 0x38, 0x36, 0x32, 0x33, 0x51, 0x38, 0x25, 0x67, 0xe8, 0x14, 0x99, 0x81, 0xa8, 0x3c, 0x52, 0x3a, - 0x09, 0xde, 0x6a, 0x4f, 0x71, 0xc3, 0xd3, 0x89, 0xb7, 0x46, 0xb0, 0x8b, 0xa9, 0x6e, 0x47, 0x6c, - 0x1e, 0x0b, 0x60, 0xa6, 0xf7, 0x5e, 0xce, 0xed, 0x13, 0x30, 0xee, 0x86, 0x8b, 0xbc, 0x62, 0x97, - 0xb2, 0xd1, 0xe3, 0xe0, 0x45, 0xd3, 0xb4, 0xfc, 0x16, 0x6e, 0x42, 0x37, 0x01, 0xa5, 0x19, 0xf0, - 0x66, 0x1a, 0x13, 0xec, 0xb6, 0x91, 0xfe, 0x42, 0x48, 0x17, 0x98, 0xd8, 0x1a, 0xbd, 0xe9, 0x36, - 0xce, 0xf3, 0x7d, 0x71, 0x56, 0x51, 0x15, 0xd7, 0x75, 0x3b, 0x95, 0xf2, 0x02, 0xd8, 0xcd, 0x52, - 0x77, 0x69, 0x45, 0x38, 0x05, 0xc6, 0x0d, 0xdb, 0x42, 0x8e, 0xe7, 0x3f, 0x1b, 0x66, 0xcf, 0xc6, - 0x82, 0x85, 0xb2, 0x29, 0x7d, 0x29, 0x80, 0xe3, 0x4c, 0xc9, 0xba, 0x6e, 0x5b, 0xa6, 0xee, 0x61, - 0x12, 0x2b, 0x15, 0xe9, 0xdd, 0xe8, 0x70, 0x1e, 0x1c, 0x08, 0x49, 0x6b, 0xba, 0x69, 0x12, 0x44, - 0x69, 0x90, 0xa4, 0x04, 0x5f, 0xbf, 0xcc, 0xef, 0x6b, 0xe8, 0x55, 0xfb, 0x82, 0xc4, 0x1f, 0x48, - 0xea, 0xfe, 0x70, 0x6f, 0x31, 0x58, 0xb9, 0x30, 0xf6, 0xf8, 0x69, 0x7e, 0xe8, 0xf7, 0xa7, 0xf9, - 0x21, 0xe9, 0x3a, 0x90, 0xba, 0x11, 0xe1, 0xd5, 0x3c, 0x09, 0x0e, 0x84, 0x07, 0x3d, 0x4a, 0x17, - 0x30, 0xda, 0x6f, 0xc4, 0xf6, 0xfb, 0xc9, 0xda, 0xa5, 0xad, 0xc5, 0x92, 0x67, 0x93, 0xd6, 0x96, - 0xab, 0x8b, 0xb4, 0x96, 0xfc, 0xdd, 0xa4, 0x25, 0x89, 0x34, 0xa5, 0xb5, 0x55, 0x92, 0x4b, 0x6b, - 0xa9, 0x9a, 0x34, 0x05, 0x8e, 0x32, 0xc0, 0x9b, 0x9b, 0x04, 0x7b, 0x9e, 0x8d, 0xd8, 0xb1, 0x0f, - 0x9b, 0xf3, 0x27, 0x81, 0x1f, 0xff, 0x96, 0xa7, 0x3c, 0x4d, 0x1e, 0x4c, 0x50, 0x5b, 0xa7, 0x9b, - 0x5a, 0x15, 0x79, 0x88, 0xb0, 0x0c, 0x23, 0x2a, 0x60, 0x4b, 0xd7, 0xfc, 0x15, 0x58, 0x00, 0xff, - 0x8b, 0x6d, 0xd0, 0x74, 0xdb, 0xc6, 0xf7, 0x75, 0xc7, 0x40, 0x4c, 0xfb, 0x88, 0x7a, 0xb0, 0xb9, - 0xb5, 0x18, 0x3e, 0x82, 0x9f, 0x82, 0x49, 0x07, 0x3d, 0xf0, 0x34, 0x82, 0x5c, 0x1b, 0x39, 0x16, - 0xdd, 0xd4, 0x0c, 0xdd, 0x31, 0x7d, 0xb1, 0x68, 0x72, 0x84, 0xf5, 0xbc, 0x28, 0x07, 0xf7, 0x82, - 0x1c, 0xde, 0x0b, 0xf2, 0xcd, 0xf0, 0x5e, 0x28, 0x8d, 0xf9, 0x33, 0xec, 0xc9, 0x2f, 0x79, 0x41, - 0x3d, 0xec, 0xa3, 0xa8, 0x21, 0xc8, 0x62, 0x88, 0x21, 0xbd, 0x0d, 0x4e, 0x31, 0x49, 0x2a, 0xaa, - 0x58, 0xd4, 0x43, 0x04, 0x99, 0xcd, 0xd3, 0x71, 0x5f, 0x27, 0xe6, 0x12, 0x72, 0x70, 0x35, 0x3a, - 0x9e, 0xcb, 0xe0, 0x74, 0xa6, 0xdd, 0xbc, 0x22, 0x87, 0xc1, 0xa8, 0xc9, 0x56, 0xd8, 0xc4, 0x1b, - 0x57, 0xf9, 0x7f, 0x52, 0x8e, 0xcf, 0xf0, 0xe0, 0xe4, 0x21, 0x93, 0x9d, 0xb4, 0xf2, 0x52, 0x94, - 0xe6, 0x91, 0x00, 0xfe, 0xdf, 0x61, 0x03, 0x47, 0xbe, 0x0d, 0xf6, 0xb9, 0xf1, 0x67, 0xe1, 0x4c, - 0x2d, 0x64, 0x1a, 0x00, 0x09, 0x58, 0x3e, 0xe8, 0x5b, 0xf0, 0xa4, 0x32, 0xd8, 0x9b, 0xd8, 0x06, - 0x27, 0x01, 0xef, 0xdf, 0xa5, 0x64, 0x3b, 0x2f, 0xc1, 0x1c, 0x00, 0xe1, 0xe0, 0x28, 0x2f, 0xb1, - 0x97, 0xb9, 0x4b, 0x8d, 0xad, 0x48, 0x57, 0x81, 0xc2, 0xd4, 0x14, 0x6d, 0x7b, 0x4d, 0xb7, 0x08, - 0x5d, 0xd7, 0xed, 0x45, 0xec, 0xf8, 0x2d, 0x57, 0x4a, 0xce, 0xb9, 0xf2, 0x52, 0x86, 0x0b, 0xf0, - 0x3b, 0x01, 0xcc, 0x66, 0x87, 0xe3, 0xf5, 0xba, 0x07, 0xfe, 0xeb, 0xea, 0x16, 0xd1, 0xea, 0xba, - 0xed, 0xdf, 0xe7, 0xec, 0x18, 0xf0, 0x92, 0xad, 0x64, 0x2b, 0x99, 0x6e, 0x91, 0x66, 0xa2, 0xe8, - 0x98, 0x39, 0xcd, 0x06, 0xd8, 0xe7, 0x26, 0xb6, 0x48, 0x7f, 0x09, 0xe0, 0x78, 0xcf, 0x28, 0xb8, - 0xd2, 0xe9, 0x6c, 0x96, 0xa6, 0x5e, 0xbf, 0xcc, 0x1f, 0x09, 0x46, 0x41, 0xeb, 0x8e, 0xf6, 0x71, - 0xe7, 0xe3, 0x74, 0x18, 0x29, 0x31, 0x9c, 0xd6, 0x1d, 0xed, 0xb3, 0x05, 0x2e, 0x80, 0x3d, 0xd1, - 0xae, 0xbb, 0xa8, 0xc1, 0xcf, 0xd8, 0xb4, 0xdc, 0x74, 0x33, 0x72, 0xe0, 0x66, 0xe4, 0xb5, 0xda, - 0x86, 0x6d, 0x19, 0xab, 0xa8, 0xa1, 0x4e, 0x84, 0x11, 0xab, 0xa8, 0x21, 0x1d, 0x02, 0x30, 0x68, - 0x5d, 0x9d, 0xe8, 0xcd, 0x83, 0x73, 0x1b, 0x1c, 0x4c, 0xac, 0xf2, 0xd7, 0x52, 0x06, 0xa3, 0x2e, - 0x5b, 0xe1, 0xf7, 0xd7, 0xe9, 0x8c, 0xef, 0xc2, 0x0f, 0xe1, 0x7d, 0xcb, 0x01, 0xa4, 0x79, 0x70, - 0x8c, 0x65, 0xb8, 0x6e, 0x9b, 0x88, 0x7a, 0xb7, 0x1c, 0x03, 0x3b, 0x77, 0x2c, 0x52, 0x45, 0xe6, - 0x3a, 0x35, 0x32, 0x74, 0xd5, 0x57, 0xe1, 0x4c, 0x4f, 0x8f, 0xe7, 0x7c, 0x2d, 0x00, 0xeb, 0xd4, - 0xd0, 0x28, 0x72, 0x4c, 0x2d, 0x72, 0x9f, 0x9c, 0xfb, 0xd9, 0x4c, 0xdc, 0xd7, 0xa9, 0x71, 0x03, - 0x39, 0x66, 0x73, 0x44, 0x05, 0x2a, 0x0e, 0xd4, 0x5b, 0xd6, 0x0b, 0x3f, 0x1c, 0x06, 0xbb, 0x19, - 0x21, 0xb8, 0x25, 0x80, 0x43, 0x69, 0x96, 0x0f, 0x5e, 0xce, 0x94, 0xb1, 0x8b, 0xcf, 0x14, 0x8b, - 0xdb, 0x40, 0x08, 0x4a, 0x22, 0x2d, 0x7f, 0xfe, 0xe2, 0xb7, 0xaf, 0x87, 0x17, 0xe0, 0x7c, 0xef, - 0x0f, 0x85, 0xa8, 0xb1, 0xb8, 0xa7, 0x54, 0x1e, 0x86, 0x6f, 0xe3, 0x33, 0xf8, 0x42, 0xe0, 0x1d, - 0x92, 0x34, 0x8f, 0x70, 0xa1, 0x7f, 0x86, 0x09, 0x53, 0x2a, 0x5e, 0x1e, 0x1c, 0x80, 0x2b, 0x3c, - 0xcf, 0x14, 0x9e, 0x81, 0x73, 0x7d, 0x28, 0x0c, 0xec, 0x2a, 0x7c, 0x34, 0x0c, 0x26, 0x3b, 0x78, - 0x50, 0x0a, 0xaf, 0x0e, 0xc8, 0x2c, 0xd5, 0xee, 0x8a, 0xd7, 0x76, 0x08, 0x8d, 0x8b, 0x7e, 0x9f, - 0x89, 0x2e, 0xc1, 0xcb, 0xfd, 0x8a, 0xf6, 0xbf, 0x3a, 0x88, 0xa7, 0x45, 0x4e, 0x12, 0xfe, 0x23, - 0x80, 0x23, 0xe9, 0x96, 0x96, 0xc2, 0xd5, 0x81, 0x49, 0xb7, 0x7b, 0x67, 0xf1, 0xea, 0xce, 0x80, - 0xf1, 0x02, 0x5c, 0x61, 0x05, 0x28, 0xc2, 0x85, 0x01, 0x0a, 0x80, 0xdd, 0x98, 0xfe, 0x3f, 0x43, - 0xd7, 0x94, 0xea, 0x3f, 0xe1, 0x4a, 0x76, 0xd6, 0xdd, 0x9c, 0xb4, 0x78, 0x65, 0xdb, 0x38, 0x5c, - 0x78, 0x91, 0x09, 0xbf, 0x08, 0xcf, 0x67, 0xf8, 0xf2, 0x0f, 0x81, 0xb4, 0xc4, 0xcd, 0x92, 0x22, - 0x39, 0xee, 0x4b, 0x07, 0x92, 0x9c, 0xe2, 0xb0, 0x07, 0x92, 0x9c, 0x66, 0x90, 0x07, 0x93, 0x9c, - 0xb8, 0x94, 0xe1, 0x8f, 0x02, 0xbf, 0xf7, 0x12, 0xde, 0x18, 0x5e, 0xca, 0x4e, 0x31, 0xcd, 0x72, - 0x8b, 0x0b, 0x03, 0xc7, 0x73, 0x69, 0xe7, 0x98, 0xb4, 0x02, 0x9c, 0xed, 0x2d, 0xcd, 0xe3, 0x00, - 0xc1, 0xef, 0x06, 0xf0, 0xdb, 0x61, 0x70, 0x22, 0x83, 0xd9, 0x85, 0xd7, 0xb3, 0x53, 0xcc, 0x64, - 0xb2, 0xc5, 0xb5, 0x9d, 0x03, 0xe4, 0x45, 0x58, 0x65, 0x45, 0x58, 0x86, 0x8b, 0xbd, 0x8b, 0x40, - 0x22, 0xc4, 0x66, 0x4f, 0x13, 0x86, 0xa9, 0x05, 0xe6, 0x1d, 0xfe, 0xd1, 0x66, 0xce, 0x93, 0x9e, - 0x93, 0xc2, 0x3e, 0x6e, 0xd5, 0x0e, 0x5f, 0x00, 0x62, 0x69, 0x3b, 0x10, 0x5c, 0x75, 0x89, 0xa9, - 0x7e, 0x0f, 0x5e, 0xe8, 0xad, 0x3a, 0xf4, 0xfe, 0x5a, 0xeb, 0x05, 0xf6, 0xcd, 0x30, 0xff, 0x11, - 0x25, 0x83, 0xd9, 0x86, 0x37, 0xb3, 0x93, 0xce, 0xfe, 0x29, 0x20, 0xde, 0xda, 0x61, 0x54, 0x5e, - 0x9d, 0x8b, 0xac, 0x3a, 0x67, 0xe1, 0x99, 0xbe, 0xe7, 0xbb, 0x65, 0xc2, 0xef, 0x05, 0x30, 0x11, - 0xf3, 0xb3, 0xf0, 0xdd, 0x3e, 0x5e, 0x57, 0xdc, 0x17, 0x8b, 0xe7, 0xfa, 0x0f, 0xe4, 0xfc, 0x67, - 0x19, 0xff, 0x53, 0x70, 0x26, 0xc3, 0xdb, 0x0d, 0x48, 0xfe, 0x2d, 0xf0, 0x8f, 0xfb, 0x34, 0x8b, - 0x0b, 0x97, 0xb3, 0x33, 0xe9, 0x62, 0xb1, 0xc5, 0x95, 0xed, 0xc2, 0xf4, 0x7f, 0x64, 0x31, 0xc3, - 0xd1, 0x6a, 0x4d, 0x20, 0xad, 0x4e, 0x8d, 0x98, 0xb9, 0x2c, 0x7d, 0xf8, 0x6c, 0x2b, 0x27, 0x3c, - 0xdf, 0xca, 0x09, 0xbf, 0x6e, 0xe5, 0x84, 0x27, 0xaf, 0x72, 0x43, 0xcf, 0x5f, 0xe5, 0x86, 0x7e, - 0x7e, 0x95, 0x1b, 0xfa, 0x68, 0xbe, 0x62, 0x79, 0x9b, 0xb5, 0x0d, 0xd9, 0xc0, 0x55, 0xc5, 0xc0, - 0xb4, 0x8a, 0x69, 0x2c, 0xdf, 0x3b, 0x51, 0xbe, 0xfa, 0x59, 0xe5, 0x41, 0xcb, 0xb0, 0x6c, 0xb8, - 0x88, 0x6e, 0x8c, 0xb2, 0xdf, 0x1c, 0xce, 0xfc, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xe9, 0x7c, 0xde, - 0xed, 0x25, 0x17, 0x00, 0x00, +func (m *QueryConsumerValidatorsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryConsumerValidatorsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryConsumerValidatorsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryConsumerValidatorsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryConsumerValidatorsRequest.Merge(m, src) +} +func (m *QueryConsumerValidatorsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryConsumerValidatorsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryConsumerValidatorsRequest.DiscardUnknown(m) } -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 +var xxx_messageInfo_QueryConsumerValidatorsRequest proto.InternalMessageInfo -// QueryClient is the client API for Query service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type QueryClient interface { - // ConsumerGenesis queries the genesis state needed to start a consumer chain - // whose proposal has been accepted - QueryConsumerGenesis(ctx context.Context, in *QueryConsumerGenesisRequest, opts ...grpc.CallOption) (*QueryConsumerGenesisResponse, error) - // ConsumerChains queries active consumer chains supported by the provider - // chain - QueryConsumerChains(ctx context.Context, in *QueryConsumerChainsRequest, opts ...grpc.CallOption) (*QueryConsumerChainsResponse, error) - // QueryConsumerChainStarts queries consumer chain start proposals. - QueryConsumerChainStarts(ctx context.Context, in *QueryConsumerChainStartProposalsRequest, opts ...grpc.CallOption) (*QueryConsumerChainStartProposalsResponse, error) - // QueryConsumerChainStops queries consumer chain stop proposals. - QueryConsumerChainStops(ctx context.Context, in *QueryConsumerChainStopProposalsRequest, opts ...grpc.CallOption) (*QueryConsumerChainStopProposalsResponse, error) - // QueryValidatorConsumerAddr queries the address - // assigned by a validator for a consumer chain. - QueryValidatorConsumerAddr(ctx context.Context, in *QueryValidatorConsumerAddrRequest, opts ...grpc.CallOption) (*QueryValidatorConsumerAddrResponse, error) - // QueryProviderAddr returns the provider chain validator - // given a consumer chain validator address - QueryValidatorProviderAddr(ctx context.Context, in *QueryValidatorProviderAddrRequest, opts ...grpc.CallOption) (*QueryValidatorProviderAddrResponse, error) - // QueryThrottleState returns the main on-chain state relevant to currently - // throttled slash packets - QueryThrottleState(ctx context.Context, in *QueryThrottleStateRequest, opts ...grpc.CallOption) (*QueryThrottleStateResponse, error) - // QueryRegisteredConsumerRewardDenoms returns a list of consumer reward - // denoms that are registered - QueryRegisteredConsumerRewardDenoms(ctx context.Context, in *QueryRegisteredConsumerRewardDenomsRequest, opts ...grpc.CallOption) (*QueryRegisteredConsumerRewardDenomsResponse, error) - // QueryProposedConsumerChainIDs returns the chain IDs of the proposed consumer chain addition proposals - // that are still in the voting period - QueryProposedConsumerChainIDs(ctx context.Context, in *QueryProposedChainIDsRequest, opts ...grpc.CallOption) (*QueryProposedChainIDsResponse, error) - // QueryAllPairsValConAddrByConsumerChainID returns a list of pair valconsensus address - // between provider and consumer chain - QueryAllPairsValConAddrByConsumerChainID(ctx context.Context, in *QueryAllPairsValConAddrByConsumerChainIDRequest, opts ...grpc.CallOption) (*QueryAllPairsValConAddrByConsumerChainIDResponse, error) - // QueryParams returns all current values of provider parameters - QueryParams(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) - // QueryOldestUnconfirmedVsc returns the send timestamp of the oldest unconfirmed VSCPacket for a given chainID - QueryOldestUnconfirmedVsc(ctx context.Context, in *QueryOldestUnconfirmedVscRequest, opts ...grpc.CallOption) (*QueryOldestUnconfirmedVscResponse, error) +func (m *QueryConsumerValidatorsRequest) GetChainId() string { + if m != nil { + return m.ChainId + } + return "" } -type queryClient struct { - cc grpc1.ClientConn +type QueryConsumerValidatorsValidator struct { + // The consensus address of the validator on the provider chain + ProviderAddress string `protobuf:"bytes,1,opt,name=provider_address,json=providerAddress,proto3" json:"provider_address,omitempty" yaml:"address"` + // The consumer public key of the validator used on the consumer chain + ConsumerKey *crypto.PublicKey `protobuf:"bytes,2,opt,name=consumer_key,json=consumerKey,proto3" json:"consumer_key,omitempty"` + // The power of the validator used on the consumer chain + Power int64 `protobuf:"varint,3,opt,name=power,proto3" json:"power,omitempty"` } -func NewQueryClient(cc grpc1.ClientConn) QueryClient { - return &queryClient{cc} +func (m *QueryConsumerValidatorsValidator) Reset() { *m = QueryConsumerValidatorsValidator{} } +func (m *QueryConsumerValidatorsValidator) String() string { return proto.CompactTextString(m) } +func (*QueryConsumerValidatorsValidator) ProtoMessage() {} +func (*QueryConsumerValidatorsValidator) Descriptor() ([]byte, []int) { + return fileDescriptor_422512d7b7586cd7, []int{28} } - -func (c *queryClient) QueryConsumerGenesis(ctx context.Context, in *QueryConsumerGenesisRequest, opts ...grpc.CallOption) (*QueryConsumerGenesisResponse, error) { - out := new(QueryConsumerGenesisResponse) - err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryConsumerGenesis", in, out, opts...) - if err != nil { - return nil, err +func (m *QueryConsumerValidatorsValidator) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryConsumerValidatorsValidator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryConsumerValidatorsValidator.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return out, nil +} +func (m *QueryConsumerValidatorsValidator) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryConsumerValidatorsValidator.Merge(m, src) +} +func (m *QueryConsumerValidatorsValidator) XXX_Size() int { + return m.Size() +} +func (m *QueryConsumerValidatorsValidator) XXX_DiscardUnknown() { + xxx_messageInfo_QueryConsumerValidatorsValidator.DiscardUnknown(m) } -func (c *queryClient) QueryConsumerChains(ctx context.Context, in *QueryConsumerChainsRequest, opts ...grpc.CallOption) (*QueryConsumerChainsResponse, error) { - out := new(QueryConsumerChainsResponse) - err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryConsumerChains", in, out, opts...) - if err != nil { - return nil, err +var xxx_messageInfo_QueryConsumerValidatorsValidator proto.InternalMessageInfo + +func (m *QueryConsumerValidatorsValidator) GetProviderAddress() string { + if m != nil { + return m.ProviderAddress } - return out, nil + return "" } -func (c *queryClient) QueryConsumerChainStarts(ctx context.Context, in *QueryConsumerChainStartProposalsRequest, opts ...grpc.CallOption) (*QueryConsumerChainStartProposalsResponse, error) { - out := new(QueryConsumerChainStartProposalsResponse) - err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryConsumerChainStarts", in, out, opts...) - if err != nil { - return nil, err +func (m *QueryConsumerValidatorsValidator) GetConsumerKey() *crypto.PublicKey { + if m != nil { + return m.ConsumerKey } - return out, nil + return nil } -func (c *queryClient) QueryConsumerChainStops(ctx context.Context, in *QueryConsumerChainStopProposalsRequest, opts ...grpc.CallOption) (*QueryConsumerChainStopProposalsResponse, error) { - out := new(QueryConsumerChainStopProposalsResponse) - err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryConsumerChainStops", in, out, opts...) - if err != nil { - return nil, err +func (m *QueryConsumerValidatorsValidator) GetPower() int64 { + if m != nil { + return m.Power } - return out, nil + return 0 } -func (c *queryClient) QueryValidatorConsumerAddr(ctx context.Context, in *QueryValidatorConsumerAddrRequest, opts ...grpc.CallOption) (*QueryValidatorConsumerAddrResponse, error) { - out := new(QueryValidatorConsumerAddrResponse) - err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryValidatorConsumerAddr", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil +type QueryConsumerValidatorsResponse struct { + Validators []*QueryConsumerValidatorsValidator `protobuf:"bytes,1,rep,name=validators,proto3" json:"validators,omitempty"` } -func (c *queryClient) QueryValidatorProviderAddr(ctx context.Context, in *QueryValidatorProviderAddrRequest, opts ...grpc.CallOption) (*QueryValidatorProviderAddrResponse, error) { - out := new(QueryValidatorProviderAddrResponse) - err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryValidatorProviderAddr", in, out, opts...) - if err != nil { - return nil, err +func (m *QueryConsumerValidatorsResponse) Reset() { *m = QueryConsumerValidatorsResponse{} } +func (m *QueryConsumerValidatorsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryConsumerValidatorsResponse) ProtoMessage() {} +func (*QueryConsumerValidatorsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_422512d7b7586cd7, []int{29} +} +func (m *QueryConsumerValidatorsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryConsumerValidatorsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryConsumerValidatorsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return out, nil +} +func (m *QueryConsumerValidatorsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryConsumerValidatorsResponse.Merge(m, src) +} +func (m *QueryConsumerValidatorsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryConsumerValidatorsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryConsumerValidatorsResponse.DiscardUnknown(m) } -func (c *queryClient) QueryThrottleState(ctx context.Context, in *QueryThrottleStateRequest, opts ...grpc.CallOption) (*QueryThrottleStateResponse, error) { - out := new(QueryThrottleStateResponse) - err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryThrottleState", in, out, opts...) - if err != nil { - return nil, err +var xxx_messageInfo_QueryConsumerValidatorsResponse proto.InternalMessageInfo + +func (m *QueryConsumerValidatorsResponse) GetValidators() []*QueryConsumerValidatorsValidator { + if m != nil { + return m.Validators } - return out, nil + return nil } -func (c *queryClient) QueryRegisteredConsumerRewardDenoms(ctx context.Context, in *QueryRegisteredConsumerRewardDenomsRequest, opts ...grpc.CallOption) (*QueryRegisteredConsumerRewardDenomsResponse, error) { - out := new(QueryRegisteredConsumerRewardDenomsResponse) - err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryRegisteredConsumerRewardDenoms", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil +type QueryConsumerChainsValidatorHasToValidateRequest struct { + // The consensus address of the validator on the provider chain + ProviderAddress string `protobuf:"bytes,1,opt,name=provider_address,json=providerAddress,proto3" json:"provider_address,omitempty" yaml:"address"` } -func (c *queryClient) QueryProposedConsumerChainIDs(ctx context.Context, in *QueryProposedChainIDsRequest, opts ...grpc.CallOption) (*QueryProposedChainIDsResponse, error) { - out := new(QueryProposedChainIDsResponse) - err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryProposedConsumerChainIDs", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil +func (m *QueryConsumerChainsValidatorHasToValidateRequest) Reset() { + *m = QueryConsumerChainsValidatorHasToValidateRequest{} } - -func (c *queryClient) QueryAllPairsValConAddrByConsumerChainID(ctx context.Context, in *QueryAllPairsValConAddrByConsumerChainIDRequest, opts ...grpc.CallOption) (*QueryAllPairsValConAddrByConsumerChainIDResponse, error) { - out := new(QueryAllPairsValConAddrByConsumerChainIDResponse) - err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryAllPairsValConAddrByConsumerChainID", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil +func (m *QueryConsumerChainsValidatorHasToValidateRequest) String() string { + return proto.CompactTextString(m) } - -func (c *queryClient) QueryParams(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { - out := new(QueryParamsResponse) - err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryParams", in, out, opts...) - if err != nil { - return nil, err +func (*QueryConsumerChainsValidatorHasToValidateRequest) ProtoMessage() {} +func (*QueryConsumerChainsValidatorHasToValidateRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_422512d7b7586cd7, []int{30} +} +func (m *QueryConsumerChainsValidatorHasToValidateRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryConsumerChainsValidatorHasToValidateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryConsumerChainsValidatorHasToValidateRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return out, nil +} +func (m *QueryConsumerChainsValidatorHasToValidateRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryConsumerChainsValidatorHasToValidateRequest.Merge(m, src) +} +func (m *QueryConsumerChainsValidatorHasToValidateRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryConsumerChainsValidatorHasToValidateRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryConsumerChainsValidatorHasToValidateRequest.DiscardUnknown(m) } -func (c *queryClient) QueryOldestUnconfirmedVsc(ctx context.Context, in *QueryOldestUnconfirmedVscRequest, opts ...grpc.CallOption) (*QueryOldestUnconfirmedVscResponse, error) { - out := new(QueryOldestUnconfirmedVscResponse) - err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryOldestUnconfirmedVsc", in, out, opts...) - if err != nil { - return nil, err +var xxx_messageInfo_QueryConsumerChainsValidatorHasToValidateRequest proto.InternalMessageInfo + +func (m *QueryConsumerChainsValidatorHasToValidateRequest) GetProviderAddress() string { + if m != nil { + return m.ProviderAddress } - return out, nil + return "" } -// QueryServer is the server API for Query service. -type QueryServer interface { - // ConsumerGenesis queries the genesis state needed to start a consumer chain - // whose proposal has been accepted - QueryConsumerGenesis(context.Context, *QueryConsumerGenesisRequest) (*QueryConsumerGenesisResponse, error) - // ConsumerChains queries active consumer chains supported by the provider - // chain - QueryConsumerChains(context.Context, *QueryConsumerChainsRequest) (*QueryConsumerChainsResponse, error) - // QueryConsumerChainStarts queries consumer chain start proposals. - QueryConsumerChainStarts(context.Context, *QueryConsumerChainStartProposalsRequest) (*QueryConsumerChainStartProposalsResponse, error) - // QueryConsumerChainStops queries consumer chain stop proposals. - QueryConsumerChainStops(context.Context, *QueryConsumerChainStopProposalsRequest) (*QueryConsumerChainStopProposalsResponse, error) - // QueryValidatorConsumerAddr queries the address - // assigned by a validator for a consumer chain. - QueryValidatorConsumerAddr(context.Context, *QueryValidatorConsumerAddrRequest) (*QueryValidatorConsumerAddrResponse, error) - // QueryProviderAddr returns the provider chain validator - // given a consumer chain validator address - QueryValidatorProviderAddr(context.Context, *QueryValidatorProviderAddrRequest) (*QueryValidatorProviderAddrResponse, error) - // QueryThrottleState returns the main on-chain state relevant to currently - // throttled slash packets - QueryThrottleState(context.Context, *QueryThrottleStateRequest) (*QueryThrottleStateResponse, error) - // QueryRegisteredConsumerRewardDenoms returns a list of consumer reward - // denoms that are registered - QueryRegisteredConsumerRewardDenoms(context.Context, *QueryRegisteredConsumerRewardDenomsRequest) (*QueryRegisteredConsumerRewardDenomsResponse, error) - // QueryProposedConsumerChainIDs returns the chain IDs of the proposed consumer chain addition proposals - // that are still in the voting period - QueryProposedConsumerChainIDs(context.Context, *QueryProposedChainIDsRequest) (*QueryProposedChainIDsResponse, error) - // QueryAllPairsValConAddrByConsumerChainID returns a list of pair valconsensus address - // between provider and consumer chain - QueryAllPairsValConAddrByConsumerChainID(context.Context, *QueryAllPairsValConAddrByConsumerChainIDRequest) (*QueryAllPairsValConAddrByConsumerChainIDResponse, error) - // QueryParams returns all current values of provider parameters - QueryParams(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) - // QueryOldestUnconfirmedVsc returns the send timestamp of the oldest unconfirmed VSCPacket for a given chainID - QueryOldestUnconfirmedVsc(context.Context, *QueryOldestUnconfirmedVscRequest) (*QueryOldestUnconfirmedVscResponse, error) +type QueryConsumerChainsValidatorHasToValidateResponse struct { + ConsumerChainIds []string `protobuf:"bytes,1,rep,name=consumer_chain_ids,json=consumerChainIds,proto3" json:"consumer_chain_ids,omitempty"` } -// UnimplementedQueryServer can be embedded to have forward compatible implementations. -type UnimplementedQueryServer struct { +func (m *QueryConsumerChainsValidatorHasToValidateResponse) Reset() { + *m = QueryConsumerChainsValidatorHasToValidateResponse{} } - -func (*UnimplementedQueryServer) QueryConsumerGenesis(ctx context.Context, req *QueryConsumerGenesisRequest) (*QueryConsumerGenesisResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryConsumerGenesis not implemented") +func (m *QueryConsumerChainsValidatorHasToValidateResponse) String() string { + return proto.CompactTextString(m) } -func (*UnimplementedQueryServer) QueryConsumerChains(ctx context.Context, req *QueryConsumerChainsRequest) (*QueryConsumerChainsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryConsumerChains not implemented") +func (*QueryConsumerChainsValidatorHasToValidateResponse) ProtoMessage() {} +func (*QueryConsumerChainsValidatorHasToValidateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_422512d7b7586cd7, []int{31} } -func (*UnimplementedQueryServer) QueryConsumerChainStarts(ctx context.Context, req *QueryConsumerChainStartProposalsRequest) (*QueryConsumerChainStartProposalsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryConsumerChainStarts not implemented") +func (m *QueryConsumerChainsValidatorHasToValidateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) } -func (*UnimplementedQueryServer) QueryConsumerChainStops(ctx context.Context, req *QueryConsumerChainStopProposalsRequest) (*QueryConsumerChainStopProposalsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryConsumerChainStops not implemented") +func (m *QueryConsumerChainsValidatorHasToValidateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryConsumerChainsValidatorHasToValidateResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } } -func (*UnimplementedQueryServer) QueryValidatorConsumerAddr(ctx context.Context, req *QueryValidatorConsumerAddrRequest) (*QueryValidatorConsumerAddrResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryValidatorConsumerAddr not implemented") +func (m *QueryConsumerChainsValidatorHasToValidateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryConsumerChainsValidatorHasToValidateResponse.Merge(m, src) } -func (*UnimplementedQueryServer) QueryValidatorProviderAddr(ctx context.Context, req *QueryValidatorProviderAddrRequest) (*QueryValidatorProviderAddrResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryValidatorProviderAddr not implemented") +func (m *QueryConsumerChainsValidatorHasToValidateResponse) XXX_Size() int { + return m.Size() } -func (*UnimplementedQueryServer) QueryThrottleState(ctx context.Context, req *QueryThrottleStateRequest) (*QueryThrottleStateResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryThrottleState not implemented") +func (m *QueryConsumerChainsValidatorHasToValidateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryConsumerChainsValidatorHasToValidateResponse.DiscardUnknown(m) } -func (*UnimplementedQueryServer) QueryRegisteredConsumerRewardDenoms(ctx context.Context, req *QueryRegisteredConsumerRewardDenomsRequest) (*QueryRegisteredConsumerRewardDenomsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryRegisteredConsumerRewardDenoms not implemented") + +var xxx_messageInfo_QueryConsumerChainsValidatorHasToValidateResponse proto.InternalMessageInfo + +func (m *QueryConsumerChainsValidatorHasToValidateResponse) GetConsumerChainIds() []string { + if m != nil { + return m.ConsumerChainIds + } + return nil } -func (*UnimplementedQueryServer) QueryProposedConsumerChainIDs(ctx context.Context, req *QueryProposedChainIDsRequest) (*QueryProposedChainIDsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryProposedConsumerChainIDs not implemented") + +type QueryValidatorConsumerCommissionRateRequest struct { + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // The consensus address of the validator on the provider chain + ProviderAddress string `protobuf:"bytes,2,opt,name=provider_address,json=providerAddress,proto3" json:"provider_address,omitempty" yaml:"address"` } -func (*UnimplementedQueryServer) QueryAllPairsValConAddrByConsumerChainID(ctx context.Context, req *QueryAllPairsValConAddrByConsumerChainIDRequest) (*QueryAllPairsValConAddrByConsumerChainIDResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryAllPairsValConAddrByConsumerChainID not implemented") + +func (m *QueryValidatorConsumerCommissionRateRequest) Reset() { + *m = QueryValidatorConsumerCommissionRateRequest{} } -func (*UnimplementedQueryServer) QueryParams(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryParams not implemented") +func (m *QueryValidatorConsumerCommissionRateRequest) String() string { + return proto.CompactTextString(m) } -func (*UnimplementedQueryServer) QueryOldestUnconfirmedVsc(ctx context.Context, req *QueryOldestUnconfirmedVscRequest) (*QueryOldestUnconfirmedVscResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryOldestUnconfirmedVsc not implemented") +func (*QueryValidatorConsumerCommissionRateRequest) ProtoMessage() {} +func (*QueryValidatorConsumerCommissionRateRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_422512d7b7586cd7, []int{32} } - -func RegisterQueryServer(s grpc1.Server, srv QueryServer) { - s.RegisterService(&_Query_serviceDesc, srv) +func (m *QueryValidatorConsumerCommissionRateRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) } - -func _Query_QueryConsumerGenesis_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryConsumerGenesisRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).QueryConsumerGenesis(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryConsumerGenesis", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).QueryConsumerGenesis(ctx, req.(*QueryConsumerGenesisRequest)) +func (m *QueryValidatorConsumerCommissionRateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryValidatorConsumerCommissionRateRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return interceptor(ctx, in, info, handler) } - -func _Query_QueryConsumerChains_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryConsumerChainsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).QueryConsumerChains(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryConsumerChains", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).QueryConsumerChains(ctx, req.(*QueryConsumerChainsRequest)) - } - return interceptor(ctx, in, info, handler) +func (m *QueryValidatorConsumerCommissionRateRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryValidatorConsumerCommissionRateRequest.Merge(m, src) } - -func _Query_QueryConsumerChainStarts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryConsumerChainStartProposalsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).QueryConsumerChainStarts(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryConsumerChainStarts", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).QueryConsumerChainStarts(ctx, req.(*QueryConsumerChainStartProposalsRequest)) - } - return interceptor(ctx, in, info, handler) +func (m *QueryValidatorConsumerCommissionRateRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryValidatorConsumerCommissionRateRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryValidatorConsumerCommissionRateRequest.DiscardUnknown(m) } -func _Query_QueryConsumerChainStops_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryConsumerChainStopProposalsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).QueryConsumerChainStops(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryConsumerChainStops", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).QueryConsumerChainStops(ctx, req.(*QueryConsumerChainStopProposalsRequest)) +var xxx_messageInfo_QueryValidatorConsumerCommissionRateRequest proto.InternalMessageInfo + +func (m *QueryValidatorConsumerCommissionRateRequest) GetChainId() string { + if m != nil { + return m.ChainId } - return interceptor(ctx, in, info, handler) + return "" } -func _Query_QueryValidatorConsumerAddr_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryValidatorConsumerAddrRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).QueryValidatorConsumerAddr(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryValidatorConsumerAddr", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).QueryValidatorConsumerAddr(ctx, req.(*QueryValidatorConsumerAddrRequest)) +func (m *QueryValidatorConsumerCommissionRateRequest) GetProviderAddress() string { + if m != nil { + return m.ProviderAddress } - return interceptor(ctx, in, info, handler) + return "" } -func _Query_QueryValidatorProviderAddr_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryValidatorProviderAddrRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).QueryValidatorProviderAddr(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryValidatorProviderAddr", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).QueryValidatorProviderAddr(ctx, req.(*QueryValidatorProviderAddrRequest)) - } - return interceptor(ctx, in, info, handler) +type QueryValidatorConsumerCommissionRateResponse struct { + // The rate to charge delegators on the consumer chain, as a fraction + Rate cosmossdk_io_math.LegacyDec `protobuf:"bytes,1,opt,name=rate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"rate"` } -func _Query_QueryThrottleState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryThrottleStateRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).QueryThrottleState(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryThrottleState", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).QueryThrottleState(ctx, req.(*QueryThrottleStateRequest)) - } - return interceptor(ctx, in, info, handler) +func (m *QueryValidatorConsumerCommissionRateResponse) Reset() { + *m = QueryValidatorConsumerCommissionRateResponse{} } - -func _Query_QueryRegisteredConsumerRewardDenoms_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryRegisteredConsumerRewardDenomsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).QueryRegisteredConsumerRewardDenoms(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryRegisteredConsumerRewardDenoms", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).QueryRegisteredConsumerRewardDenoms(ctx, req.(*QueryRegisteredConsumerRewardDenomsRequest)) - } - return interceptor(ctx, in, info, handler) +func (m *QueryValidatorConsumerCommissionRateResponse) String() string { + return proto.CompactTextString(m) } - -func _Query_QueryProposedConsumerChainIDs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryProposedChainIDsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).QueryProposedConsumerChainIDs(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryProposedConsumerChainIDs", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).QueryProposedConsumerChainIDs(ctx, req.(*QueryProposedChainIDsRequest)) - } - return interceptor(ctx, in, info, handler) +func (*QueryValidatorConsumerCommissionRateResponse) ProtoMessage() {} +func (*QueryValidatorConsumerCommissionRateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_422512d7b7586cd7, []int{33} } - -func _Query_QueryAllPairsValConAddrByConsumerChainID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryAllPairsValConAddrByConsumerChainIDRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).QueryAllPairsValConAddrByConsumerChainID(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryAllPairsValConAddrByConsumerChainID", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).QueryAllPairsValConAddrByConsumerChainID(ctx, req.(*QueryAllPairsValConAddrByConsumerChainIDRequest)) - } - return interceptor(ctx, in, info, handler) +func (m *QueryValidatorConsumerCommissionRateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) } - -func _Query_QueryParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryParamsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).QueryParams(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryParams", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).QueryParams(ctx, req.(*QueryParamsRequest)) +func (m *QueryValidatorConsumerCommissionRateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryValidatorConsumerCommissionRateResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil } - return interceptor(ctx, in, info, handler) } - -func _Query_QueryOldestUnconfirmedVsc_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryOldestUnconfirmedVscRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).QueryOldestUnconfirmedVsc(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryOldestUnconfirmedVsc", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).QueryOldestUnconfirmedVsc(ctx, req.(*QueryOldestUnconfirmedVscRequest)) - } - return interceptor(ctx, in, info, handler) +func (m *QueryValidatorConsumerCommissionRateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryValidatorConsumerCommissionRateResponse.Merge(m, src) } - -var _Query_serviceDesc = grpc.ServiceDesc{ - ServiceName: "interchain_security.ccv.provider.v1.Query", - HandlerType: (*QueryServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "QueryConsumerGenesis", - Handler: _Query_QueryConsumerGenesis_Handler, - }, - { - MethodName: "QueryConsumerChains", - Handler: _Query_QueryConsumerChains_Handler, - }, - { - MethodName: "QueryConsumerChainStarts", - Handler: _Query_QueryConsumerChainStarts_Handler, - }, - { - MethodName: "QueryConsumerChainStops", - Handler: _Query_QueryConsumerChainStops_Handler, - }, - { - MethodName: "QueryValidatorConsumerAddr", - Handler: _Query_QueryValidatorConsumerAddr_Handler, - }, - { - MethodName: "QueryValidatorProviderAddr", - Handler: _Query_QueryValidatorProviderAddr_Handler, - }, - { - MethodName: "QueryThrottleState", - Handler: _Query_QueryThrottleState_Handler, - }, - { - MethodName: "QueryRegisteredConsumerRewardDenoms", - Handler: _Query_QueryRegisteredConsumerRewardDenoms_Handler, - }, - { - MethodName: "QueryProposedConsumerChainIDs", - Handler: _Query_QueryProposedConsumerChainIDs_Handler, - }, - { - MethodName: "QueryAllPairsValConAddrByConsumerChainID", - Handler: _Query_QueryAllPairsValConAddrByConsumerChainID_Handler, - }, - { - MethodName: "QueryParams", - Handler: _Query_QueryParams_Handler, - }, - { - MethodName: "QueryOldestUnconfirmedVsc", - Handler: _Query_QueryOldestUnconfirmedVsc_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "interchain_security/ccv/provider/v1/query.proto", +func (m *QueryValidatorConsumerCommissionRateResponse) XXX_Size() int { + return m.Size() } - -func (m *QueryConsumerGenesisRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil +func (m *QueryValidatorConsumerCommissionRateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryValidatorConsumerCommissionRateResponse.DiscardUnknown(m) } -func (m *QueryConsumerGenesisRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} +var xxx_messageInfo_QueryValidatorConsumerCommissionRateResponse proto.InternalMessageInfo -func (m *QueryConsumerGenesisRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil +type QueryOldestUnconfirmedVscRequest struct { + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` } -func (m *QueryConsumerGenesisResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil +func (m *QueryOldestUnconfirmedVscRequest) Reset() { *m = QueryOldestUnconfirmedVscRequest{} } +func (m *QueryOldestUnconfirmedVscRequest) String() string { return proto.CompactTextString(m) } +func (*QueryOldestUnconfirmedVscRequest) ProtoMessage() {} +func (*QueryOldestUnconfirmedVscRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_422512d7b7586cd7, []int{34} } - -func (m *QueryConsumerGenesisResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (m *QueryOldestUnconfirmedVscRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) } - -func (m *QueryConsumerGenesisResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.GenesisState.MarshalToSizedBuffer(dAtA[:i]) +func (m *QueryOldestUnconfirmedVscRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryOldestUnconfirmedVscRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) if err != nil { - return 0, err + return nil, err } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) + return b[:n], nil } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil } - -func (m *QueryConsumerChainsRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil +func (m *QueryOldestUnconfirmedVscRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryOldestUnconfirmedVscRequest.Merge(m, src) } - -func (m *QueryConsumerChainsRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (m *QueryOldestUnconfirmedVscRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryOldestUnconfirmedVscRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryOldestUnconfirmedVscRequest.DiscardUnknown(m) } -func (m *QueryConsumerChainsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} +var xxx_messageInfo_QueryOldestUnconfirmedVscRequest proto.InternalMessageInfo -func (m *QueryConsumerChainsResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err +func (m *QueryOldestUnconfirmedVscRequest) GetChainId() string { + if m != nil { + return m.ChainId } - return dAtA[:n], nil + return "" } -func (m *QueryConsumerChainsResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +type QueryOldestUnconfirmedVscResponse struct { + VscSendTimestamp VscSendTimestamp `protobuf:"bytes,1,opt,name=vsc_send_timestamp,json=vscSendTimestamp,proto3" json:"vsc_send_timestamp"` } -func (m *QueryConsumerChainsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Chains) > 0 { - for iNdEx := len(m.Chains) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Chains[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa +func (m *QueryOldestUnconfirmedVscResponse) Reset() { *m = QueryOldestUnconfirmedVscResponse{} } +func (m *QueryOldestUnconfirmedVscResponse) String() string { return proto.CompactTextString(m) } +func (*QueryOldestUnconfirmedVscResponse) ProtoMessage() {} +func (*QueryOldestUnconfirmedVscResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_422512d7b7586cd7, []int{35} +} +func (m *QueryOldestUnconfirmedVscResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryOldestUnconfirmedVscResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryOldestUnconfirmedVscResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err } + return b[:n], nil } - return len(dAtA) - i, nil +} +func (m *QueryOldestUnconfirmedVscResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryOldestUnconfirmedVscResponse.Merge(m, src) +} +func (m *QueryOldestUnconfirmedVscResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryOldestUnconfirmedVscResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryOldestUnconfirmedVscResponse.DiscardUnknown(m) } -func (m *QueryConsumerChainStartProposalsRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err +var xxx_messageInfo_QueryOldestUnconfirmedVscResponse proto.InternalMessageInfo + +func (m *QueryOldestUnconfirmedVscResponse) GetVscSendTimestamp() VscSendTimestamp { + if m != nil { + return m.VscSendTimestamp } - return dAtA[:n], nil + return VscSendTimestamp{} } -func (m *QueryConsumerChainStartProposalsRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func init() { + proto.RegisterType((*QueryConsumerGenesisRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerGenesisRequest") + proto.RegisterType((*QueryConsumerGenesisResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerGenesisResponse") + proto.RegisterType((*QueryConsumerChainsRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainsRequest") + proto.RegisterType((*QueryConsumerChainsResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainsResponse") + proto.RegisterType((*QueryConsumerChainStartProposalsRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainStartProposalsRequest") + proto.RegisterType((*QueryConsumerChainStartProposalsResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainStartProposalsResponse") + proto.RegisterType((*QueryConsumerChainStopProposalsRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainStopProposalsRequest") + proto.RegisterType((*QueryConsumerChainStopProposalsResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainStopProposalsResponse") + proto.RegisterType((*Chain)(nil), "interchain_security.ccv.provider.v1.Chain") + proto.RegisterType((*QueryValidatorConsumerAddrRequest)(nil), "interchain_security.ccv.provider.v1.QueryValidatorConsumerAddrRequest") + proto.RegisterType((*QueryValidatorConsumerAddrResponse)(nil), "interchain_security.ccv.provider.v1.QueryValidatorConsumerAddrResponse") + proto.RegisterType((*QueryValidatorProviderAddrRequest)(nil), "interchain_security.ccv.provider.v1.QueryValidatorProviderAddrRequest") + proto.RegisterType((*QueryValidatorProviderAddrResponse)(nil), "interchain_security.ccv.provider.v1.QueryValidatorProviderAddrResponse") + proto.RegisterType((*QueryThrottleStateRequest)(nil), "interchain_security.ccv.provider.v1.QueryThrottleStateRequest") + proto.RegisterType((*QueryThrottleStateResponse)(nil), "interchain_security.ccv.provider.v1.QueryThrottleStateResponse") + proto.RegisterType((*QueryRegisteredConsumerRewardDenomsRequest)(nil), "interchain_security.ccv.provider.v1.QueryRegisteredConsumerRewardDenomsRequest") + proto.RegisterType((*QueryRegisteredConsumerRewardDenomsResponse)(nil), "interchain_security.ccv.provider.v1.QueryRegisteredConsumerRewardDenomsResponse") + proto.RegisterType((*QueryProposedChainIDsRequest)(nil), "interchain_security.ccv.provider.v1.QueryProposedChainIDsRequest") + proto.RegisterType((*QueryProposedChainIDsResponse)(nil), "interchain_security.ccv.provider.v1.QueryProposedChainIDsResponse") + proto.RegisterType((*ProposedChain)(nil), "interchain_security.ccv.provider.v1.ProposedChain") + proto.RegisterType((*QueryAllPairsValConAddrByConsumerChainIDRequest)(nil), "interchain_security.ccv.provider.v1.QueryAllPairsValConAddrByConsumerChainIDRequest") + proto.RegisterType((*QueryAllPairsValConAddrByConsumerChainIDResponse)(nil), "interchain_security.ccv.provider.v1.QueryAllPairsValConAddrByConsumerChainIDResponse") + proto.RegisterType((*PairValConAddrProviderAndConsumer)(nil), "interchain_security.ccv.provider.v1.PairValConAddrProviderAndConsumer") + proto.RegisterType((*QueryParamsRequest)(nil), "interchain_security.ccv.provider.v1.QueryParamsRequest") + proto.RegisterType((*QueryParamsResponse)(nil), "interchain_security.ccv.provider.v1.QueryParamsResponse") + proto.RegisterType((*QueryConsumerChainOptedInValidatorsRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainOptedInValidatorsRequest") + proto.RegisterType((*QueryConsumerChainOptedInValidatorsResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainOptedInValidatorsResponse") + proto.RegisterType((*QueryConsumerValidatorsRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerValidatorsRequest") + proto.RegisterType((*QueryConsumerValidatorsValidator)(nil), "interchain_security.ccv.provider.v1.QueryConsumerValidatorsValidator") + proto.RegisterType((*QueryConsumerValidatorsResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerValidatorsResponse") + proto.RegisterType((*QueryConsumerChainsValidatorHasToValidateRequest)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainsValidatorHasToValidateRequest") + proto.RegisterType((*QueryConsumerChainsValidatorHasToValidateResponse)(nil), "interchain_security.ccv.provider.v1.QueryConsumerChainsValidatorHasToValidateResponse") + proto.RegisterType((*QueryValidatorConsumerCommissionRateRequest)(nil), "interchain_security.ccv.provider.v1.QueryValidatorConsumerCommissionRateRequest") + proto.RegisterType((*QueryValidatorConsumerCommissionRateResponse)(nil), "interchain_security.ccv.provider.v1.QueryValidatorConsumerCommissionRateResponse") + proto.RegisterType((*QueryOldestUnconfirmedVscRequest)(nil), "interchain_security.ccv.provider.v1.QueryOldestUnconfirmedVscRequest") + proto.RegisterType((*QueryOldestUnconfirmedVscResponse)(nil), "interchain_security.ccv.provider.v1.QueryOldestUnconfirmedVscResponse") } -func (m *QueryConsumerChainStartProposalsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil +func init() { + proto.RegisterFile("interchain_security/ccv/provider/v1/query.proto", fileDescriptor_422512d7b7586cd7) } -func (m *QueryConsumerChainStartProposalsResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil +var fileDescriptor_422512d7b7586cd7 = []byte{ + // 2045 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xcf, 0x6f, 0xdc, 0xc6, + 0xf5, 0x17, 0x57, 0x3f, 0x22, 0x8d, 0xe2, 0x5f, 0x63, 0x7d, 0x13, 0x99, 0x52, 0x76, 0x15, 0xe6, + 0xdb, 0x56, 0x96, 0x9d, 0xa5, 0x24, 0xc3, 0xad, 0x63, 0x57, 0x91, 0xb5, 0x5a, 0xdb, 0xd9, 0xda, + 0x89, 0x15, 0x5a, 0x56, 0x0b, 0xb7, 0x28, 0x3d, 0x26, 0x27, 0x2b, 0xc2, 0x24, 0x87, 0xe2, 0x50, + 0xeb, 0x6c, 0x8d, 0x1c, 0xd2, 0x43, 0x9b, 0x53, 0x11, 0xf4, 0x07, 0xd0, 0x63, 0x2e, 0x05, 0x7a, + 0x29, 0x50, 0x14, 0x45, 0x91, 0x3f, 0x21, 0xb7, 0xa6, 0xcd, 0xa5, 0xe8, 0xc1, 0x2d, 0xec, 0x02, + 0x2d, 0x7a, 0x28, 0x8a, 0xa0, 0x40, 0x4f, 0x05, 0x0a, 0x0e, 0x87, 0xbf, 0x76, 0xb9, 0xbb, 0xe4, + 0xae, 0x7a, 0x11, 0x96, 0x33, 0x6f, 0x3e, 0xf3, 0xde, 0x9b, 0xf7, 0xde, 0xbc, 0xcf, 0x08, 0xc8, + 0x86, 0xed, 0x61, 0x57, 0xdb, 0x47, 0x86, 0xad, 0x52, 0xac, 0x1d, 0xba, 0x86, 0xd7, 0x96, 0x35, + 0xad, 0x25, 0x3b, 0x2e, 0x69, 0x19, 0x3a, 0x76, 0xe5, 0xd6, 0x9a, 0x7c, 0x70, 0x88, 0xdd, 0x76, + 0xd5, 0x71, 0x89, 0x47, 0xe0, 0x2b, 0x19, 0x0b, 0xaa, 0x9a, 0xd6, 0xaa, 0x86, 0x0b, 0xaa, 0xad, + 0x35, 0x71, 0xb1, 0x49, 0x48, 0xd3, 0xc4, 0x32, 0x72, 0x0c, 0x19, 0xd9, 0x36, 0xf1, 0x90, 0x67, + 0x10, 0x9b, 0x06, 0x10, 0xe2, 0x5c, 0x93, 0x34, 0x09, 0xfb, 0x29, 0xfb, 0xbf, 0xf8, 0x68, 0x85, + 0xaf, 0x61, 0x5f, 0x0f, 0x0e, 0xdf, 0x91, 0x3d, 0xc3, 0xc2, 0xd4, 0x43, 0x96, 0xc3, 0x05, 0xd6, + 0xf3, 0xa8, 0x1a, 0x69, 0x11, 0xac, 0x59, 0xed, 0xb5, 0xa6, 0xb5, 0x26, 0xd3, 0x7d, 0xe4, 0x62, + 0x5d, 0xd5, 0x88, 0x4d, 0x0f, 0xad, 0x68, 0xc5, 0x17, 0xfa, 0xac, 0x78, 0x64, 0xb8, 0x98, 0x8b, + 0x2d, 0x7a, 0xd8, 0xd6, 0xb1, 0x6b, 0x19, 0xb6, 0x27, 0x6b, 0x6e, 0xdb, 0xf1, 0x88, 0xfc, 0x10, + 0xb7, 0x43, 0x0b, 0xcf, 0x68, 0x84, 0x5a, 0x84, 0xaa, 0x81, 0x91, 0xc1, 0x07, 0x9f, 0x3a, 0x85, + 0x2c, 0xc3, 0x26, 0x32, 0xfb, 0x1b, 0x0c, 0x49, 0x97, 0xc0, 0xc2, 0xdb, 0xbe, 0x87, 0xb7, 0xb9, + 0x26, 0x37, 0xb0, 0x8d, 0xa9, 0x41, 0x15, 0x7c, 0x70, 0x88, 0xa9, 0x07, 0xcf, 0x80, 0xe9, 0x40, + 0x1d, 0x43, 0x9f, 0x17, 0x96, 0x84, 0xe5, 0x19, 0xe5, 0x39, 0xf6, 0xdd, 0xd0, 0xa5, 0xc7, 0x60, + 0x31, 0x7b, 0x25, 0x75, 0x88, 0x4d, 0x31, 0xfc, 0x26, 0x38, 0xd6, 0x0c, 0x86, 0x54, 0xea, 0x21, + 0x0f, 0xb3, 0xf5, 0xb3, 0xeb, 0xab, 0xd5, 0x5e, 0x87, 0xd8, 0x5a, 0xab, 0x76, 0x60, 0xdd, 0xf1, + 0xd7, 0xd5, 0x26, 0x3e, 0x79, 0x52, 0x19, 0x53, 0x9e, 0x6f, 0x26, 0xc6, 0xa4, 0x45, 0x20, 0xa6, + 0x36, 0xdf, 0xf6, 0xe1, 0x42, 0xad, 0x25, 0xd4, 0x61, 0x54, 0x38, 0xcb, 0x35, 0xab, 0x81, 0x29, + 0xb6, 0x3d, 0x9d, 0x17, 0x96, 0xc6, 0x97, 0x67, 0xd7, 0x57, 0xaa, 0x39, 0xe2, 0xaa, 0xca, 0x40, + 0x14, 0xbe, 0x52, 0x3a, 0x0b, 0xbe, 0xd4, 0xbd, 0xc5, 0x1d, 0x0f, 0xb9, 0xde, 0x8e, 0x4b, 0x1c, + 0x42, 0x91, 0x19, 0x69, 0xf3, 0x81, 0x00, 0x96, 0x07, 0xcb, 0x72, 0xdd, 0xbe, 0x05, 0x66, 0x9c, + 0x70, 0x90, 0x7b, 0xec, 0xf5, 0x7c, 0xea, 0x71, 0xf0, 0x2d, 0x5d, 0x37, 0xfc, 0x80, 0x8f, 0xa1, + 0x63, 0x40, 0x69, 0x19, 0x7c, 0x31, 0x4b, 0x13, 0xe2, 0x74, 0x29, 0xfd, 0x3d, 0x21, 0xdb, 0xc0, + 0x94, 0x68, 0x74, 0xd2, 0x5d, 0x3a, 0x6f, 0x14, 0xd2, 0x59, 0xc1, 0x16, 0x69, 0x21, 0x33, 0x53, + 0xe5, 0x9f, 0x96, 0xc0, 0x24, 0xdb, 0xbb, 0x4f, 0x2c, 0xc2, 0x05, 0x30, 0xa3, 0x99, 0x06, 0xb6, + 0x3d, 0x7f, 0xae, 0xc4, 0xe6, 0xa6, 0x83, 0x81, 0x86, 0x0e, 0x4f, 0x83, 0x49, 0x8f, 0x38, 0xea, + 0x5b, 0xf3, 0xe3, 0x4b, 0xc2, 0xf2, 0x31, 0x65, 0xc2, 0x23, 0xce, 0x5b, 0x70, 0x05, 0x40, 0xcb, + 0xb0, 0x55, 0x87, 0x3c, 0xc2, 0xae, 0x6a, 0xd8, 0x6a, 0x20, 0x31, 0xb1, 0x24, 0x2c, 0x8f, 0x2b, + 0xc7, 0x2d, 0xc3, 0xde, 0xf1, 0x27, 0x1a, 0xf6, 0xae, 0x2f, 0xbb, 0x0a, 0xe6, 0x5a, 0xc8, 0x34, + 0x74, 0xe4, 0x11, 0x97, 0xf2, 0x25, 0x1a, 0x72, 0xe6, 0x27, 0x19, 0x1e, 0x8c, 0xe7, 0xd8, 0xa2, + 0x6d, 0xe4, 0xc0, 0x15, 0x70, 0x2a, 0x1a, 0x55, 0x29, 0xf6, 0x98, 0xf8, 0x14, 0x13, 0x3f, 0x11, + 0x4d, 0xdc, 0xc1, 0x9e, 0x2f, 0xbb, 0x08, 0x66, 0x90, 0x69, 0x92, 0x47, 0xa6, 0x41, 0xbd, 0xf9, + 0xe7, 0x96, 0xc6, 0x97, 0x67, 0x94, 0x78, 0x00, 0x8a, 0x60, 0x5a, 0xc7, 0x76, 0x9b, 0x4d, 0x4e, + 0xb3, 0xc9, 0xe8, 0x5b, 0xfa, 0xbe, 0x00, 0x5e, 0x66, 0x67, 0xb4, 0x17, 0x42, 0x26, 0x82, 0xc0, + 0x1d, 0x9c, 0xc2, 0x70, 0x03, 0x9c, 0x0c, 0x8f, 0x43, 0x45, 0xba, 0xee, 0x62, 0x4a, 0x03, 0xef, + 0xd5, 0xe0, 0xe7, 0x4f, 0x2a, 0xc7, 0xdb, 0xc8, 0x32, 0x2f, 0x4b, 0x7c, 0x42, 0x52, 0x4e, 0x84, + 0xb2, 0x5b, 0xc1, 0xc8, 0xe5, 0xe9, 0x0f, 0x3e, 0xaa, 0x8c, 0xfd, 0xed, 0xa3, 0xca, 0x98, 0x74, + 0x1b, 0x48, 0xfd, 0x14, 0xe1, 0x71, 0x72, 0x16, 0x9c, 0x0c, 0x0b, 0x5e, 0xb4, 0x5d, 0xa0, 0xd1, + 0x09, 0x2d, 0x21, 0xef, 0x6f, 0xd6, 0x6d, 0xda, 0x4e, 0x62, 0xf3, 0x7c, 0xa6, 0x75, 0xed, 0xd5, + 0xc7, 0xb4, 0x8e, 0xfd, 0xfb, 0x99, 0x96, 0x56, 0x24, 0x36, 0xad, 0xcb, 0x93, 0xdc, 0xb4, 0x0e, + 0xaf, 0x49, 0x0b, 0xe0, 0x0c, 0x03, 0xdc, 0xdd, 0x77, 0x89, 0xe7, 0x99, 0x98, 0x15, 0xb4, 0x30, + 0xed, 0x7e, 0x27, 0xf0, 0xc2, 0xd6, 0x31, 0xcb, 0xb7, 0xa9, 0x80, 0x59, 0x6a, 0x22, 0xba, 0xaf, + 0x5a, 0xd8, 0xc3, 0x2e, 0xdb, 0x61, 0x5c, 0x01, 0x6c, 0xe8, 0x4d, 0x7f, 0x04, 0xae, 0x83, 0xff, + 0x4b, 0x08, 0xa8, 0x2c, 0x8e, 0x90, 0xad, 0x61, 0x66, 0xfb, 0xb8, 0x72, 0x3a, 0x16, 0xdd, 0x0a, + 0xa7, 0xe0, 0xb7, 0xc1, 0xbc, 0x8d, 0xdf, 0xf5, 0x54, 0x17, 0x3b, 0x26, 0xb6, 0x0d, 0xba, 0xaf, + 0x6a, 0xc8, 0xd6, 0x7d, 0x63, 0x31, 0x4b, 0x99, 0xd9, 0x75, 0xb1, 0x1a, 0xdc, 0x8f, 0xd5, 0xf0, + 0x7e, 0xac, 0xee, 0x86, 0xf7, 0x63, 0x6d, 0xda, 0xaf, 0xce, 0x1f, 0xfe, 0xa9, 0x22, 0x28, 0x2f, + 0xf8, 0x28, 0x4a, 0x08, 0xb2, 0x1d, 0x62, 0x48, 0xe7, 0xc1, 0x0a, 0x33, 0x49, 0xc1, 0x4d, 0x83, + 0x7a, 0xd8, 0xc5, 0x7a, 0x9c, 0xf7, 0x8f, 0x90, 0xab, 0xd7, 0xb1, 0x4d, 0xac, 0xa8, 0xf0, 0x5c, + 0x03, 0xe7, 0x72, 0x49, 0x73, 0x8f, 0xbc, 0x00, 0xa6, 0x74, 0x36, 0xc2, 0x6a, 0xf9, 0x8c, 0xc2, + 0xbf, 0xa4, 0x32, 0xbf, 0x9d, 0x82, 0x9a, 0x82, 0x75, 0x56, 0x42, 0x1a, 0xf5, 0x68, 0x9b, 0xf7, + 0x05, 0xf0, 0x52, 0x0f, 0x01, 0x8e, 0x7c, 0x1f, 0x1c, 0x77, 0x92, 0x73, 0xe1, 0x6d, 0xb1, 0x9e, + 0xab, 0xb4, 0xa5, 0x60, 0xf9, 0x15, 0xd6, 0x81, 0x27, 0x35, 0xc0, 0xb1, 0x94, 0x18, 0x9c, 0x07, + 0x3c, 0x7e, 0xeb, 0xe9, 0x70, 0xae, 0xc3, 0x32, 0x00, 0x61, 0x49, 0x6c, 0xd4, 0xd9, 0x61, 0x4e, + 0x28, 0x89, 0x11, 0xe9, 0x16, 0x90, 0x99, 0x35, 0x5b, 0xa6, 0xb9, 0x83, 0x0c, 0x97, 0xee, 0x21, + 0x73, 0x9b, 0xd8, 0x7e, 0xc8, 0xd5, 0xd2, 0x15, 0xbc, 0x51, 0xcf, 0x71, 0xb5, 0xff, 0x4c, 0x00, + 0xab, 0xf9, 0xe1, 0xb8, 0xbf, 0x0e, 0xc0, 0x29, 0x07, 0x19, 0xae, 0xda, 0x42, 0xa6, 0xdf, 0xd7, + 0xb0, 0x34, 0xe0, 0x2e, 0xbb, 0x9e, 0xcf, 0x65, 0xc8, 0x70, 0xe3, 0x8d, 0xa2, 0x34, 0xb3, 0xe3, + 0x00, 0x38, 0xee, 0xa4, 0x44, 0xa4, 0x7f, 0x09, 0xe0, 0xe5, 0x81, 0xab, 0xe0, 0xf5, 0x5e, 0xb9, + 0x59, 0x5b, 0xf8, 0xfc, 0x49, 0xe5, 0xc5, 0xa0, 0x14, 0x74, 0x4a, 0x74, 0x97, 0x3b, 0x1f, 0xa7, + 0x47, 0x49, 0x49, 0xe0, 0x74, 0x4a, 0x74, 0xd7, 0x16, 0xb8, 0x09, 0x9e, 0x8f, 0xa4, 0x1e, 0xe2, + 0x36, 0xcf, 0xb1, 0xc5, 0x6a, 0xdc, 0xd5, 0x55, 0x83, 0xae, 0xae, 0xba, 0x73, 0xf8, 0xc0, 0x34, + 0xb4, 0x9b, 0xb8, 0xad, 0xcc, 0x86, 0x2b, 0x6e, 0xe2, 0xb6, 0x34, 0x07, 0x60, 0x10, 0xba, 0xc8, + 0x45, 0x71, 0xe2, 0xdc, 0x07, 0xa7, 0x53, 0xa3, 0xfc, 0x58, 0x1a, 0x60, 0xca, 0x61, 0x23, 0xfc, + 0x66, 0x3e, 0x97, 0xf3, 0x2c, 0xfc, 0x25, 0x3c, 0x6e, 0x39, 0x80, 0x74, 0x83, 0x27, 0x72, 0x2a, + 0x02, 0x6e, 0x3b, 0x1e, 0xd6, 0x1b, 0x76, 0x54, 0x1e, 0xf3, 0xb4, 0x8e, 0x07, 0x3c, 0xc7, 0x07, + 0x01, 0x45, 0xfd, 0xda, 0x4b, 0xc9, 0xfb, 0xb7, 0xe3, 0xa4, 0x70, 0x98, 0xfa, 0x0b, 0x89, 0x8b, + 0x38, 0x7d, 0x74, 0x98, 0x4a, 0x57, 0x40, 0x39, 0xb5, 0x65, 0x21, 0x7d, 0x3f, 0x16, 0xc0, 0x52, + 0x8f, 0xd5, 0xd1, 0xaf, 0xcc, 0xcb, 0x54, 0xc8, 0x7d, 0x99, 0x76, 0x45, 0x45, 0xa9, 0x60, 0x54, + 0xc0, 0x39, 0x30, 0xc9, 0x5a, 0x13, 0x16, 0x4f, 0xe3, 0x4a, 0xf0, 0xe1, 0x37, 0x9f, 0x95, 0x9e, + 0x86, 0x73, 0xff, 0x62, 0x00, 0x62, 0xd7, 0xf1, 0x94, 0xbd, 0x96, 0x2b, 0x4c, 0x06, 0x39, 0x45, + 0x49, 0x00, 0x4b, 0x07, 0xbc, 0xa8, 0xa4, 0xbb, 0xf2, 0x48, 0xf6, 0x0d, 0x44, 0x77, 0x09, 0xff, + 0x0a, 0xef, 0xc3, 0x11, 0x9d, 0x2a, 0x21, 0xb0, 0x56, 0x60, 0x4b, 0xee, 0x8e, 0xf3, 0x00, 0x46, + 0x27, 0x11, 0x46, 0x44, 0x18, 0x63, 0x51, 0x05, 0x08, 0xaa, 0x9f, 0xce, 0x3a, 0x95, 0x73, 0xd9, + 0xbd, 0xcf, 0x36, 0xb1, 0x2c, 0x83, 0x52, 0x83, 0xd8, 0x4a, 0xc2, 0xa2, 0xff, 0x59, 0x3b, 0x26, + 0x7d, 0x07, 0x9c, 0xcf, 0xa7, 0x08, 0xb7, 0xf3, 0x6b, 0x60, 0xc2, 0x0d, 0x79, 0xd9, 0x4c, 0xed, + 0xcb, 0x7e, 0xaa, 0xff, 0xf1, 0x49, 0x65, 0x21, 0x60, 0x8c, 0x54, 0x7f, 0x58, 0x35, 0x88, 0x6c, + 0x21, 0x6f, 0xbf, 0x7a, 0x0b, 0x37, 0x91, 0xd6, 0xae, 0x63, 0xed, 0xf7, 0xbf, 0x7e, 0x15, 0x70, + 0x42, 0x59, 0xc7, 0xda, 0xcf, 0xff, 0xfa, 0xcb, 0x15, 0x41, 0x61, 0x18, 0xd2, 0x06, 0x4f, 0x90, + 0xdb, 0xa6, 0x8e, 0xa9, 0x77, 0xd7, 0xd6, 0x88, 0xfd, 0x8e, 0xe1, 0x5a, 0x58, 0xdf, 0xa3, 0x5a, + 0x8e, 0x04, 0xfb, 0x41, 0xd8, 0xee, 0x65, 0xaf, 0xe7, 0x0a, 0x1b, 0x00, 0xb6, 0xa8, 0xa6, 0x52, + 0x6c, 0xeb, 0x6a, 0x44, 0xd0, 0x79, 0x59, 0xbb, 0x98, 0x2b, 0x5e, 0xf7, 0xa8, 0x76, 0x07, 0xdb, + 0x7a, 0xdc, 0xbd, 0x04, 0x05, 0xee, 0x64, 0xab, 0x63, 0x7c, 0xfd, 0xe3, 0x0a, 0x98, 0x64, 0x0a, + 0xc1, 0xa7, 0x02, 0x98, 0xcb, 0xe2, 0xb9, 0xf0, 0x6a, 0xf1, 0x0c, 0x49, 0x93, 0x6b, 0x71, 0x6b, + 0x04, 0x84, 0xc0, 0x25, 0xd2, 0xb5, 0xef, 0x7e, 0xf6, 0x97, 0x1f, 0x95, 0x36, 0xe1, 0xc6, 0xe0, + 0xb7, 0x94, 0x28, 0xa6, 0x39, 0x91, 0x96, 0x1f, 0x87, 0xa7, 0xf1, 0x1e, 0xfc, 0x4c, 0xe0, 0x97, + 0x47, 0x3a, 0x51, 0xe0, 0x66, 0x71, 0x0d, 0x53, 0x4c, 0x5c, 0xbc, 0x3a, 0x3c, 0x00, 0xb7, 0xf0, + 0x35, 0x66, 0xe1, 0x05, 0xb8, 0x56, 0xc0, 0xc2, 0x80, 0xa3, 0xc3, 0xf7, 0x4b, 0x60, 0xbe, 0x07, + 0xf1, 0xa6, 0xf0, 0xd6, 0x90, 0x9a, 0x65, 0x72, 0x7c, 0xf1, 0xcd, 0x23, 0x42, 0xe3, 0x46, 0xbf, + 0xc1, 0x8c, 0xae, 0xc1, 0xab, 0x45, 0x8d, 0x56, 0xa9, 0x0f, 0xa8, 0x46, 0xf4, 0x19, 0xfe, 0x47, + 0x00, 0x2f, 0x66, 0xf3, 0x78, 0x0a, 0x6f, 0x0e, 0xad, 0x74, 0xf7, 0x83, 0x81, 0x78, 0xeb, 0x68, + 0xc0, 0xb8, 0x03, 0x6e, 0x30, 0x07, 0x6c, 0xc1, 0xcd, 0x21, 0x1c, 0x40, 0x9c, 0x84, 0xfd, 0xff, + 0x0c, 0x09, 0x55, 0x26, 0x35, 0x85, 0xd7, 0xf3, 0x6b, 0xdd, 0x8f, 0x64, 0x8b, 0x37, 0x46, 0xc6, + 0xe1, 0x86, 0x6f, 0x31, 0xc3, 0xaf, 0xc0, 0xd7, 0x72, 0x3c, 0x8e, 0x46, 0x2f, 0x0c, 0xa9, 0xa6, + 0x33, 0xc3, 0xe4, 0x64, 0x3b, 0x34, 0x94, 0xc9, 0x19, 0xe4, 0x7b, 0x28, 0x93, 0xb3, 0xb8, 0xf3, + 0x70, 0x26, 0xa7, 0x2e, 0x4a, 0xf8, 0x5b, 0x81, 0xb7, 0xc4, 0x29, 0xda, 0x0c, 0x5f, 0xcf, 0xaf, + 0x62, 0x16, 0x1b, 0x17, 0x37, 0x87, 0x5e, 0xcf, 0x4d, 0xbb, 0xc4, 0x4c, 0x5b, 0x87, 0xab, 0x83, + 0x4d, 0xf3, 0x38, 0x40, 0xf0, 0x58, 0x0a, 0x7f, 0x52, 0x02, 0xaf, 0xe4, 0xe0, 0xc1, 0xf0, 0x76, + 0x7e, 0x15, 0x73, 0xf1, 0x6f, 0x71, 0xe7, 0xe8, 0x00, 0xb9, 0x13, 0x6e, 0x32, 0x27, 0x5c, 0x83, + 0xdb, 0x83, 0x9d, 0xe0, 0x46, 0x88, 0x71, 0x4c, 0xbb, 0x0c, 0x53, 0x0d, 0x78, 0x3d, 0xfc, 0x7b, + 0x17, 0x6f, 0x4f, 0xd3, 0x51, 0x0a, 0x0b, 0xdc, 0xaa, 0x3d, 0x1e, 0x07, 0xc4, 0xda, 0x28, 0x10, + 0xdc, 0xea, 0x1a, 0xb3, 0xfa, 0xab, 0xf0, 0xf2, 0x60, 0xab, 0xc3, 0x67, 0x01, 0xb5, 0xf3, 0x02, + 0xfb, 0x71, 0x89, 0xbf, 0x1c, 0xe7, 0xe0, 0xe1, 0x70, 0x37, 0xbf, 0xd2, 0xf9, 0x5f, 0x09, 0xc4, + 0xbb, 0x47, 0x8c, 0xca, 0xbd, 0x73, 0x85, 0x79, 0xe7, 0x22, 0xbc, 0x50, 0xb8, 0xbe, 0x1b, 0x3a, + 0xfc, 0x95, 0x00, 0x66, 0x13, 0x54, 0x17, 0x7e, 0xa5, 0xc0, 0x71, 0x25, 0x29, 0xb3, 0x78, 0xa9, + 0xf8, 0x42, 0xae, 0xff, 0x2a, 0xd3, 0x7f, 0x05, 0x2e, 0xe7, 0x38, 0xdd, 0x40, 0xc9, 0x1f, 0x86, + 0x09, 0xdd, 0x9f, 0xf4, 0x16, 0x49, 0xe8, 0x5c, 0x3c, 0xbc, 0x48, 0x42, 0xe7, 0xe3, 0xe3, 0x45, + 0xba, 0x13, 0xe2, 0x83, 0xa8, 0x86, 0xad, 0xc6, 0x3c, 0x30, 0xd9, 0x77, 0xfe, 0xa6, 0x04, 0xce, + 0xe6, 0x26, 0x68, 0xf0, 0xee, 0xb0, 0xcd, 0x64, 0x5f, 0x8e, 0x29, 0xee, 0x1d, 0x35, 0x2c, 0x77, + 0xd3, 0x3d, 0xe6, 0xa6, 0x5d, 0xa8, 0x14, 0xee, 0x5c, 0x55, 0x07, 0xbb, 0xb1, 0xc7, 0xe4, 0xc7, + 0x9d, 0xac, 0xf0, 0x3d, 0xf8, 0x8b, 0x12, 0xf8, 0xff, 0x3c, 0x64, 0x0f, 0xee, 0x8c, 0xd0, 0x98, + 0x64, 0x12, 0x58, 0xf1, 0xed, 0x23, 0x44, 0xe4, 0x9e, 0xba, 0xcf, 0x3c, 0x75, 0x0f, 0x7e, 0xa3, + 0x88, 0xa7, 0x22, 0x28, 0xd5, 0x67, 0xa0, 0x89, 0xa8, 0xca, 0xf2, 0xd7, 0xbf, 0x05, 0xfe, 0xea, + 0x9e, 0x45, 0x30, 0x61, 0x81, 0xc7, 0x8e, 0x3e, 0x04, 0x57, 0xbc, 0x3e, 0x2a, 0x4c, 0xf1, 0x0b, + 0x93, 0x30, 0x1c, 0xf5, 0x30, 0x06, 0x52, 0x5b, 0x54, 0x4b, 0xa6, 0xd8, 0x3f, 0x3a, 0x09, 0x40, + 0xa2, 0xd6, 0x6c, 0x8f, 0xf2, 0xc8, 0x13, 0x5a, 0x5d, 0x1f, 0x0d, 0x64, 0x04, 0xc6, 0x93, 0x59, + 0x53, 0x6a, 0x5f, 0xff, 0xe4, 0x69, 0x59, 0xf8, 0xf4, 0x69, 0x59, 0xf8, 0xf3, 0xd3, 0xb2, 0xf0, + 0xe1, 0xb3, 0xf2, 0xd8, 0xa7, 0xcf, 0xca, 0x63, 0x7f, 0x78, 0x56, 0x1e, 0xbb, 0xb7, 0xd1, 0x34, + 0xbc, 0xfd, 0xc3, 0x07, 0x55, 0x8d, 0x58, 0xfc, 0xff, 0xe2, 0x89, 0xcd, 0x5e, 0x8d, 0x36, 0x6b, + 0x5d, 0x94, 0xdf, 0xed, 0xe8, 0xcd, 0xda, 0x0e, 0xa6, 0x0f, 0xa6, 0xd8, 0x7f, 0x3f, 0x2e, 0xfc, + 0x37, 0x00, 0x00, 0xff, 0xff, 0xf5, 0x73, 0x8b, 0xa7, 0xb7, 0x20, 0x00, 0x00, } -func (m *QueryConsumerChainStartProposalsResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + // ConsumerGenesis queries the genesis state needed to start a consumer chain + // whose proposal has been accepted + QueryConsumerGenesis(ctx context.Context, in *QueryConsumerGenesisRequest, opts ...grpc.CallOption) (*QueryConsumerGenesisResponse, error) + // ConsumerChains queries active consumer chains supported by the provider + // chain + QueryConsumerChains(ctx context.Context, in *QueryConsumerChainsRequest, opts ...grpc.CallOption) (*QueryConsumerChainsResponse, error) + // QueryConsumerChainStarts queries consumer chain start proposals. + QueryConsumerChainStarts(ctx context.Context, in *QueryConsumerChainStartProposalsRequest, opts ...grpc.CallOption) (*QueryConsumerChainStartProposalsResponse, error) + // QueryConsumerChainStops queries consumer chain stop proposals. + QueryConsumerChainStops(ctx context.Context, in *QueryConsumerChainStopProposalsRequest, opts ...grpc.CallOption) (*QueryConsumerChainStopProposalsResponse, error) + // QueryValidatorConsumerAddr queries the address + // assigned by a validator for a consumer chain. + QueryValidatorConsumerAddr(ctx context.Context, in *QueryValidatorConsumerAddrRequest, opts ...grpc.CallOption) (*QueryValidatorConsumerAddrResponse, error) + // QueryProviderAddr returns the provider chain validator + // given a consumer chain validator address + QueryValidatorProviderAddr(ctx context.Context, in *QueryValidatorProviderAddrRequest, opts ...grpc.CallOption) (*QueryValidatorProviderAddrResponse, error) + // QueryThrottleState returns the main on-chain state relevant to currently + // throttled slash packets + QueryThrottleState(ctx context.Context, in *QueryThrottleStateRequest, opts ...grpc.CallOption) (*QueryThrottleStateResponse, error) + // QueryRegisteredConsumerRewardDenoms returns a list of consumer reward + // denoms that are registered + QueryRegisteredConsumerRewardDenoms(ctx context.Context, in *QueryRegisteredConsumerRewardDenomsRequest, opts ...grpc.CallOption) (*QueryRegisteredConsumerRewardDenomsResponse, error) + // QueryProposedConsumerChainIDs returns the chain IDs of the proposed consumer chain addition proposals + // that are still in the voting period + QueryProposedConsumerChainIDs(ctx context.Context, in *QueryProposedChainIDsRequest, opts ...grpc.CallOption) (*QueryProposedChainIDsResponse, error) + // QueryAllPairsValConAddrByConsumerChainID returns a list of pair valconsensus address + // between provider and consumer chain + QueryAllPairsValConAddrByConsumerChainID(ctx context.Context, in *QueryAllPairsValConAddrByConsumerChainIDRequest, opts ...grpc.CallOption) (*QueryAllPairsValConAddrByConsumerChainIDResponse, error) + // QueryParams returns all current values of provider parameters + QueryParams(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // QueryConsumerChainOptedInValidators returns a list of validators consensus addresses + // that opted-in to the given consumer chain + QueryConsumerChainOptedInValidators(ctx context.Context, in *QueryConsumerChainOptedInValidatorsRequest, opts ...grpc.CallOption) (*QueryConsumerChainOptedInValidatorsResponse, error) + // QueryConsumerChainsValidatorHasToValidate returns a list of consumer chains + // that a given validator must validate + QueryConsumerChainsValidatorHasToValidate(ctx context.Context, in *QueryConsumerChainsValidatorHasToValidateRequest, opts ...grpc.CallOption) (*QueryConsumerChainsValidatorHasToValidateResponse, error) + // QueryValidatorConsumerCommissionRate returns the commission rate a given + // validator charges on a given consumer chain + QueryValidatorConsumerCommissionRate(ctx context.Context, in *QueryValidatorConsumerCommissionRateRequest, opts ...grpc.CallOption) (*QueryValidatorConsumerCommissionRateResponse, error) + // QueryOldestUnconfirmedVsc returns the send timestamp of the oldest unconfirmed VSCPacket for a given chainID + QueryOldestUnconfirmedVsc(ctx context.Context, in *QueryOldestUnconfirmedVscRequest, opts ...grpc.CallOption) (*QueryOldestUnconfirmedVscResponse, error) + // QueryConsumerValidators returns the latest set consumer-validator set for a given chainID + // Note that this does not necessarily mean that the consumer chain is using this validator set at this exact moment + // because a VSCPacket could be delayed to be delivered on the consumer chain. + QueryConsumerValidators(ctx context.Context, in *QueryConsumerValidatorsRequest, opts ...grpc.CallOption) (*QueryConsumerValidatorsResponse, error) } -func (m *QueryConsumerChainStartProposalsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Proposals != nil { - { - size, err := m.Proposals.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil +type queryClient struct { + cc grpc1.ClientConn } -func (m *QueryConsumerChainStopProposalsRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) QueryConsumerGenesis(ctx context.Context, in *QueryConsumerGenesisRequest, opts ...grpc.CallOption) (*QueryConsumerGenesisResponse, error) { + out := new(QueryConsumerGenesisResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryConsumerGenesis", in, out, opts...) if err != nil { return nil, err } - return dAtA[:n], nil + return out, nil } -func (m *QueryConsumerChainStopProposalsRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (c *queryClient) QueryConsumerChains(ctx context.Context, in *QueryConsumerChainsRequest, opts ...grpc.CallOption) (*QueryConsumerChainsResponse, error) { + out := new(QueryConsumerChainsResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryConsumerChains", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil } -func (m *QueryConsumerChainStopProposalsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil +func (c *queryClient) QueryConsumerChainStarts(ctx context.Context, in *QueryConsumerChainStartProposalsRequest, opts ...grpc.CallOption) (*QueryConsumerChainStartProposalsResponse, error) { + out := new(QueryConsumerChainStartProposalsResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryConsumerChainStarts", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil } -func (m *QueryConsumerChainStopProposalsResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) +func (c *queryClient) QueryConsumerChainStops(ctx context.Context, in *QueryConsumerChainStopProposalsRequest, opts ...grpc.CallOption) (*QueryConsumerChainStopProposalsResponse, error) { + out := new(QueryConsumerChainStopProposalsResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryConsumerChainStops", in, out, opts...) if err != nil { return nil, err } - return dAtA[:n], nil + return out, nil } -func (m *QueryConsumerChainStopProposalsResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (c *queryClient) QueryValidatorConsumerAddr(ctx context.Context, in *QueryValidatorConsumerAddrRequest, opts ...grpc.CallOption) (*QueryValidatorConsumerAddrResponse, error) { + out := new(QueryValidatorConsumerAddrResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryValidatorConsumerAddr", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil } -func (m *QueryConsumerChainStopProposalsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Proposals != nil { - { - size, err := m.Proposals.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *Chain) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) +func (c *queryClient) QueryValidatorProviderAddr(ctx context.Context, in *QueryValidatorProviderAddrRequest, opts ...grpc.CallOption) (*QueryValidatorProviderAddrResponse, error) { + out := new(QueryValidatorProviderAddrResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryValidatorProviderAddr", in, out, opts...) if err != nil { return nil, err } - return dAtA[:n], nil -} - -func (m *Chain) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) + return out, nil } -func (m *Chain) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.ClientId) > 0 { - i -= len(m.ClientId) - copy(dAtA[i:], m.ClientId) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ClientId))) - i-- - dAtA[i] = 0x12 - } - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) - i-- - dAtA[i] = 0xa +func (c *queryClient) QueryThrottleState(ctx context.Context, in *QueryThrottleStateRequest, opts ...grpc.CallOption) (*QueryThrottleStateResponse, error) { + out := new(QueryThrottleStateResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryThrottleState", in, out, opts...) + if err != nil { + return nil, err } - return len(dAtA) - i, nil + return out, nil } -func (m *QueryValidatorConsumerAddrRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) +func (c *queryClient) QueryRegisteredConsumerRewardDenoms(ctx context.Context, in *QueryRegisteredConsumerRewardDenomsRequest, opts ...grpc.CallOption) (*QueryRegisteredConsumerRewardDenomsResponse, error) { + out := new(QueryRegisteredConsumerRewardDenomsResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryRegisteredConsumerRewardDenoms", in, out, opts...) if err != nil { return nil, err } - return dAtA[:n], nil -} - -func (m *QueryValidatorConsumerAddrRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) + return out, nil } -func (m *QueryValidatorConsumerAddrRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.ProviderAddress) > 0 { - i -= len(m.ProviderAddress) - copy(dAtA[i:], m.ProviderAddress) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ProviderAddress))) - i-- - dAtA[i] = 0x12 - } - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) - i-- - dAtA[i] = 0xa +func (c *queryClient) QueryProposedConsumerChainIDs(ctx context.Context, in *QueryProposedChainIDsRequest, opts ...grpc.CallOption) (*QueryProposedChainIDsResponse, error) { + out := new(QueryProposedChainIDsResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryProposedConsumerChainIDs", in, out, opts...) + if err != nil { + return nil, err } - return len(dAtA) - i, nil + return out, nil } -func (m *QueryValidatorConsumerAddrResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) +func (c *queryClient) QueryAllPairsValConAddrByConsumerChainID(ctx context.Context, in *QueryAllPairsValConAddrByConsumerChainIDRequest, opts ...grpc.CallOption) (*QueryAllPairsValConAddrByConsumerChainIDResponse, error) { + out := new(QueryAllPairsValConAddrByConsumerChainIDResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryAllPairsValConAddrByConsumerChainID", in, out, opts...) if err != nil { return nil, err } - return dAtA[:n], nil -} - -func (m *QueryValidatorConsumerAddrResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) + return out, nil } -func (m *QueryValidatorConsumerAddrResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.ConsumerAddress) > 0 { - i -= len(m.ConsumerAddress) - copy(dAtA[i:], m.ConsumerAddress) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ConsumerAddress))) - i-- - dAtA[i] = 0xa +func (c *queryClient) QueryParams(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryParams", in, out, opts...) + if err != nil { + return nil, err } - return len(dAtA) - i, nil + return out, nil } -func (m *QueryValidatorProviderAddrRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) +func (c *queryClient) QueryConsumerChainOptedInValidators(ctx context.Context, in *QueryConsumerChainOptedInValidatorsRequest, opts ...grpc.CallOption) (*QueryConsumerChainOptedInValidatorsResponse, error) { + out := new(QueryConsumerChainOptedInValidatorsResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryConsumerChainOptedInValidators", in, out, opts...) if err != nil { return nil, err } - return dAtA[:n], nil -} - -func (m *QueryValidatorProviderAddrRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) + return out, nil } -func (m *QueryValidatorProviderAddrRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.ConsumerAddress) > 0 { - i -= len(m.ConsumerAddress) - copy(dAtA[i:], m.ConsumerAddress) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ConsumerAddress))) - i-- - dAtA[i] = 0x12 - } - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) - i-- - dAtA[i] = 0xa +func (c *queryClient) QueryConsumerChainsValidatorHasToValidate(ctx context.Context, in *QueryConsumerChainsValidatorHasToValidateRequest, opts ...grpc.CallOption) (*QueryConsumerChainsValidatorHasToValidateResponse, error) { + out := new(QueryConsumerChainsValidatorHasToValidateResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryConsumerChainsValidatorHasToValidate", in, out, opts...) + if err != nil { + return nil, err } - return len(dAtA) - i, nil + return out, nil } -func (m *QueryValidatorProviderAddrResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) +func (c *queryClient) QueryValidatorConsumerCommissionRate(ctx context.Context, in *QueryValidatorConsumerCommissionRateRequest, opts ...grpc.CallOption) (*QueryValidatorConsumerCommissionRateResponse, error) { + out := new(QueryValidatorConsumerCommissionRateResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryValidatorConsumerCommissionRate", in, out, opts...) if err != nil { return nil, err } - return dAtA[:n], nil -} - -func (m *QueryValidatorProviderAddrResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) + return out, nil } -func (m *QueryValidatorProviderAddrResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.ProviderAddress) > 0 { - i -= len(m.ProviderAddress) - copy(dAtA[i:], m.ProviderAddress) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ProviderAddress))) - i-- - dAtA[i] = 0xa +func (c *queryClient) QueryOldestUnconfirmedVsc(ctx context.Context, in *QueryOldestUnconfirmedVscRequest, opts ...grpc.CallOption) (*QueryOldestUnconfirmedVscResponse, error) { + out := new(QueryOldestUnconfirmedVscResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryOldestUnconfirmedVsc", in, out, opts...) + if err != nil { + return nil, err } - return len(dAtA) - i, nil + return out, nil } -func (m *QueryThrottleStateRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) +func (c *queryClient) QueryConsumerValidators(ctx context.Context, in *QueryConsumerValidatorsRequest, opts ...grpc.CallOption) (*QueryConsumerValidatorsResponse, error) { + out := new(QueryConsumerValidatorsResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryConsumerValidators", in, out, opts...) if err != nil { return nil, err } - return dAtA[:n], nil + return out, nil } -func (m *QueryThrottleStateRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +// QueryServer is the server API for Query service. +type QueryServer interface { + // ConsumerGenesis queries the genesis state needed to start a consumer chain + // whose proposal has been accepted + QueryConsumerGenesis(context.Context, *QueryConsumerGenesisRequest) (*QueryConsumerGenesisResponse, error) + // ConsumerChains queries active consumer chains supported by the provider + // chain + QueryConsumerChains(context.Context, *QueryConsumerChainsRequest) (*QueryConsumerChainsResponse, error) + // QueryConsumerChainStarts queries consumer chain start proposals. + QueryConsumerChainStarts(context.Context, *QueryConsumerChainStartProposalsRequest) (*QueryConsumerChainStartProposalsResponse, error) + // QueryConsumerChainStops queries consumer chain stop proposals. + QueryConsumerChainStops(context.Context, *QueryConsumerChainStopProposalsRequest) (*QueryConsumerChainStopProposalsResponse, error) + // QueryValidatorConsumerAddr queries the address + // assigned by a validator for a consumer chain. + QueryValidatorConsumerAddr(context.Context, *QueryValidatorConsumerAddrRequest) (*QueryValidatorConsumerAddrResponse, error) + // QueryProviderAddr returns the provider chain validator + // given a consumer chain validator address + QueryValidatorProviderAddr(context.Context, *QueryValidatorProviderAddrRequest) (*QueryValidatorProviderAddrResponse, error) + // QueryThrottleState returns the main on-chain state relevant to currently + // throttled slash packets + QueryThrottleState(context.Context, *QueryThrottleStateRequest) (*QueryThrottleStateResponse, error) + // QueryRegisteredConsumerRewardDenoms returns a list of consumer reward + // denoms that are registered + QueryRegisteredConsumerRewardDenoms(context.Context, *QueryRegisteredConsumerRewardDenomsRequest) (*QueryRegisteredConsumerRewardDenomsResponse, error) + // QueryProposedConsumerChainIDs returns the chain IDs of the proposed consumer chain addition proposals + // that are still in the voting period + QueryProposedConsumerChainIDs(context.Context, *QueryProposedChainIDsRequest) (*QueryProposedChainIDsResponse, error) + // QueryAllPairsValConAddrByConsumerChainID returns a list of pair valconsensus address + // between provider and consumer chain + QueryAllPairsValConAddrByConsumerChainID(context.Context, *QueryAllPairsValConAddrByConsumerChainIDRequest) (*QueryAllPairsValConAddrByConsumerChainIDResponse, error) + // QueryParams returns all current values of provider parameters + QueryParams(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // QueryConsumerChainOptedInValidators returns a list of validators consensus addresses + // that opted-in to the given consumer chain + QueryConsumerChainOptedInValidators(context.Context, *QueryConsumerChainOptedInValidatorsRequest) (*QueryConsumerChainOptedInValidatorsResponse, error) + // QueryConsumerChainsValidatorHasToValidate returns a list of consumer chains + // that a given validator must validate + QueryConsumerChainsValidatorHasToValidate(context.Context, *QueryConsumerChainsValidatorHasToValidateRequest) (*QueryConsumerChainsValidatorHasToValidateResponse, error) + // QueryValidatorConsumerCommissionRate returns the commission rate a given + // validator charges on a given consumer chain + QueryValidatorConsumerCommissionRate(context.Context, *QueryValidatorConsumerCommissionRateRequest) (*QueryValidatorConsumerCommissionRateResponse, error) + // QueryOldestUnconfirmedVsc returns the send timestamp of the oldest unconfirmed VSCPacket for a given chainID + QueryOldestUnconfirmedVsc(context.Context, *QueryOldestUnconfirmedVscRequest) (*QueryOldestUnconfirmedVscResponse, error) + // QueryConsumerValidators returns the latest set consumer-validator set for a given chainID + // Note that this does not necessarily mean that the consumer chain is using this validator set at this exact moment + // because a VSCPacket could be delayed to be delivered on the consumer chain. + QueryConsumerValidators(context.Context, *QueryConsumerValidatorsRequest) (*QueryConsumerValidatorsResponse, error) } -func (m *QueryThrottleStateRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { } -func (m *QueryThrottleStateResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil +func (*UnimplementedQueryServer) QueryConsumerGenesis(ctx context.Context, req *QueryConsumerGenesisRequest) (*QueryConsumerGenesisResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryConsumerGenesis not implemented") } - -func (m *QueryThrottleStateResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (*UnimplementedQueryServer) QueryConsumerChains(ctx context.Context, req *QueryConsumerChainsRequest) (*QueryConsumerChainsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryConsumerChains not implemented") } - -func (m *QueryThrottleStateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - n4, err4 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.NextReplenishCandidate, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.NextReplenishCandidate):]) - if err4 != nil { - return 0, err4 - } - i -= n4 - i = encodeVarintQuery(dAtA, i, uint64(n4)) - i-- - dAtA[i] = 0x1a - if m.SlashMeterAllowance != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.SlashMeterAllowance)) - i-- - dAtA[i] = 0x10 - } - if m.SlashMeter != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.SlashMeter)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil +func (*UnimplementedQueryServer) QueryConsumerChainStarts(ctx context.Context, req *QueryConsumerChainStartProposalsRequest) (*QueryConsumerChainStartProposalsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryConsumerChainStarts not implemented") } - -func (m *QueryRegisteredConsumerRewardDenomsRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil +func (*UnimplementedQueryServer) QueryConsumerChainStops(ctx context.Context, req *QueryConsumerChainStopProposalsRequest) (*QueryConsumerChainStopProposalsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryConsumerChainStops not implemented") } - -func (m *QueryRegisteredConsumerRewardDenomsRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (*UnimplementedQueryServer) QueryValidatorConsumerAddr(ctx context.Context, req *QueryValidatorConsumerAddrRequest) (*QueryValidatorConsumerAddrResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryValidatorConsumerAddr not implemented") } - -func (m *QueryRegisteredConsumerRewardDenomsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil +func (*UnimplementedQueryServer) QueryValidatorProviderAddr(ctx context.Context, req *QueryValidatorProviderAddrRequest) (*QueryValidatorProviderAddrResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryValidatorProviderAddr not implemented") } - -func (m *QueryRegisteredConsumerRewardDenomsResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil +func (*UnimplementedQueryServer) QueryThrottleState(ctx context.Context, req *QueryThrottleStateRequest) (*QueryThrottleStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryThrottleState not implemented") } - -func (m *QueryRegisteredConsumerRewardDenomsResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (*UnimplementedQueryServer) QueryRegisteredConsumerRewardDenoms(ctx context.Context, req *QueryRegisteredConsumerRewardDenomsRequest) (*QueryRegisteredConsumerRewardDenomsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryRegisteredConsumerRewardDenoms not implemented") } - -func (m *QueryRegisteredConsumerRewardDenomsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Denoms) > 0 { - for iNdEx := len(m.Denoms) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Denoms[iNdEx]) - copy(dAtA[i:], m.Denoms[iNdEx]) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Denoms[iNdEx]))) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil +func (*UnimplementedQueryServer) QueryProposedConsumerChainIDs(ctx context.Context, req *QueryProposedChainIDsRequest) (*QueryProposedChainIDsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryProposedConsumerChainIDs not implemented") } - -func (m *QueryProposedChainIDsRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil +func (*UnimplementedQueryServer) QueryAllPairsValConAddrByConsumerChainID(ctx context.Context, req *QueryAllPairsValConAddrByConsumerChainIDRequest) (*QueryAllPairsValConAddrByConsumerChainIDResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryAllPairsValConAddrByConsumerChainID not implemented") } - -func (m *QueryProposedChainIDsRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (*UnimplementedQueryServer) QueryParams(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryParams not implemented") } - -func (m *QueryProposedChainIDsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil +func (*UnimplementedQueryServer) QueryConsumerChainOptedInValidators(ctx context.Context, req *QueryConsumerChainOptedInValidatorsRequest) (*QueryConsumerChainOptedInValidatorsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryConsumerChainOptedInValidators not implemented") } - -func (m *QueryProposedChainIDsResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil +func (*UnimplementedQueryServer) QueryConsumerChainsValidatorHasToValidate(ctx context.Context, req *QueryConsumerChainsValidatorHasToValidateRequest) (*QueryConsumerChainsValidatorHasToValidateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryConsumerChainsValidatorHasToValidate not implemented") } - -func (m *QueryProposedChainIDsResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func (*UnimplementedQueryServer) QueryValidatorConsumerCommissionRate(ctx context.Context, req *QueryValidatorConsumerCommissionRateRequest) (*QueryValidatorConsumerCommissionRateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryValidatorConsumerCommissionRate not implemented") +} +func (*UnimplementedQueryServer) QueryOldestUnconfirmedVsc(ctx context.Context, req *QueryOldestUnconfirmedVscRequest) (*QueryOldestUnconfirmedVscResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryOldestUnconfirmedVsc not implemented") +} +func (*UnimplementedQueryServer) QueryConsumerValidators(ctx context.Context, req *QueryConsumerValidatorsRequest) (*QueryConsumerValidatorsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryConsumerValidators not implemented") } -func (m *QueryProposedChainIDsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.ProposedChains) > 0 { - for iNdEx := len(m.ProposedChains) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.ProposedChains[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) } -func (m *ProposedChain) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { +func _Query_QueryConsumerGenesis_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryConsumerGenesisRequest) + if err := dec(in); err != nil { return nil, err } - return dAtA[:n], nil + if interceptor == nil { + return srv.(QueryServer).QueryConsumerGenesis(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryConsumerGenesis", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryConsumerGenesis(ctx, req.(*QueryConsumerGenesisRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *ProposedChain) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func _Query_QueryConsumerChains_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryConsumerChainsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QueryConsumerChains(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryConsumerChains", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryConsumerChains(ctx, req.(*QueryConsumerChainsRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *ProposedChain) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.ProposalID != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.ProposalID)) - i-- - dAtA[i] = 0x10 +func _Query_QueryConsumerChainStarts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryConsumerChainStartProposalsRequest) + if err := dec(in); err != nil { + return nil, err } - if len(m.ChainID) > 0 { - i -= len(m.ChainID) - copy(dAtA[i:], m.ChainID) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainID))) - i-- - dAtA[i] = 0xa + if interceptor == nil { + return srv.(QueryServer).QueryConsumerChainStarts(ctx, in) } - return len(dAtA) - i, nil + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryConsumerChainStarts", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryConsumerChainStarts(ctx, req.(*QueryConsumerChainStartProposalsRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *QueryAllPairsValConAddrByConsumerChainIDRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { +func _Query_QueryConsumerChainStops_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryConsumerChainStopProposalsRequest) + if err := dec(in); err != nil { return nil, err } - return dAtA[:n], nil + if interceptor == nil { + return srv.(QueryServer).QueryConsumerChainStops(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryConsumerChainStops", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryConsumerChainStops(ctx, req.(*QueryConsumerChainStopProposalsRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *QueryAllPairsValConAddrByConsumerChainIDRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func _Query_QueryValidatorConsumerAddr_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryValidatorConsumerAddrRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QueryValidatorConsumerAddr(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryValidatorConsumerAddr", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryValidatorConsumerAddr(ctx, req.(*QueryValidatorConsumerAddrRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *QueryAllPairsValConAddrByConsumerChainIDRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.ChainId) > 0 { - i -= len(m.ChainId) - copy(dAtA[i:], m.ChainId) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) - i-- - dAtA[i] = 0xa +func _Query_QueryValidatorProviderAddr_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryValidatorProviderAddrRequest) + if err := dec(in); err != nil { + return nil, err } - return len(dAtA) - i, nil + if interceptor == nil { + return srv.(QueryServer).QueryValidatorProviderAddr(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryValidatorProviderAddr", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryValidatorProviderAddr(ctx, req.(*QueryValidatorProviderAddrRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *QueryAllPairsValConAddrByConsumerChainIDResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { +func _Query_QueryThrottleState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryThrottleStateRequest) + if err := dec(in); err != nil { return nil, err } - return dAtA[:n], nil -} - -func (m *QueryAllPairsValConAddrByConsumerChainIDResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) + if interceptor == nil { + return srv.(QueryServer).QueryThrottleState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryThrottleState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryThrottleState(ctx, req.(*QueryThrottleStateRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *QueryAllPairsValConAddrByConsumerChainIDResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.PairValConAddr) > 0 { - for iNdEx := len(m.PairValConAddr) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.PairValConAddr[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } +func _Query_QueryRegisteredConsumerRewardDenoms_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryRegisteredConsumerRewardDenomsRequest) + if err := dec(in); err != nil { + return nil, err } - return len(dAtA) - i, nil + if interceptor == nil { + return srv.(QueryServer).QueryRegisteredConsumerRewardDenoms(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryRegisteredConsumerRewardDenoms", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryRegisteredConsumerRewardDenoms(ctx, req.(*QueryRegisteredConsumerRewardDenomsRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *PairValConAddrProviderAndConsumer) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { +func _Query_QueryProposedConsumerChainIDs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryProposedChainIDsRequest) + if err := dec(in); err != nil { return nil, err } - return dAtA[:n], nil + if interceptor == nil { + return srv.(QueryServer).QueryProposedConsumerChainIDs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryProposedConsumerChainIDs", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryProposedConsumerChainIDs(ctx, req.(*QueryProposedChainIDsRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *PairValConAddrProviderAndConsumer) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func _Query_QueryAllPairsValConAddrByConsumerChainID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAllPairsValConAddrByConsumerChainIDRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QueryAllPairsValConAddrByConsumerChainID(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryAllPairsValConAddrByConsumerChainID", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryAllPairsValConAddrByConsumerChainID(ctx, req.(*QueryAllPairsValConAddrByConsumerChainIDRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *PairValConAddrProviderAndConsumer) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.ConsumerKey != nil { - { - size, err := m.ConsumerKey.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a +func _Query_QueryParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err } - if len(m.ConsumerAddress) > 0 { - i -= len(m.ConsumerAddress) - copy(dAtA[i:], m.ConsumerAddress) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ConsumerAddress))) - i-- - dAtA[i] = 0x12 + if interceptor == nil { + return srv.(QueryServer).QueryParams(ctx, in) } - if len(m.ProviderAddress) > 0 { - i -= len(m.ProviderAddress) - copy(dAtA[i:], m.ProviderAddress) - i = encodeVarintQuery(dAtA, i, uint64(len(m.ProviderAddress))) - i-- - dAtA[i] = 0xa + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryParams", } - return len(dAtA) - i, nil + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryParams(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { +func _Query_QueryConsumerChainOptedInValidators_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryConsumerChainOptedInValidatorsRequest) + if err := dec(in); err != nil { return nil, err } - return dAtA[:n], nil + if interceptor == nil { + return srv.(QueryServer).QueryConsumerChainOptedInValidators(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryConsumerChainOptedInValidators", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryConsumerChainOptedInValidators(ctx, req.(*QueryConsumerChainOptedInValidatorsRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func _Query_QueryConsumerChainsValidatorHasToValidate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryConsumerChainsValidatorHasToValidateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QueryConsumerChainsValidatorHasToValidate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryConsumerChainsValidatorHasToValidate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryConsumerChainsValidatorHasToValidate(ctx, req.(*QueryConsumerChainsValidatorHasToValidateRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil +func _Query_QueryValidatorConsumerCommissionRate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryValidatorConsumerCommissionRateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QueryValidatorConsumerCommissionRate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryValidatorConsumerCommissionRate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryValidatorConsumerCommissionRate(ctx, req.(*QueryValidatorConsumerCommissionRateRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *QueryParamsResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { +func _Query_QueryOldestUnconfirmedVsc_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryOldestUnconfirmedVscRequest) + if err := dec(in); err != nil { return nil, err } - return dAtA[:n], nil + if interceptor == nil { + return srv.(QueryServer).QueryOldestUnconfirmedVsc(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryOldestUnconfirmedVsc", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryOldestUnconfirmedVsc(ctx, req.(*QueryOldestUnconfirmedVscRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) +func _Query_QueryConsumerValidators_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryConsumerValidatorsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).QueryConsumerValidators(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryConsumerValidators", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).QueryConsumerValidators(ctx, req.(*QueryConsumerValidatorsRequest)) + } + return interceptor(ctx, in, info, handler) } -func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - { - size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "interchain_security.ccv.provider.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "QueryConsumerGenesis", + Handler: _Query_QueryConsumerGenesis_Handler, + }, + { + MethodName: "QueryConsumerChains", + Handler: _Query_QueryConsumerChains_Handler, + }, + { + MethodName: "QueryConsumerChainStarts", + Handler: _Query_QueryConsumerChainStarts_Handler, + }, + { + MethodName: "QueryConsumerChainStops", + Handler: _Query_QueryConsumerChainStops_Handler, + }, + { + MethodName: "QueryValidatorConsumerAddr", + Handler: _Query_QueryValidatorConsumerAddr_Handler, + }, + { + MethodName: "QueryValidatorProviderAddr", + Handler: _Query_QueryValidatorProviderAddr_Handler, + }, + { + MethodName: "QueryThrottleState", + Handler: _Query_QueryThrottleState_Handler, + }, + { + MethodName: "QueryRegisteredConsumerRewardDenoms", + Handler: _Query_QueryRegisteredConsumerRewardDenoms_Handler, + }, + { + MethodName: "QueryProposedConsumerChainIDs", + Handler: _Query_QueryProposedConsumerChainIDs_Handler, + }, + { + MethodName: "QueryAllPairsValConAddrByConsumerChainID", + Handler: _Query_QueryAllPairsValConAddrByConsumerChainID_Handler, + }, + { + MethodName: "QueryParams", + Handler: _Query_QueryParams_Handler, + }, + { + MethodName: "QueryConsumerChainOptedInValidators", + Handler: _Query_QueryConsumerChainOptedInValidators_Handler, + }, + { + MethodName: "QueryConsumerChainsValidatorHasToValidate", + Handler: _Query_QueryConsumerChainsValidatorHasToValidate_Handler, + }, + { + MethodName: "QueryValidatorConsumerCommissionRate", + Handler: _Query_QueryValidatorConsumerCommissionRate_Handler, + }, + { + MethodName: "QueryOldestUnconfirmedVsc", + Handler: _Query_QueryOldestUnconfirmedVsc_Handler, + }, + { + MethodName: "QueryConsumerValidators", + Handler: _Query_QueryConsumerValidators_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "interchain_security/ccv/provider/v1/query.proto", } -func (m *QueryOldestUnconfirmedVscRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryConsumerGenesisRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2697,12 +2608,12 @@ func (m *QueryOldestUnconfirmedVscRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryOldestUnconfirmedVscRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryConsumerGenesisRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryOldestUnconfirmedVscRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryConsumerGenesisRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -2717,7 +2628,7 @@ func (m *QueryOldestUnconfirmedVscRequest) MarshalToSizedBuffer(dAtA []byte) (in return len(dAtA) - i, nil } -func (m *QueryOldestUnconfirmedVscResponse) Marshal() (dAtA []byte, err error) { +func (m *QueryConsumerGenesisResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2727,18 +2638,18 @@ func (m *QueryOldestUnconfirmedVscResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryOldestUnconfirmedVscResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryConsumerGenesisResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryOldestUnconfirmedVscResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryConsumerGenesisResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l { - size, err := m.VscSendTimestamp.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.GenesisState.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -2750,376 +2661,2695 @@ func (m *QueryOldestUnconfirmedVscResponse) MarshalToSizedBuffer(dAtA []byte) (i return len(dAtA) - i, nil } -func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { - offset -= sovQuery(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *QueryConsumerChainsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *QueryConsumerGenesisRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.ChainId) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - return n + +func (m *QueryConsumerChainsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryConsumerGenesisResponse) Size() (n int) { - if m == nil { - return 0 - } +func (m *QueryConsumerChainsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = m.GenesisState.Size() - n += 1 + l + sovQuery(uint64(l)) - return n + return len(dAtA) - i, nil } -func (m *QueryConsumerChainsRequest) Size() (n int) { - if m == nil { - return 0 +func (m *QueryConsumerChainsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - return n + return dAtA[:n], nil } -func (m *QueryConsumerChainsResponse) Size() (n int) { - if m == nil { - return 0 - } +func (m *QueryConsumerChainsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConsumerChainsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l if len(m.Chains) > 0 { - for _, e := range m.Chains { - l = e.Size() - n += 1 + l + sovQuery(uint64(l)) + for iNdEx := len(m.Chains) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Chains[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa } } - return n + return len(dAtA) - i, nil } -func (m *QueryConsumerChainStartProposalsRequest) Size() (n int) { - if m == nil { - return 0 +func (m *QueryConsumerChainStartProposalsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *QueryConsumerChainStartProposalsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConsumerChainStartProposalsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - return n + return len(dAtA) - i, nil } -func (m *QueryConsumerChainStartProposalsResponse) Size() (n int) { - if m == nil { - return 0 +func (m *QueryConsumerChainStartProposalsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *QueryConsumerChainStartProposalsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConsumerChainStartProposalsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l if m.Proposals != nil { - l = m.Proposals.Size() - n += 1 + l + sovQuery(uint64(l)) + { + size, err := m.Proposals.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *QueryConsumerChainStopProposalsRequest) Size() (n int) { - if m == nil { - return 0 +func (m *QueryConsumerChainStopProposalsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - return n + return dAtA[:n], nil } -func (m *QueryConsumerChainStopProposalsResponse) Size() (n int) { - if m == nil { - return 0 - } +func (m *QueryConsumerChainStopProposalsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConsumerChainStopProposalsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.Proposals != nil { - l = m.Proposals.Size() - n += 1 + l + sovQuery(uint64(l)) - } - return n + return len(dAtA) - i, nil } -func (m *Chain) Size() (n int) { - if m == nil { - return 0 +func (m *QueryConsumerChainStopProposalsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *QueryConsumerChainStopProposalsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConsumerChainStopProposalsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.ChainId) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - l = len(m.ClientId) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + if m.Proposals != nil { + { + size, err := m.Proposals.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *QueryValidatorConsumerAddrRequest) Size() (n int) { - if m == nil { - return 0 +func (m *Chain) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *Chain) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Chain) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.ChainId) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + if len(m.Denylist) > 0 { + for iNdEx := len(m.Denylist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Denylist[iNdEx]) + copy(dAtA[i:], m.Denylist[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Denylist[iNdEx]))) + i-- + dAtA[i] = 0x42 + } } - l = len(m.ProviderAddress) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + if len(m.Allowlist) > 0 { + for iNdEx := len(m.Allowlist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Allowlist[iNdEx]) + copy(dAtA[i:], m.Allowlist[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Allowlist[iNdEx]))) + i-- + dAtA[i] = 0x3a + } } - return n -} - -func (m *QueryValidatorConsumerAddrResponse) Size() (n int) { - if m == nil { - return 0 + if m.ValidatorSetCap != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.ValidatorSetCap)) + i-- + dAtA[i] = 0x30 } - var l int - _ = l - l = len(m.ConsumerAddress) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + if m.ValidatorsPowerCap != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.ValidatorsPowerCap)) + i-- + dAtA[i] = 0x28 } - return n -} - -func (m *QueryValidatorProviderAddrRequest) Size() (n int) { - if m == nil { - return 0 + if m.MinPowerInTop_N != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.MinPowerInTop_N)) + i-- + dAtA[i] = 0x20 } - var l int - _ = l - l = len(m.ChainId) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + if m.Top_N != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Top_N)) + i-- + dAtA[i] = 0x18 } - l = len(m.ConsumerAddress) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + if len(m.ClientId) > 0 { + i -= len(m.ClientId) + copy(dAtA[i:], m.ClientId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ClientId))) + i-- + dAtA[i] = 0x12 } - return n + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil } -func (m *QueryValidatorProviderAddrResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.ProviderAddress) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) +func (m *QueryValidatorConsumerAddrRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - return n + return dAtA[:n], nil } -func (m *QueryThrottleStateRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n +func (m *QueryValidatorConsumerAddrRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryThrottleStateResponse) Size() (n int) { - if m == nil { - return 0 - } +func (m *QueryValidatorConsumerAddrRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.SlashMeter != 0 { - n += 1 + sovQuery(uint64(m.SlashMeter)) + if len(m.ProviderAddress) > 0 { + i -= len(m.ProviderAddress) + copy(dAtA[i:], m.ProviderAddress) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ProviderAddress))) + i-- + dAtA[i] = 0x12 } - if m.SlashMeterAllowance != 0 { - n += 1 + sovQuery(uint64(m.SlashMeterAllowance)) + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa } - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.NextReplenishCandidate) - n += 1 + l + sovQuery(uint64(l)) - return n + return len(dAtA) - i, nil } -func (m *QueryRegisteredConsumerRewardDenomsRequest) Size() (n int) { - if m == nil { - return 0 +func (m *QueryValidatorConsumerAddrResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - return n + return dAtA[:n], nil } -func (m *QueryRegisteredConsumerRewardDenomsResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Denoms) > 0 { - for _, s := range m.Denoms { - l = len(s) - n += 1 + l + sovQuery(uint64(l)) - } - } - return n +func (m *QueryValidatorConsumerAddrResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryProposedChainIDsRequest) Size() (n int) { - if m == nil { - return 0 - } +func (m *QueryValidatorConsumerAddrResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - return n + if len(m.ConsumerAddress) > 0 { + i -= len(m.ConsumerAddress) + copy(dAtA[i:], m.ConsumerAddress) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ConsumerAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil } -func (m *QueryProposedChainIDsResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.ProposedChains) > 0 { - for _, e := range m.ProposedChains { - l = e.Size() - n += 1 + l + sovQuery(uint64(l)) - } +func (m *QueryValidatorProviderAddrRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - return n + return dAtA[:n], nil } -func (m *ProposedChain) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.ChainID) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - if m.ProposalID != 0 { - n += 1 + sovQuery(uint64(m.ProposalID)) - } - return n +func (m *QueryValidatorProviderAddrRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryAllPairsValConAddrByConsumerChainIDRequest) Size() (n int) { - if m == nil { - return 0 - } +func (m *QueryValidatorProviderAddrRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.ChainId) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + if len(m.ConsumerAddress) > 0 { + i -= len(m.ConsumerAddress) + copy(dAtA[i:], m.ConsumerAddress) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ConsumerAddress))) + i-- + dAtA[i] = 0x12 } - return n + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil } -func (m *QueryAllPairsValConAddrByConsumerChainIDResponse) Size() (n int) { - if m == nil { - return 0 +func (m *QueryValidatorProviderAddrResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *QueryValidatorProviderAddrResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryValidatorProviderAddrResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if len(m.PairValConAddr) > 0 { - for _, e := range m.PairValConAddr { - l = e.Size() - n += 1 + l + sovQuery(uint64(l)) - } + if len(m.ProviderAddress) > 0 { + i -= len(m.ProviderAddress) + copy(dAtA[i:], m.ProviderAddress) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ProviderAddress))) + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *PairValConAddrProviderAndConsumer) Size() (n int) { - if m == nil { - return 0 +func (m *QueryThrottleStateRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryThrottleStateRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryThrottleStateRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryThrottleStateResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *QueryThrottleStateResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryThrottleStateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.ProviderAddress) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + n4, err4 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.NextReplenishCandidate, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.NextReplenishCandidate):]) + if err4 != nil { + return 0, err4 } - l = len(m.ConsumerAddress) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + i -= n4 + i = encodeVarintQuery(dAtA, i, uint64(n4)) + i-- + dAtA[i] = 0x1a + if m.SlashMeterAllowance != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.SlashMeterAllowance)) + i-- + dAtA[i] = 0x10 } - if m.ConsumerKey != nil { - l = m.ConsumerKey.Size() - n += 1 + l + sovQuery(uint64(l)) + if m.SlashMeter != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.SlashMeter)) + i-- + dAtA[i] = 0x8 } - return n + return len(dAtA) - i, nil } -func (m *QueryParamsRequest) Size() (n int) { - if m == nil { - return 0 +func (m *QueryRegisteredConsumerRewardDenomsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryRegisteredConsumerRewardDenomsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryRegisteredConsumerRewardDenomsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryRegisteredConsumerRewardDenomsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *QueryRegisteredConsumerRewardDenomsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryRegisteredConsumerRewardDenomsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - return n + if len(m.Denoms) > 0 { + for iNdEx := len(m.Denoms) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Denoms[iNdEx]) + copy(dAtA[i:], m.Denoms[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Denoms[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil } -func (m *QueryParamsResponse) Size() (n int) { - if m == nil { - return 0 +func (m *QueryProposedChainIDsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *QueryProposedChainIDsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryProposedChainIDsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = m.Params.Size() - n += 1 + l + sovQuery(uint64(l)) - return n + return len(dAtA) - i, nil } -func (m *QueryOldestUnconfirmedVscRequest) Size() (n int) { - if m == nil { - return 0 +func (m *QueryProposedChainIDsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *QueryProposedChainIDsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryProposedChainIDsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.ChainId) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + if len(m.ProposedChains) > 0 { + for iNdEx := len(m.ProposedChains) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ProposedChains[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } } - return n + return len(dAtA) - i, nil } -func (m *QueryOldestUnconfirmedVscResponse) Size() (n int) { - if m == nil { - return 0 +func (m *ProposedChain) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ProposedChain) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ProposedChain) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ProposalID != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.ProposalID)) + i-- + dAtA[i] = 0x10 + } + if len(m.ChainID) > 0 { + i -= len(m.ChainID) + copy(dAtA[i:], m.ChainID) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainID))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryAllPairsValConAddrByConsumerChainIDRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAllPairsValConAddrByConsumerChainIDRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAllPairsValConAddrByConsumerChainIDRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryAllPairsValConAddrByConsumerChainIDResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAllPairsValConAddrByConsumerChainIDResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAllPairsValConAddrByConsumerChainIDResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.PairValConAddr) > 0 { + for iNdEx := len(m.PairValConAddr) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.PairValConAddr[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *PairValConAddrProviderAndConsumer) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PairValConAddrProviderAndConsumer) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PairValConAddrProviderAndConsumer) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ConsumerKey != nil { + { + size, err := m.ConsumerKey.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if len(m.ConsumerAddress) > 0 { + i -= len(m.ConsumerAddress) + copy(dAtA[i:], m.ConsumerAddress) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ConsumerAddress))) + i-- + dAtA[i] = 0x12 + } + if len(m.ProviderAddress) > 0 { + i -= len(m.ProviderAddress) + copy(dAtA[i:], m.ProviderAddress) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ProviderAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryParamsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryConsumerChainOptedInValidatorsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryConsumerChainOptedInValidatorsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConsumerChainOptedInValidatorsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryConsumerChainOptedInValidatorsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryConsumerChainOptedInValidatorsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConsumerChainOptedInValidatorsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ValidatorsProviderAddresses) > 0 { + for iNdEx := len(m.ValidatorsProviderAddresses) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ValidatorsProviderAddresses[iNdEx]) + copy(dAtA[i:], m.ValidatorsProviderAddresses[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ValidatorsProviderAddresses[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryConsumerValidatorsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryConsumerValidatorsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConsumerValidatorsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryConsumerValidatorsValidator) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryConsumerValidatorsValidator) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConsumerValidatorsValidator) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Power != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Power)) + i-- + dAtA[i] = 0x18 + } + if m.ConsumerKey != nil { + { + size, err := m.ConsumerKey.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.ProviderAddress) > 0 { + i -= len(m.ProviderAddress) + copy(dAtA[i:], m.ProviderAddress) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ProviderAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryConsumerValidatorsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryConsumerValidatorsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConsumerValidatorsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Validators) > 0 { + for iNdEx := len(m.Validators) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Validators[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryConsumerChainsValidatorHasToValidateRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryConsumerChainsValidatorHasToValidateRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConsumerChainsValidatorHasToValidateRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ProviderAddress) > 0 { + i -= len(m.ProviderAddress) + copy(dAtA[i:], m.ProviderAddress) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ProviderAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryConsumerChainsValidatorHasToValidateResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryConsumerChainsValidatorHasToValidateResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryConsumerChainsValidatorHasToValidateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ConsumerChainIds) > 0 { + for iNdEx := len(m.ConsumerChainIds) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ConsumerChainIds[iNdEx]) + copy(dAtA[i:], m.ConsumerChainIds[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ConsumerChainIds[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryValidatorConsumerCommissionRateRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryValidatorConsumerCommissionRateRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryValidatorConsumerCommissionRateRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ProviderAddress) > 0 { + i -= len(m.ProviderAddress) + copy(dAtA[i:], m.ProviderAddress) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ProviderAddress))) + i-- + dAtA[i] = 0x12 + } + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryValidatorConsumerCommissionRateResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryValidatorConsumerCommissionRateResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryValidatorConsumerCommissionRateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.Rate.Size() + i -= size + if _, err := m.Rate.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryOldestUnconfirmedVscRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryOldestUnconfirmedVscRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryOldestUnconfirmedVscRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryOldestUnconfirmedVscResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryOldestUnconfirmedVscResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryOldestUnconfirmedVscResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.VscSendTimestamp.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryConsumerGenesisRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryConsumerGenesisResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.GenesisState.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryConsumerChainsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryConsumerChainsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Chains) > 0 { + for _, e := range m.Chains { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryConsumerChainStartProposalsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryConsumerChainStartProposalsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Proposals != nil { + l = m.Proposals.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryConsumerChainStopProposalsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryConsumerChainStopProposalsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Proposals != nil { + l = m.Proposals.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *Chain) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ClientId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Top_N != 0 { + n += 1 + sovQuery(uint64(m.Top_N)) + } + if m.MinPowerInTop_N != 0 { + n += 1 + sovQuery(uint64(m.MinPowerInTop_N)) + } + if m.ValidatorsPowerCap != 0 { + n += 1 + sovQuery(uint64(m.ValidatorsPowerCap)) + } + if m.ValidatorSetCap != 0 { + n += 1 + sovQuery(uint64(m.ValidatorSetCap)) + } + if len(m.Allowlist) > 0 { + for _, s := range m.Allowlist { + l = len(s) + n += 1 + l + sovQuery(uint64(l)) + } + } + if len(m.Denylist) > 0 { + for _, s := range m.Denylist { + l = len(s) + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryValidatorConsumerAddrRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ProviderAddress) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryValidatorConsumerAddrResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ConsumerAddress) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryValidatorProviderAddrRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ConsumerAddress) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryValidatorProviderAddrResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ProviderAddress) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryThrottleStateRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryThrottleStateResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SlashMeter != 0 { + n += 1 + sovQuery(uint64(m.SlashMeter)) + } + if m.SlashMeterAllowance != 0 { + n += 1 + sovQuery(uint64(m.SlashMeterAllowance)) + } + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.NextReplenishCandidate) + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryRegisteredConsumerRewardDenomsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryRegisteredConsumerRewardDenomsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Denoms) > 0 { + for _, s := range m.Denoms { + l = len(s) + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryProposedChainIDsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryProposedChainIDsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ProposedChains) > 0 { + for _, e := range m.ProposedChains { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *ProposedChain) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainID) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.ProposalID != 0 { + n += 1 + sovQuery(uint64(m.ProposalID)) + } + return n +} + +func (m *QueryAllPairsValConAddrByConsumerChainIDRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryAllPairsValConAddrByConsumerChainIDResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.PairValConAddr) > 0 { + for _, e := range m.PairValConAddr { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *PairValConAddrProviderAndConsumer) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ProviderAddress) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ConsumerAddress) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.ConsumerKey != nil { + l = m.ConsumerKey.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryConsumerChainOptedInValidatorsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryConsumerChainOptedInValidatorsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ValidatorsProviderAddresses) > 0 { + for _, s := range m.ValidatorsProviderAddresses { + l = len(s) + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryConsumerValidatorsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryConsumerValidatorsValidator) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ProviderAddress) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.ConsumerKey != nil { + l = m.ConsumerKey.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.Power != 0 { + n += 1 + sovQuery(uint64(m.Power)) + } + return n +} + +func (m *QueryConsumerValidatorsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Validators) > 0 { + for _, e := range m.Validators { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryConsumerChainsValidatorHasToValidateRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ProviderAddress) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryConsumerChainsValidatorHasToValidateResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ConsumerChainIds) > 0 { + for _, s := range m.ConsumerChainIds { + l = len(s) + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryValidatorConsumerCommissionRateRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ProviderAddress) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryValidatorConsumerCommissionRateResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Rate.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryOldestUnconfirmedVscRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryOldestUnconfirmedVscResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.VscSendTimestamp.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryConsumerGenesisRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryConsumerGenesisRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryConsumerGenesisRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryConsumerGenesisResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryConsumerGenesisResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryConsumerGenesisResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GenesisState", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.GenesisState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryConsumerChainsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryConsumerChainsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryConsumerChainsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryConsumerChainsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryConsumerChainsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryConsumerChainsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Chains", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Chains = append(m.Chains, &Chain{}) + if err := m.Chains[len(m.Chains)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryConsumerChainStartProposalsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryConsumerChainStartProposalsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryConsumerChainStartProposalsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryConsumerChainStartProposalsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryConsumerChainStartProposalsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryConsumerChainStartProposalsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Proposals", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Proposals == nil { + m.Proposals = &ConsumerAdditionProposals{} + } + if err := m.Proposals.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryConsumerChainStopProposalsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryConsumerChainStopProposalsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryConsumerChainStopProposalsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryConsumerChainStopProposalsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryConsumerChainStopProposalsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryConsumerChainStopProposalsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Proposals", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Proposals == nil { + m.Proposals = &ConsumerRemovalProposals{} + } + if err := m.Proposals.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Chain) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Chain: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Chain: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClientId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClientId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Top_N", wireType) + } + m.Top_N = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Top_N |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinPowerInTop_N", wireType) + } + m.MinPowerInTop_N = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinPowerInTop_N |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorsPowerCap", wireType) + } + m.ValidatorsPowerCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorsPowerCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorSetCap", wireType) + } + m.ValidatorSetCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorSetCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Allowlist", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Allowlist = append(m.Allowlist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denylist", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Denylist = append(m.Denylist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryValidatorConsumerAddrRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryValidatorConsumerAddrRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryValidatorConsumerAddrRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProviderAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryValidatorConsumerAddrResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryValidatorConsumerAddrResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryValidatorConsumerAddrResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConsumerAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } } - var l int - _ = l - l = m.VscSendTimestamp.Size() - n += 1 + l + sovQuery(uint64(l)) - return n -} -func sovQuery(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozQuery(x uint64) (n int) { - return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil } -func (m *QueryConsumerGenesisRequest) Unmarshal(dAtA []byte) error { +func (m *QueryValidatorProviderAddrRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3142,10 +5372,10 @@ func (m *QueryConsumerGenesisRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryConsumerGenesisRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryValidatorProviderAddrRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryConsumerGenesisRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryValidatorProviderAddrRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -3180,6 +5410,38 @@ func (m *QueryConsumerGenesisRequest) Unmarshal(dAtA []byte) error { } m.ChainId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConsumerAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -3201,7 +5463,7 @@ func (m *QueryConsumerGenesisRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryConsumerGenesisResponse) Unmarshal(dAtA []byte) error { +func (m *QueryValidatorProviderAddrResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3224,17 +5486,17 @@ func (m *QueryConsumerGenesisResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryConsumerGenesisResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryValidatorProviderAddrResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryConsumerGenesisResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryValidatorProviderAddrResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GenesisState", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddress", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -3244,24 +5506,23 @@ func (m *QueryConsumerGenesisResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.GenesisState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ProviderAddress = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -3284,7 +5545,7 @@ func (m *QueryConsumerGenesisResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryConsumerChainsRequest) Unmarshal(dAtA []byte) error { +func (m *QueryThrottleStateRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3307,10 +5568,10 @@ func (m *QueryConsumerChainsRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryConsumerChainsRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryThrottleStateRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryConsumerChainsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryThrottleStateRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -3334,7 +5595,7 @@ func (m *QueryConsumerChainsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryConsumerChainsResponse) Unmarshal(dAtA []byte) error { +func (m *QueryThrottleStateResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3357,15 +5618,53 @@ func (m *QueryConsumerChainsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryConsumerChainsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryThrottleStateResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryConsumerChainsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryThrottleStateResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SlashMeter", wireType) + } + m.SlashMeter = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SlashMeter |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SlashMeterAllowance", wireType) + } + m.SlashMeterAllowance = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SlashMeterAllowance |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Chains", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field NextReplenishCandidate", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3392,8 +5691,7 @@ func (m *QueryConsumerChainsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Chains = append(m.Chains, &Chain{}) - if err := m.Chains[len(m.Chains)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.NextReplenishCandidate, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -3418,7 +5716,7 @@ func (m *QueryConsumerChainsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryConsumerChainStartProposalsRequest) Unmarshal(dAtA []byte) error { +func (m *QueryRegisteredConsumerRewardDenomsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3441,10 +5739,10 @@ func (m *QueryConsumerChainStartProposalsRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryConsumerChainStartProposalsRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryConsumerChainStartProposalsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -3468,7 +5766,7 @@ func (m *QueryConsumerChainStartProposalsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryConsumerChainStartProposalsResponse) Unmarshal(dAtA []byte) error { +func (m *QueryRegisteredConsumerRewardDenomsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3491,17 +5789,17 @@ func (m *QueryConsumerChainStartProposalsResponse) Unmarshal(dAtA []byte) error fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryConsumerChainStartProposalsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryConsumerChainStartProposalsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Proposals", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Denoms", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -3511,27 +5809,23 @@ func (m *QueryConsumerChainStartProposalsResponse) Unmarshal(dAtA []byte) error } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Proposals == nil { - m.Proposals = &ConsumerAdditionProposals{} - } - if err := m.Proposals.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Denoms = append(m.Denoms, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -3554,7 +5848,7 @@ func (m *QueryConsumerChainStartProposalsResponse) Unmarshal(dAtA []byte) error } return nil } -func (m *QueryConsumerChainStopProposalsRequest) Unmarshal(dAtA []byte) error { +func (m *QueryProposedChainIDsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3577,10 +5871,10 @@ func (m *QueryConsumerChainStopProposalsRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryConsumerChainStopProposalsRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryProposedChainIDsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryConsumerChainStopProposalsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryProposedChainIDsRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -3604,7 +5898,7 @@ func (m *QueryConsumerChainStopProposalsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryConsumerChainStopProposalsResponse) Unmarshal(dAtA []byte) error { +func (m *QueryProposedChainIDsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3627,15 +5921,15 @@ func (m *QueryConsumerChainStopProposalsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryConsumerChainStopProposalsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryProposedChainIDsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryConsumerChainStopProposalsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryProposedChainIDsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Proposals", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProposedChains", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3662,10 +5956,8 @@ func (m *QueryConsumerChainStopProposalsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Proposals == nil { - m.Proposals = &ConsumerRemovalProposals{} - } - if err := m.Proposals.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.ProposedChains = append(m.ProposedChains, ProposedChain{}) + if err := m.ProposedChains[len(m.ProposedChains)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -3690,7 +5982,7 @@ func (m *QueryConsumerChainStopProposalsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *Chain) Unmarshal(dAtA []byte) error { +func (m *ProposedChain) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3713,15 +6005,15 @@ func (m *Chain) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Chain: wiretype end group for non-group") + return fmt.Errorf("proto: ProposedChain: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Chain: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ProposedChain: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3749,13 +6041,13 @@ func (m *Chain) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainId = string(dAtA[iNdEx:postIndex]) + m.ChainID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ClientId", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ProposalID", wireType) } - var stringLen uint64 + m.ProposalID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -3765,24 +6057,11 @@ func (m *Chain) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.ProposalID |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ClientId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -3804,7 +6083,7 @@ func (m *Chain) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryValidatorConsumerAddrRequest) Unmarshal(dAtA []byte) error { +func (m *QueryAllPairsValConAddrByConsumerChainIDRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3822,52 +6101,20 @@ func (m *QueryValidatorConsumerAddrRequest) Unmarshal(dAtA []byte) error { wire |= uint64(b&0x7F) << shift if b < 0x80 { break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: QueryValidatorConsumerAddrRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryValidatorConsumerAddrRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ChainId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAllPairsValConAddrByConsumerChainIDRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAllPairsValConAddrByConsumerChainIDRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddress", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3895,7 +6142,7 @@ func (m *QueryValidatorConsumerAddrRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ProviderAddress = string(dAtA[iNdEx:postIndex]) + m.ChainId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -3918,7 +6165,7 @@ func (m *QueryValidatorConsumerAddrRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryValidatorConsumerAddrResponse) Unmarshal(dAtA []byte) error { +func (m *QueryAllPairsValConAddrByConsumerChainIDResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3941,17 +6188,17 @@ func (m *QueryValidatorConsumerAddrResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryValidatorConsumerAddrResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryAllPairsValConAddrByConsumerChainIDResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryValidatorConsumerAddrResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryAllPairsValConAddrByConsumerChainIDResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConsumerAddress", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PairValConAddr", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -3961,23 +6208,25 @@ func (m *QueryValidatorConsumerAddrResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } - m.ConsumerAddress = string(dAtA[iNdEx:postIndex]) + m.PairValConAddr = append(m.PairValConAddr, &PairValConAddrProviderAndConsumer{}) + if err := m.PairValConAddr[len(m.PairValConAddr)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -4000,7 +6249,7 @@ func (m *QueryValidatorConsumerAddrResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryValidatorProviderAddrRequest) Unmarshal(dAtA []byte) error { +func (m *PairValConAddrProviderAndConsumer) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4023,15 +6272,15 @@ func (m *QueryValidatorProviderAddrRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryValidatorProviderAddrRequest: wiretype end group for non-group") + return fmt.Errorf("proto: PairValConAddrProviderAndConsumer: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryValidatorProviderAddrRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: PairValConAddrProviderAndConsumer: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddress", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4059,7 +6308,7 @@ func (m *QueryValidatorProviderAddrRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainId = string(dAtA[iNdEx:postIndex]) + m.ProviderAddress = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -4093,61 +6342,11 @@ func (m *QueryValidatorProviderAddrRequest) Unmarshal(dAtA []byte) error { } m.ConsumerAddress = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryValidatorProviderAddrResponse) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: QueryValidatorProviderAddrResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryValidatorProviderAddrResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddress", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerKey", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -4157,23 +6356,27 @@ func (m *QueryValidatorProviderAddrResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } - m.ProviderAddress = string(dAtA[iNdEx:postIndex]) + if m.ConsumerKey == nil { + m.ConsumerKey = &crypto.PublicKey{} + } + if err := m.ConsumerKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -4196,7 +6399,7 @@ func (m *QueryValidatorProviderAddrResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryThrottleStateRequest) Unmarshal(dAtA []byte) error { +func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4219,10 +6422,10 @@ func (m *QueryThrottleStateRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryThrottleStateRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryThrottleStateRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -4246,7 +6449,7 @@ func (m *QueryThrottleStateRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryThrottleStateResponse) Unmarshal(dAtA []byte) error { +func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4269,53 +6472,15 @@ func (m *QueryThrottleStateResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryThrottleStateResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryThrottleStateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field SlashMeter", wireType) - } - m.SlashMeter = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.SlashMeter |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field SlashMeterAllowance", wireType) - } - m.SlashMeterAllowance = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.SlashMeterAllowance |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NextReplenishCandidate", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4342,7 +6507,7 @@ func (m *QueryThrottleStateResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.NextReplenishCandidate, dAtA[iNdEx:postIndex]); err != nil { + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -4367,7 +6532,7 @@ func (m *QueryThrottleStateResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryRegisteredConsumerRewardDenomsRequest) Unmarshal(dAtA []byte) error { +func (m *QueryConsumerChainOptedInValidatorsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4390,12 +6555,44 @@ func (m *QueryRegisteredConsumerRewardDenomsRequest) Unmarshal(dAtA []byte) erro fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryConsumerChainOptedInValidatorsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryConsumerChainOptedInValidatorsRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -4417,7 +6614,7 @@ func (m *QueryRegisteredConsumerRewardDenomsRequest) Unmarshal(dAtA []byte) erro } return nil } -func (m *QueryRegisteredConsumerRewardDenomsResponse) Unmarshal(dAtA []byte) error { +func (m *QueryConsumerChainOptedInValidatorsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4440,15 +6637,15 @@ func (m *QueryRegisteredConsumerRewardDenomsResponse) Unmarshal(dAtA []byte) err fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryConsumerChainOptedInValidatorsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryConsumerChainOptedInValidatorsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Denoms", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorsProviderAddresses", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4473,61 +6670,11 @@ func (m *QueryRegisteredConsumerRewardDenomsResponse) Unmarshal(dAtA []byte) err if postIndex < 0 { return ErrInvalidLengthQuery } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Denoms = append(m.Denoms, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryProposedChainIDsRequest) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: QueryProposedChainIDsRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryProposedChainIDsRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorsProviderAddresses = append(m.ValidatorsProviderAddresses, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -4549,7 +6696,7 @@ func (m *QueryProposedChainIDsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryProposedChainIDsResponse) Unmarshal(dAtA []byte) error { +func (m *QueryConsumerValidatorsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4572,17 +6719,17 @@ func (m *QueryProposedChainIDsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryProposedChainIDsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryConsumerValidatorsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryProposedChainIDsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryConsumerValidatorsRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProposedChains", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -4592,25 +6739,23 @@ func (m *QueryProposedChainIDsResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } - m.ProposedChains = append(m.ProposedChains, ProposedChain{}) - if err := m.ProposedChains[len(m.ProposedChains)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ChainId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -4633,7 +6778,7 @@ func (m *QueryProposedChainIDsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *ProposedChain) Unmarshal(dAtA []byte) error { +func (m *QueryConsumerValidatorsValidator) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4656,15 +6801,15 @@ func (m *ProposedChain) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ProposedChain: wiretype end group for non-group") + return fmt.Errorf("proto: QueryConsumerValidatorsValidator: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ProposedChain: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryConsumerValidatorsValidator: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddress", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4692,13 +6837,49 @@ func (m *ProposedChain) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainID = string(dAtA[iNdEx:postIndex]) + m.ProviderAddress = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerKey", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ConsumerKey == nil { + m.ConsumerKey = &crypto.PublicKey{} + } + if err := m.ConsumerKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ProposalID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Power", wireType) } - m.ProposalID = 0 + m.Power = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -4708,7 +6889,7 @@ func (m *ProposedChain) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ProposalID |= uint64(b&0x7F) << shift + m.Power |= int64(b&0x7F) << shift if b < 0x80 { break } @@ -4734,7 +6915,7 @@ func (m *ProposedChain) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryAllPairsValConAddrByConsumerChainIDRequest) Unmarshal(dAtA []byte) error { +func (m *QueryConsumerValidatorsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4757,17 +6938,17 @@ func (m *QueryAllPairsValConAddrByConsumerChainIDRequest) Unmarshal(dAtA []byte) fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryAllPairsValConAddrByConsumerChainIDRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryConsumerValidatorsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryAllPairsValConAddrByConsumerChainIDRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryConsumerValidatorsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Validators", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -4777,23 +6958,25 @@ func (m *QueryAllPairsValConAddrByConsumerChainIDRequest) Unmarshal(dAtA []byte) } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainId = string(dAtA[iNdEx:postIndex]) + m.Validators = append(m.Validators, &QueryConsumerValidatorsValidator{}) + if err := m.Validators[len(m.Validators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -4816,7 +6999,7 @@ func (m *QueryAllPairsValConAddrByConsumerChainIDRequest) Unmarshal(dAtA []byte) } return nil } -func (m *QueryAllPairsValConAddrByConsumerChainIDResponse) Unmarshal(dAtA []byte) error { +func (m *QueryConsumerChainsValidatorHasToValidateRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4839,17 +7022,17 @@ func (m *QueryAllPairsValConAddrByConsumerChainIDResponse) Unmarshal(dAtA []byte fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryAllPairsValConAddrByConsumerChainIDResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryConsumerChainsValidatorHasToValidateRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryAllPairsValConAddrByConsumerChainIDResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryConsumerChainsValidatorHasToValidateRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PairValConAddr", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddress", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -4859,25 +7042,23 @@ func (m *QueryAllPairsValConAddrByConsumerChainIDResponse) Unmarshal(dAtA []byte } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } - m.PairValConAddr = append(m.PairValConAddr, &PairValConAddrProviderAndConsumer{}) - if err := m.PairValConAddr[len(m.PairValConAddr)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ProviderAddress = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -4900,7 +7081,7 @@ func (m *QueryAllPairsValConAddrByConsumerChainIDResponse) Unmarshal(dAtA []byte } return nil } -func (m *PairValConAddrProviderAndConsumer) Unmarshal(dAtA []byte) error { +func (m *QueryConsumerChainsValidatorHasToValidateResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4923,15 +7104,15 @@ func (m *PairValConAddrProviderAndConsumer) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PairValConAddrProviderAndConsumer: wiretype end group for non-group") + return fmt.Errorf("proto: QueryConsumerChainsValidatorHasToValidateResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PairValConAddrProviderAndConsumer: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryConsumerChainsValidatorHasToValidateResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddress", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerChainIds", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4959,11 +7140,61 @@ func (m *PairValConAddrProviderAndConsumer) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ProviderAddress = string(dAtA[iNdEx:postIndex]) + m.ConsumerChainIds = append(m.ConsumerChainIds, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 2: + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryValidatorConsumerCommissionRateRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryValidatorConsumerCommissionRateRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryValidatorConsumerCommissionRateRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConsumerAddress", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4991,13 +7222,13 @@ func (m *PairValConAddrProviderAndConsumer) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ConsumerAddress = string(dAtA[iNdEx:postIndex]) + m.ChainId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConsumerKey", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddress", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -5007,27 +7238,23 @@ func (m *PairValConAddrProviderAndConsumer) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } - if m.ConsumerKey == nil { - m.ConsumerKey = &crypto.PublicKey{} - } - if err := m.ConsumerKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ProviderAddress = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -5050,57 +7277,7 @@ func (m *PairValConAddrProviderAndConsumer) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { +func (m *QueryValidatorConsumerCommissionRateResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5123,17 +7300,17 @@ func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryValidatorConsumerCommissionRateResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryValidatorConsumerCommissionRateResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Rate", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -5143,22 +7320,23 @@ func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Rate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/x/ccv/provider/types/query.pb.gw.go b/x/ccv/provider/types/query.pb.gw.go index 0ebfbfa6fd..16bb010d71 100644 --- a/x/ccv/provider/types/query.pb.gw.go +++ b/x/ccv/provider/types/query.pb.gw.go @@ -321,6 +321,190 @@ func local_request_Query_QueryParams_0(ctx context.Context, marshaler runtime.Ma } +func request_Query_QueryConsumerChainOptedInValidators_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryConsumerChainOptedInValidatorsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + msg, err := client.QueryConsumerChainOptedInValidators(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_QueryConsumerChainOptedInValidators_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryConsumerChainOptedInValidatorsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + msg, err := server.QueryConsumerChainOptedInValidators(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_QueryConsumerChainsValidatorHasToValidate_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryConsumerChainsValidatorHasToValidateRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["provider_address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "provider_address") + } + + protoReq.ProviderAddress, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "provider_address", err) + } + + msg, err := client.QueryConsumerChainsValidatorHasToValidate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_QueryConsumerChainsValidatorHasToValidate_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryConsumerChainsValidatorHasToValidateRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["provider_address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "provider_address") + } + + protoReq.ProviderAddress, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "provider_address", err) + } + + msg, err := server.QueryConsumerChainsValidatorHasToValidate(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_QueryValidatorConsumerCommissionRate_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryValidatorConsumerCommissionRateRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + val, ok = pathParams["provider_address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "provider_address") + } + + protoReq.ProviderAddress, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "provider_address", err) + } + + msg, err := client.QueryValidatorConsumerCommissionRate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_QueryValidatorConsumerCommissionRate_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryValidatorConsumerCommissionRateRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + val, ok = pathParams["provider_address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "provider_address") + } + + protoReq.ProviderAddress, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "provider_address", err) + } + + msg, err := server.QueryValidatorConsumerCommissionRate(ctx, &protoReq) + return msg, metadata, err + +} + func request_Query_QueryOldestUnconfirmedVsc_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryOldestUnconfirmedVscRequest var metadata runtime.ServerMetadata @@ -375,6 +559,60 @@ func local_request_Query_QueryOldestUnconfirmedVsc_0(ctx context.Context, marsha } +func request_Query_QueryConsumerValidators_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryConsumerValidatorsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + msg, err := client.QueryConsumerValidators(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_QueryConsumerValidators_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryConsumerValidatorsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["chain_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "chain_id") + } + + protoReq.ChainId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "chain_id", err) + } + + msg, err := server.QueryConsumerValidators(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -634,6 +872,75 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_QueryConsumerChainOptedInValidators_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_QueryConsumerChainOptedInValidators_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QueryConsumerChainOptedInValidators_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_QueryConsumerChainsValidatorHasToValidate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_QueryConsumerChainsValidatorHasToValidate_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QueryConsumerChainsValidatorHasToValidate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_QueryValidatorConsumerCommissionRate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_QueryValidatorConsumerCommissionRate_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QueryValidatorConsumerCommissionRate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_QueryOldestUnconfirmedVsc_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -657,6 +964,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_QueryConsumerValidators_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_QueryConsumerValidators_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QueryConsumerValidators_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -918,6 +1248,66 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_QueryConsumerChainOptedInValidators_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_QueryConsumerChainOptedInValidators_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QueryConsumerChainOptedInValidators_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_QueryConsumerChainsValidatorHasToValidate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_QueryConsumerChainsValidatorHasToValidate_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QueryConsumerChainsValidatorHasToValidate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_QueryValidatorConsumerCommissionRate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_QueryValidatorConsumerCommissionRate_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QueryValidatorConsumerCommissionRate_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_QueryOldestUnconfirmedVsc_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -938,6 +1328,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_QueryConsumerValidators_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_QueryConsumerValidators_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_QueryConsumerValidators_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -964,7 +1374,15 @@ var ( pattern_Query_QueryParams_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"interchain_security", "ccv", "provider", "params"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_QueryConsumerChainOptedInValidators_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"interchain_security", "ccv", "provider", "opted_in_validators", "chain_id"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_QueryConsumerChainsValidatorHasToValidate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"interchain_security", "ccv", "provider", "consumer_chains_per_validator", "provider_address"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_QueryValidatorConsumerCommissionRate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"interchain_security", "ccv", "provider", "consumer_commission_rate", "chain_id", "provider_address"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_QueryOldestUnconfirmedVsc_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"interchain_security", "ccv", "provider", "oldest_unconfirmed_vsc", "chain_id"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_QueryConsumerValidators_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"interchain_security", "ccv", "provider", "consumer_validators", "chain_id"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -990,5 +1408,13 @@ var ( forward_Query_QueryParams_0 = runtime.ForwardResponseMessage + forward_Query_QueryConsumerChainOptedInValidators_0 = runtime.ForwardResponseMessage + + forward_Query_QueryConsumerChainsValidatorHasToValidate_0 = runtime.ForwardResponseMessage + + forward_Query_QueryValidatorConsumerCommissionRate_0 = runtime.ForwardResponseMessage + forward_Query_QueryOldestUnconfirmedVsc_0 = runtime.ForwardResponseMessage + + forward_Query_QueryConsumerValidators_0 = runtime.ForwardResponseMessage ) diff --git a/x/ccv/provider/types/tx.pb.go b/x/ccv/provider/types/tx.pb.go index e0ddad16ba..debc79ba02 100644 --- a/x/ccv/provider/types/tx.pb.go +++ b/x/ccv/provider/types/tx.pb.go @@ -5,6 +5,7 @@ package types import ( context "context" + cosmossdk_io_math "cosmossdk.io/math" fmt "fmt" types "github.com/cometbft/cometbft/proto/tendermint/types" _ "github.com/cosmos/cosmos-proto" @@ -425,8 +426,27 @@ type MsgConsumerAddition struct { // chain. it is most relevant for chains performing a sovereign to consumer // changeover in order to maintan the existing ibc transfer channel DistributionTransmissionChannel string `protobuf:"bytes,12,opt,name=distribution_transmission_channel,json=distributionTransmissionChannel,proto3" json:"distribution_transmission_channel,omitempty"` + // Corresponds to the percentage of validators that have to validate the chain under the Top N case. + // For example, 53 corresponds to a Top 53% chain, meaning that the top 53% provider validators by voting power + // have to validate the proposed consumer chain. top_N can either be 0 or any value in [50, 100]. + // A chain can join with top_N == 0 as an Opt In chain, or with top_N ∈ [50, 100] as a Top N chain. + Top_N uint32 `protobuf:"varint,13,opt,name=top_N,json=topN,proto3" json:"top_N,omitempty"` + // Corresponds to the maximum power (percentage-wise) a validator can have on the consumer chain. For instance, if + // `validators_power_cap` is set to 32, it means that no validator can have more than 32% of the voting power on the + // consumer chain. Note that this might not be feasible. For example, think of a consumer chain with only + // 5 validators and with `validators_power_cap` set to 10%. In such a scenario, at least one validator would need + // to have more than 20% of the total voting power. Therefore, `validators_power_cap` operates on a best-effort basis. + ValidatorsPowerCap uint32 `protobuf:"varint,14,opt,name=validators_power_cap,json=validatorsPowerCap,proto3" json:"validators_power_cap,omitempty"` + // Corresponds to the maximum number of validators that can validate a consumer chain. + // Only applicable to Opt In chains. Setting `validator_set_cap` on a Top N chain is a no-op. + ValidatorSetCap uint32 `protobuf:"varint,15,opt,name=validator_set_cap,json=validatorSetCap,proto3" json:"validator_set_cap,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that are the ONLY ones that can validate + // the consumer chain. + Allowlist []string `protobuf:"bytes,16,rep,name=allowlist,proto3" json:"allowlist,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that CANNOT validate the consumer chain. + Denylist []string `protobuf:"bytes,17,rep,name=denylist,proto3" json:"denylist,omitempty"` // signer address - Authority string `protobuf:"bytes,13,opt,name=authority,proto3" json:"authority,omitempty"` + Authority string `protobuf:"bytes,18,opt,name=authority,proto3" json:"authority,omitempty"` } func (m *MsgConsumerAddition) Reset() { *m = MsgConsumerAddition{} } @@ -546,6 +566,41 @@ func (m *MsgConsumerAddition) GetDistributionTransmissionChannel() string { return "" } +func (m *MsgConsumerAddition) GetTop_N() uint32 { + if m != nil { + return m.Top_N + } + return 0 +} + +func (m *MsgConsumerAddition) GetValidatorsPowerCap() uint32 { + if m != nil { + return m.ValidatorsPowerCap + } + return 0 +} + +func (m *MsgConsumerAddition) GetValidatorSetCap() uint32 { + if m != nil { + return m.ValidatorSetCap + } + return 0 +} + +func (m *MsgConsumerAddition) GetAllowlist() []string { + if m != nil { + return m.Allowlist + } + return nil +} + +func (m *MsgConsumerAddition) GetDenylist() []string { + if m != nil { + return m.Denylist + } + return nil +} + func (m *MsgConsumerAddition) GetAuthority() string { if m != nil { return m.Authority @@ -801,6 +856,415 @@ func (m *MsgChangeRewardDenomsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgChangeRewardDenomsResponse proto.InternalMessageInfo +type MsgOptIn struct { + // the chain id of the consumer chain to opt in to + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // the validator address on the provider + ProviderAddr string `protobuf:"bytes,2,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty" yaml:"address"` + // (optional) The consensus public key to use on the consumer in json string format corresponding to proto-any, + // for example `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is="}`. + // This field is optional and can remain empty (i.e., `consumer_key = ""`). A validator can always change the + // consumer public key at a later stage by issuing a `MsgAssignConsumerKey` message. + ConsumerKey string `protobuf:"bytes,3,opt,name=consumer_key,json=consumerKey,proto3" json:"consumer_key,omitempty"` + // signer address + Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty"` +} + +func (m *MsgOptIn) Reset() { *m = MsgOptIn{} } +func (m *MsgOptIn) String() string { return proto.CompactTextString(m) } +func (*MsgOptIn) ProtoMessage() {} +func (*MsgOptIn) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{14} +} +func (m *MsgOptIn) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgOptIn) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgOptIn.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgOptIn) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgOptIn.Merge(m, src) +} +func (m *MsgOptIn) XXX_Size() int { + return m.Size() +} +func (m *MsgOptIn) XXX_DiscardUnknown() { + xxx_messageInfo_MsgOptIn.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgOptIn proto.InternalMessageInfo + +type MsgOptInResponse struct { +} + +func (m *MsgOptInResponse) Reset() { *m = MsgOptInResponse{} } +func (m *MsgOptInResponse) String() string { return proto.CompactTextString(m) } +func (*MsgOptInResponse) ProtoMessage() {} +func (*MsgOptInResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{15} +} +func (m *MsgOptInResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgOptInResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgOptInResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgOptInResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgOptInResponse.Merge(m, src) +} +func (m *MsgOptInResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgOptInResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgOptInResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgOptInResponse proto.InternalMessageInfo + +type MsgOptOut struct { + // the chain id of the consumer chain to opt out from + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // the validator address on the provider + ProviderAddr string `protobuf:"bytes,2,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty" yaml:"address"` + // signer address + Signer string `protobuf:"bytes,3,opt,name=signer,proto3" json:"signer,omitempty"` +} + +func (m *MsgOptOut) Reset() { *m = MsgOptOut{} } +func (m *MsgOptOut) String() string { return proto.CompactTextString(m) } +func (*MsgOptOut) ProtoMessage() {} +func (*MsgOptOut) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{16} +} +func (m *MsgOptOut) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgOptOut) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgOptOut.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgOptOut) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgOptOut.Merge(m, src) +} +func (m *MsgOptOut) XXX_Size() int { + return m.Size() +} +func (m *MsgOptOut) XXX_DiscardUnknown() { + xxx_messageInfo_MsgOptOut.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgOptOut proto.InternalMessageInfo + +type MsgOptOutResponse struct { +} + +func (m *MsgOptOutResponse) Reset() { *m = MsgOptOutResponse{} } +func (m *MsgOptOutResponse) String() string { return proto.CompactTextString(m) } +func (*MsgOptOutResponse) ProtoMessage() {} +func (*MsgOptOutResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{17} +} +func (m *MsgOptOutResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgOptOutResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgOptOutResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgOptOutResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgOptOutResponse.Merge(m, src) +} +func (m *MsgOptOutResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgOptOutResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgOptOutResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgOptOutResponse proto.InternalMessageInfo + +// MsgSetConsumerCommissionRate allows validators to set +// a per-consumer chain commission rate +type MsgSetConsumerCommissionRate struct { + // The validator address on the provider + ProviderAddr string `protobuf:"bytes,1,opt,name=provider_addr,json=providerAddr,proto3" json:"provider_addr,omitempty" yaml:"address"` + // The chain id of the consumer chain to set a commission rate + ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // The rate to charge delegators on the consumer chain, as a fraction + // TODO: migrate rate from sdk.Dec to math.LegacyDec + Rate cosmossdk_io_math.LegacyDec `protobuf:"bytes,3,opt,name=rate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"rate"` +} + +func (m *MsgSetConsumerCommissionRate) Reset() { *m = MsgSetConsumerCommissionRate{} } +func (m *MsgSetConsumerCommissionRate) String() string { return proto.CompactTextString(m) } +func (*MsgSetConsumerCommissionRate) ProtoMessage() {} +func (*MsgSetConsumerCommissionRate) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{18} +} +func (m *MsgSetConsumerCommissionRate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetConsumerCommissionRate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetConsumerCommissionRate.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSetConsumerCommissionRate) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetConsumerCommissionRate.Merge(m, src) +} +func (m *MsgSetConsumerCommissionRate) XXX_Size() int { + return m.Size() +} +func (m *MsgSetConsumerCommissionRate) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetConsumerCommissionRate.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetConsumerCommissionRate proto.InternalMessageInfo + +type MsgSetConsumerCommissionRateResponse struct { +} + +func (m *MsgSetConsumerCommissionRateResponse) Reset() { *m = MsgSetConsumerCommissionRateResponse{} } +func (m *MsgSetConsumerCommissionRateResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSetConsumerCommissionRateResponse) ProtoMessage() {} +func (*MsgSetConsumerCommissionRateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{19} +} +func (m *MsgSetConsumerCommissionRateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetConsumerCommissionRateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetConsumerCommissionRateResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSetConsumerCommissionRateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetConsumerCommissionRateResponse.Merge(m, src) +} +func (m *MsgSetConsumerCommissionRateResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgSetConsumerCommissionRateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetConsumerCommissionRateResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetConsumerCommissionRateResponse proto.InternalMessageInfo + +// MsgConsumerModification message contains a governance proposal on the provider chain to +// modify a running consumer chain. If it passes, the consumer chain's +// parameters are updated. +// +// Note: this replaces ConsumerModificationProposal which is deprecated and will be removed soon +type MsgConsumerModification struct { + // the title of the proposal + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + // the description of the proposal + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + // the chain-id of the consumer chain to be modified + ChainId string `protobuf:"bytes,3,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // Corresponds to the percentage of validators that have to validate the chain under the Top N case. + // For example, 53 corresponds to a Top 53% chain, meaning that the top 53% provider validators by voting power + // have to validate the proposed consumer chain. top_N can either be 0 or any value in [50, 100]. + // A chain can join with top_N == 0 as an Opt In chain, or with top_N ∈ [50, 100] as a Top N chain. + Top_N uint32 `protobuf:"varint,4,opt,name=top_N,json=topN,proto3" json:"top_N,omitempty"` + // Corresponds to the maximum power (percentage-wise) a validator can have on the consumer chain. For instance, if + // `validators_power_cap` is set to 32, it means that no validator can have more than 32% of the voting power on the + // consumer chain. Note that this might not be feasible. For example, think of a consumer chain with only + // 5 validators and with `validators_power_cap` set to 10%. In such a scenario, at least one validator would need + // to have more than 20% of the total voting power. Therefore, `validators_power_cap` operates on a best-effort basis. + ValidatorsPowerCap uint32 `protobuf:"varint,5,opt,name=validators_power_cap,json=validatorsPowerCap,proto3" json:"validators_power_cap,omitempty"` + // Corresponds to the maximum number of validators that can validate a consumer chain. + // Only applicable to Opt In chains. Setting `validator_set_cap` on a Top N chain is a no-op. + ValidatorSetCap uint32 `protobuf:"varint,6,opt,name=validator_set_cap,json=validatorSetCap,proto3" json:"validator_set_cap,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that are the ONLY ones that can validate + // the consumer chain. + Allowlist []string `protobuf:"bytes,7,rep,name=allowlist,proto3" json:"allowlist,omitempty"` + // Corresponds to a list of provider consensus addresses of validators that CANNOT validate the consumer chain. + Denylist []string `protobuf:"bytes,8,rep,name=denylist,proto3" json:"denylist,omitempty"` + // signer address + Authority string `protobuf:"bytes,9,opt,name=authority,proto3" json:"authority,omitempty"` +} + +func (m *MsgConsumerModification) Reset() { *m = MsgConsumerModification{} } +func (m *MsgConsumerModification) String() string { return proto.CompactTextString(m) } +func (*MsgConsumerModification) ProtoMessage() {} +func (*MsgConsumerModification) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{20} +} +func (m *MsgConsumerModification) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgConsumerModification) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgConsumerModification.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgConsumerModification) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgConsumerModification.Merge(m, src) +} +func (m *MsgConsumerModification) XXX_Size() int { + return m.Size() +} +func (m *MsgConsumerModification) XXX_DiscardUnknown() { + xxx_messageInfo_MsgConsumerModification.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgConsumerModification proto.InternalMessageInfo + +func (m *MsgConsumerModification) GetTitle() string { + if m != nil { + return m.Title + } + return "" +} + +func (m *MsgConsumerModification) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *MsgConsumerModification) GetChainId() string { + if m != nil { + return m.ChainId + } + return "" +} + +func (m *MsgConsumerModification) GetTop_N() uint32 { + if m != nil { + return m.Top_N + } + return 0 +} + +func (m *MsgConsumerModification) GetValidatorsPowerCap() uint32 { + if m != nil { + return m.ValidatorsPowerCap + } + return 0 +} + +func (m *MsgConsumerModification) GetValidatorSetCap() uint32 { + if m != nil { + return m.ValidatorSetCap + } + return 0 +} + +func (m *MsgConsumerModification) GetAllowlist() []string { + if m != nil { + return m.Allowlist + } + return nil +} + +func (m *MsgConsumerModification) GetDenylist() []string { + if m != nil { + return m.Denylist + } + return nil +} + +func (m *MsgConsumerModification) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +type MsgConsumerModificationResponse struct { +} + +func (m *MsgConsumerModificationResponse) Reset() { *m = MsgConsumerModificationResponse{} } +func (m *MsgConsumerModificationResponse) String() string { return proto.CompactTextString(m) } +func (*MsgConsumerModificationResponse) ProtoMessage() {} +func (*MsgConsumerModificationResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{21} +} +func (m *MsgConsumerModificationResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgConsumerModificationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgConsumerModificationResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgConsumerModificationResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgConsumerModificationResponse.Merge(m, src) +} +func (m *MsgConsumerModificationResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgConsumerModificationResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgConsumerModificationResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgConsumerModificationResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgAssignConsumerKey)(nil), "interchain_security.ccv.provider.v1.MsgAssignConsumerKey") proto.RegisterType((*MsgAssignConsumerKeyResponse)(nil), "interchain_security.ccv.provider.v1.MsgAssignConsumerKeyResponse") @@ -816,6 +1280,14 @@ func init() { proto.RegisterType((*MsgConsumerRemovalResponse)(nil), "interchain_security.ccv.provider.v1.MsgConsumerRemovalResponse") proto.RegisterType((*MsgChangeRewardDenoms)(nil), "interchain_security.ccv.provider.v1.MsgChangeRewardDenoms") proto.RegisterType((*MsgChangeRewardDenomsResponse)(nil), "interchain_security.ccv.provider.v1.MsgChangeRewardDenomsResponse") + proto.RegisterType((*MsgOptIn)(nil), "interchain_security.ccv.provider.v1.MsgOptIn") + proto.RegisterType((*MsgOptInResponse)(nil), "interchain_security.ccv.provider.v1.MsgOptInResponse") + proto.RegisterType((*MsgOptOut)(nil), "interchain_security.ccv.provider.v1.MsgOptOut") + proto.RegisterType((*MsgOptOutResponse)(nil), "interchain_security.ccv.provider.v1.MsgOptOutResponse") + proto.RegisterType((*MsgSetConsumerCommissionRate)(nil), "interchain_security.ccv.provider.v1.MsgSetConsumerCommissionRate") + proto.RegisterType((*MsgSetConsumerCommissionRateResponse)(nil), "interchain_security.ccv.provider.v1.MsgSetConsumerCommissionRateResponse") + proto.RegisterType((*MsgConsumerModification)(nil), "interchain_security.ccv.provider.v1.MsgConsumerModification") + proto.RegisterType((*MsgConsumerModificationResponse)(nil), "interchain_security.ccv.provider.v1.MsgConsumerModificationResponse") } func init() { @@ -823,89 +1295,113 @@ func init() { } var fileDescriptor_43221a4391e9fbf4 = []byte{ - // 1305 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcf, 0x8f, 0x14, 0xc5, - 0x17, 0xdf, 0x66, 0x61, 0xd9, 0xad, 0xfd, 0xc1, 0xd2, 0xb0, 0xdf, 0x9d, 0x9d, 0x2f, 0xcc, 0x2c, - 0xe3, 0x0f, 0x08, 0x42, 0xb7, 0xac, 0x3f, 0xd0, 0x8d, 0x46, 0x67, 0x59, 0x14, 0x30, 0xab, 0x6b, - 0xb3, 0x62, 0xa2, 0x89, 0x9d, 0x9a, 0xee, 0xa2, 0xbb, 0xc2, 0x74, 0xd5, 0xa4, 0xaa, 0xba, 0x61, - 0x6e, 0x86, 0x93, 0x89, 0x89, 0xc1, 0x9b, 0x47, 0x62, 0x3c, 0x6a, 0xc2, 0xc1, 0x93, 0x37, 0x6f, - 0x1c, 0x89, 0xf1, 0xe0, 0x09, 0x09, 0x1c, 0xf0, 0xec, 0x5f, 0x60, 0xea, 0x47, 0xf7, 0xf4, 0xec, - 0x0e, 0xcb, 0x30, 0x7a, 0x99, 0x74, 0xd7, 0xfb, 0xbc, 0xcf, 0xfb, 0xbc, 0xd7, 0xf5, 0x5e, 0xd5, - 0x80, 0x53, 0x98, 0x08, 0xc4, 0x82, 0x18, 0x62, 0xe2, 0x73, 0x14, 0xa4, 0x0c, 0x8b, 0xae, 0x1b, - 0x04, 0x99, 0xdb, 0x61, 0x34, 0xc3, 0x21, 0x62, 0x6e, 0x76, 0xc6, 0x15, 0x37, 0x9c, 0x0e, 0xa3, - 0x82, 0xda, 0xcf, 0x0d, 0x40, 0x3b, 0x41, 0x90, 0x39, 0x39, 0xda, 0xc9, 0xce, 0x54, 0x0f, 0xc2, - 0x04, 0x13, 0xea, 0xaa, 0x5f, 0xed, 0x57, 0x3d, 0x12, 0x51, 0x1a, 0xb5, 0x91, 0x0b, 0x3b, 0xd8, - 0x85, 0x84, 0x50, 0x01, 0x05, 0xa6, 0x84, 0x1b, 0x6b, 0xdd, 0x58, 0xd5, 0x5b, 0x2b, 0xbd, 0xea, - 0x0a, 0x9c, 0x20, 0x2e, 0x60, 0xd2, 0x31, 0x80, 0xda, 0x76, 0x40, 0x98, 0x32, 0xc5, 0x60, 0xec, - 0x4b, 0xdb, 0xed, 0x90, 0x74, 0x8d, 0xe9, 0x70, 0x44, 0x23, 0xaa, 0x1e, 0x5d, 0xf9, 0x94, 0x3b, - 0x04, 0x94, 0x27, 0x94, 0xfb, 0xda, 0xa0, 0x5f, 0x8c, 0x69, 0x51, 0xbf, 0xb9, 0x09, 0x8f, 0x64, - 0xea, 0x09, 0x8f, 0x72, 0x95, 0xb8, 0x15, 0xb8, 0x01, 0x65, 0xc8, 0x0d, 0xda, 0x18, 0x11, 0x21, - 0xad, 0xfa, 0xc9, 0x00, 0x56, 0x86, 0x29, 0x65, 0x51, 0x28, 0xed, 0xe3, 0x4a, 0xd2, 0x36, 0x8e, - 0x62, 0xa1, 0xa9, 0xb8, 0x2b, 0x10, 0x09, 0x11, 0x4b, 0xb0, 0x0e, 0xd0, 0x7b, 0xcb, 0x55, 0x94, - 0xec, 0xa2, 0xdb, 0x41, 0xdc, 0x45, 0x92, 0x8f, 0x04, 0x48, 0x03, 0x1a, 0xbf, 0x5b, 0xe0, 0xf0, - 0x06, 0x8f, 0x9a, 0x9c, 0xe3, 0x88, 0x9c, 0xa3, 0x84, 0xa7, 0x09, 0x62, 0x1f, 0xa0, 0xae, 0xbd, - 0x04, 0x26, 0xb5, 0x36, 0x1c, 0x56, 0xac, 0x65, 0xeb, 0xc4, 0x94, 0xb7, 0x5f, 0xbd, 0x5f, 0x0c, - 0xed, 0xb3, 0x60, 0x36, 0xd7, 0xe5, 0xc3, 0x30, 0x64, 0x95, 0x3d, 0xd2, 0xbe, 0x66, 0xff, 0x7d, - 0xbf, 0x3e, 0xd7, 0x85, 0x49, 0x7b, 0xb5, 0x21, 0x57, 0x11, 0xe7, 0x0d, 0x6f, 0x26, 0x07, 0x36, - 0xc3, 0x90, 0xd9, 0xc7, 0xc0, 0x4c, 0x60, 0x42, 0xf8, 0xd7, 0x50, 0xb7, 0x32, 0xae, 0x78, 0xa7, - 0x83, 0x52, 0xd8, 0x97, 0xc1, 0x84, 0x54, 0x82, 0x58, 0x65, 0xaf, 0x22, 0xad, 0xfc, 0xf6, 0xf3, - 0xe9, 0xc3, 0xa6, 0xe2, 0x4d, 0xcd, 0x7a, 0x59, 0x30, 0x4c, 0x22, 0xcf, 0xe0, 0x56, 0x0f, 0x7d, - 0x75, 0xbb, 0x3e, 0xf6, 0xd7, 0xed, 0xfa, 0xd8, 0xcd, 0xc7, 0x77, 0x4e, 0x9a, 0xc5, 0x46, 0x0d, - 0x1c, 0x19, 0x94, 0x95, 0x87, 0x78, 0x87, 0x12, 0x8e, 0x1a, 0xbf, 0x5a, 0xe0, 0xe8, 0x06, 0x8f, - 0x2e, 0xa7, 0xad, 0x04, 0x8b, 0x1c, 0xb0, 0x81, 0x79, 0x0b, 0xc5, 0x30, 0xc3, 0x34, 0x65, 0xf6, - 0xeb, 0x60, 0x8a, 0x2b, 0xab, 0x40, 0x4c, 0x17, 0x60, 0x17, 0x2d, 0x3d, 0xa8, 0xbd, 0x09, 0x66, - 0x92, 0x12, 0x8f, 0xaa, 0xcd, 0xf4, 0xca, 0x29, 0x07, 0xb7, 0x02, 0xa7, 0xfc, 0xe5, 0x9c, 0xd2, - 0xb7, 0xca, 0xce, 0x38, 0xe5, 0xd8, 0x5e, 0x1f, 0xc3, 0xea, 0xff, 0xca, 0x09, 0xf6, 0x22, 0x35, - 0x8e, 0x83, 0x17, 0x76, 0x4d, 0xa1, 0x48, 0xf6, 0xce, 0x9e, 0x01, 0xc9, 0xae, 0xd3, 0xb4, 0xd5, - 0x46, 0x57, 0xa8, 0xc0, 0x24, 0x1a, 0x39, 0x59, 0x1f, 0x2c, 0x86, 0x69, 0xa7, 0x8d, 0x03, 0x28, - 0x90, 0x9f, 0x51, 0x81, 0xfc, 0x7c, 0x7b, 0x99, 0xbc, 0x8f, 0x97, 0xd3, 0x54, 0x1b, 0xd0, 0x59, - 0xcf, 0x1d, 0xae, 0x50, 0x81, 0xce, 0x1b, 0xb8, 0xb7, 0x10, 0x0e, 0x5a, 0xb6, 0xbf, 0x00, 0x8b, - 0x98, 0x5c, 0x65, 0x30, 0x90, 0xed, 0xeb, 0xb7, 0xda, 0x34, 0xb8, 0xe6, 0xc7, 0x08, 0x86, 0x88, - 0xa9, 0xcd, 0x33, 0xbd, 0xf2, 0xe2, 0xd3, 0x0a, 0x7b, 0x41, 0xa1, 0xbd, 0x85, 0x1e, 0xcd, 0x9a, - 0x64, 0xd1, 0xcb, 0xcf, 0x54, 0xdb, 0x72, 0xc5, 0x8a, 0xda, 0xfe, 0x60, 0x81, 0x03, 0x1b, 0x3c, - 0xfa, 0xa4, 0x13, 0x42, 0x81, 0x36, 0x21, 0x83, 0x09, 0x97, 0xd5, 0x84, 0xa9, 0x88, 0xa9, 0xec, - 0xe8, 0xa7, 0x57, 0xb3, 0x80, 0xda, 0x17, 0xc1, 0x44, 0x47, 0x31, 0x98, 0xe2, 0xbd, 0xe4, 0x0c, - 0x31, 0x3f, 0x1d, 0x1d, 0x74, 0x6d, 0xef, 0xdd, 0xfb, 0xf5, 0x31, 0xcf, 0x10, 0xac, 0xce, 0xa9, - 0x7c, 0x0a, 0xea, 0xc6, 0x12, 0x58, 0xdc, 0xa6, 0xb2, 0xc8, 0xe0, 0xc1, 0x04, 0x38, 0xb4, 0xc1, - 0xa3, 0x3c, 0xcb, 0x66, 0x18, 0x62, 0x59, 0xa5, 0xdd, 0x06, 0xc0, 0xfb, 0x60, 0x0e, 0x13, 0x2c, - 0x30, 0x6c, 0xfb, 0x31, 0x92, 0xa5, 0x37, 0x82, 0xab, 0xea, 0x63, 0xc8, 0xa1, 0xe7, 0x98, 0x51, - 0xa7, 0x3e, 0x80, 0x44, 0x18, 0x7d, 0xb3, 0xc6, 0x4f, 0x2f, 0xca, 0x81, 0x10, 0x21, 0x82, 0x38, - 0xe6, 0x7e, 0x0c, 0x79, 0xac, 0xbe, 0xe9, 0x8c, 0x37, 0x6d, 0xd6, 0x2e, 0x40, 0x1e, 0xdb, 0x75, - 0x30, 0xdd, 0xc2, 0x04, 0xb2, 0xae, 0x46, 0xec, 0x55, 0x08, 0xa0, 0x97, 0x14, 0xe0, 0x1c, 0x00, - 0xbc, 0x03, 0xaf, 0x13, 0x5f, 0x1e, 0x03, 0x95, 0x7d, 0x46, 0x88, 0x1e, 0xf1, 0x4e, 0x3e, 0xe2, - 0x9d, 0xad, 0xfc, 0x8c, 0x58, 0x9b, 0x94, 0x42, 0x6e, 0xfd, 0x59, 0xb7, 0xbc, 0x29, 0xe5, 0x27, - 0x2d, 0xf6, 0x87, 0x60, 0x3e, 0x25, 0x2d, 0x4a, 0x42, 0x4c, 0x22, 0xbf, 0x83, 0x18, 0xa6, 0x61, - 0x65, 0x42, 0x51, 0x2d, 0xed, 0xa0, 0x5a, 0x37, 0xa7, 0x89, 0x66, 0xfa, 0x4e, 0x32, 0x1d, 0x28, - 0x9c, 0x37, 0x95, 0xaf, 0xfd, 0x31, 0xb0, 0x83, 0x20, 0x53, 0x92, 0x68, 0x2a, 0x72, 0xc6, 0xfd, - 0xc3, 0x33, 0xce, 0x07, 0x41, 0xb6, 0xa5, 0xbd, 0x0d, 0xe5, 0xe7, 0x60, 0x51, 0x30, 0x48, 0xf8, - 0x55, 0xc4, 0xb6, 0xf3, 0x4e, 0x0e, 0xcf, 0xbb, 0x90, 0x73, 0xf4, 0x93, 0x5f, 0x00, 0xcb, 0xc5, - 0x64, 0x66, 0x28, 0xc4, 0x5c, 0x30, 0xdc, 0x4a, 0x55, 0xd3, 0xe5, 0x6d, 0x53, 0x99, 0x52, 0x9b, - 0xa0, 0x96, 0xe3, 0xbc, 0x3e, 0xd8, 0x7b, 0x06, 0x65, 0x7f, 0x04, 0x9e, 0x57, 0x6d, 0xca, 0xa5, - 0x38, 0xbf, 0x8f, 0x49, 0x85, 0x4e, 0x30, 0xe7, 0x92, 0x0d, 0x2c, 0x5b, 0x27, 0xc6, 0xbd, 0x63, - 0x1a, 0xbb, 0x89, 0xd8, 0x7a, 0x09, 0xb9, 0x55, 0x02, 0xda, 0xa7, 0x81, 0x1d, 0x63, 0x2e, 0x28, - 0xc3, 0x01, 0x6c, 0xfb, 0x88, 0x08, 0x86, 0x11, 0xaf, 0x4c, 0x2b, 0xf7, 0x83, 0x3d, 0xcb, 0x79, - 0x6d, 0xb0, 0x2f, 0x81, 0x63, 0x4f, 0x0c, 0xea, 0x07, 0x31, 0x24, 0x04, 0xb5, 0x2b, 0x33, 0x2a, - 0x95, 0x7a, 0xf8, 0x84, 0x98, 0xe7, 0x34, 0xac, 0xbf, 0x91, 0x67, 0x87, 0x6e, 0xe4, 0x1d, 0xdd, - 0x77, 0x14, 0xfc, 0x7f, 0x40, 0x87, 0x15, 0x1d, 0xf8, 0x8b, 0x05, 0xec, 0x92, 0xdd, 0x43, 0x09, - 0xcd, 0x60, 0x7b, 0xb7, 0x06, 0x6c, 0x82, 0x29, 0x2e, 0x68, 0x47, 0x6f, 0xf9, 0x3d, 0xcf, 0xb0, - 0xe5, 0x27, 0xa5, 0x9b, 0xda, 0xf1, 0x7d, 0xb9, 0x8d, 0x8f, 0x9e, 0xdb, 0x11, 0x50, 0xdd, 0xa9, - 0xbd, 0x48, 0xed, 0x27, 0x0b, 0x2c, 0x48, 0x73, 0x0c, 0x49, 0x84, 0x3c, 0x74, 0x1d, 0xb2, 0x70, - 0x1d, 0x11, 0x9a, 0x70, 0xbb, 0x01, 0x66, 0x43, 0xf5, 0xe4, 0x0b, 0x2a, 0x6f, 0x11, 0x15, 0x6b, - 0x79, 0x5c, 0x5e, 0x06, 0xf4, 0xe2, 0x16, 0x6d, 0x86, 0xa1, 0x7d, 0x02, 0xcc, 0xf7, 0x30, 0x4c, - 0x52, 0xcb, 0x6c, 0x25, 0x6c, 0x2e, 0x87, 0xa9, 0x80, 0xff, 0x5d, 0x36, 0x75, 0x75, 0x52, 0xee, - 0x94, 0x9b, 0x27, 0xb4, 0xf2, 0xfd, 0x7e, 0x30, 0xbe, 0xc1, 0x23, 0xfb, 0x5b, 0x0b, 0x1c, 0xdc, - 0x79, 0x69, 0x7a, 0x73, 0xa8, 0x89, 0x3d, 0xe8, 0x66, 0x52, 0x6d, 0x8e, 0xec, 0x9a, 0x6b, 0xb3, - 0x7f, 0xb4, 0x40, 0x75, 0x97, 0x1b, 0xcd, 0xda, 0xb0, 0x11, 0x9e, 0xcc, 0x51, 0xbd, 0xf4, 0xef, - 0x39, 0x76, 0x91, 0xdb, 0x77, 0x27, 0x19, 0x51, 0x6e, 0x99, 0x63, 0x54, 0xb9, 0x83, 0x4e, 0x7a, - 0xfb, 0x1b, 0x0b, 0xcc, 0xef, 0x38, 0x24, 0xdf, 0x18, 0x36, 0xc0, 0x76, 0xcf, 0xea, 0xbb, 0xa3, - 0x7a, 0x16, 0x82, 0xbe, 0xb6, 0xc0, 0x81, 0xed, 0x33, 0xe3, 0xec, 0xb3, 0xb2, 0x1a, 0xc7, 0xea, - 0x3b, 0x23, 0x3a, 0x16, 0x6a, 0x6e, 0x5a, 0x60, 0xa6, 0xef, 0x16, 0xf4, 0xea, 0xb0, 0x8c, 0x65, - 0xaf, 0xea, 0x5b, 0xa3, 0x78, 0xe5, 0x22, 0xaa, 0xfb, 0xbe, 0x7c, 0x7c, 0xe7, 0xa4, 0xb5, 0xf6, - 0xe9, 0xdd, 0x87, 0x35, 0xeb, 0xde, 0xc3, 0x9a, 0xf5, 0xe0, 0x61, 0xcd, 0xba, 0xf5, 0xa8, 0x36, - 0x76, 0xef, 0x51, 0x6d, 0xec, 0x8f, 0x47, 0xb5, 0xb1, 0xcf, 0xde, 0x8e, 0xb0, 0x88, 0xd3, 0x96, - 0x13, 0xd0, 0xc4, 0xfc, 0x8f, 0x73, 0x7b, 0xf1, 0x4e, 0x17, 0x7f, 0xc3, 0xb2, 0xd7, 0xdc, 0x1b, - 0xfd, 0xff, 0xc5, 0xd4, 0xdd, 0xb5, 0x35, 0xa1, 0x86, 0xeb, 0x2b, 0xff, 0x04, 0x00, 0x00, 0xff, - 0xff, 0x3a, 0xa6, 0xa7, 0xc0, 0x07, 0x0f, 0x00, 0x00, + // 1689 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x58, 0xcf, 0x6f, 0xe4, 0x48, + 0x15, 0x8e, 0xf3, 0x6b, 0xba, 0xab, 0xf3, 0xd3, 0x93, 0x90, 0x8e, 0x37, 0xdb, 0x9d, 0x34, 0xcb, + 0x6e, 0x34, 0x6c, 0xec, 0x9d, 0xc0, 0xce, 0x42, 0xb4, 0x08, 0x92, 0xf4, 0xc2, 0x64, 0x20, 0x93, + 0xe0, 0x09, 0x8b, 0x04, 0x12, 0x56, 0xb5, 0x5d, 0x71, 0x97, 0xc6, 0x76, 0x59, 0x55, 0xd5, 0x9d, + 0xed, 0x1b, 0xda, 0x13, 0x12, 0x02, 0x2d, 0x37, 0xc4, 0x69, 0x0f, 0x08, 0x81, 0x04, 0xd2, 0x1c, + 0xf6, 0xc4, 0x8d, 0xdb, 0x1c, 0x38, 0x2c, 0x2b, 0x0e, 0x88, 0xc3, 0x80, 0x66, 0x0e, 0xcb, 0x99, + 0xbf, 0x00, 0x55, 0xb9, 0xec, 0x76, 0x27, 0x9d, 0xde, 0xee, 0x0e, 0x1c, 0xb8, 0xb4, 0xda, 0xf5, + 0xbe, 0xf7, 0xd5, 0xf7, 0x3d, 0xbb, 0x5e, 0x95, 0x0d, 0x5e, 0xc7, 0x11, 0x47, 0xd4, 0x6d, 0x42, + 0x1c, 0x39, 0x0c, 0xb9, 0x2d, 0x8a, 0x79, 0xc7, 0x72, 0xdd, 0xb6, 0x15, 0x53, 0xd2, 0xc6, 0x1e, + 0xa2, 0x56, 0xfb, 0xae, 0xc5, 0xdf, 0x33, 0x63, 0x4a, 0x38, 0xd1, 0x3f, 0xdf, 0x07, 0x6d, 0xba, + 0x6e, 0xdb, 0x4c, 0xd1, 0x66, 0xfb, 0xae, 0xb1, 0x0c, 0x43, 0x1c, 0x11, 0x4b, 0xfe, 0x26, 0x79, + 0xc6, 0x86, 0x4f, 0x88, 0x1f, 0x20, 0x0b, 0xc6, 0xd8, 0x82, 0x51, 0x44, 0x38, 0xe4, 0x98, 0x44, + 0x4c, 0x45, 0xab, 0x2a, 0x2a, 0xaf, 0x1a, 0xad, 0x73, 0x8b, 0xe3, 0x10, 0x31, 0x0e, 0xc3, 0x58, + 0x01, 0x2a, 0x97, 0x01, 0x5e, 0x8b, 0x4a, 0x06, 0x15, 0x5f, 0xbf, 0x1c, 0x87, 0x51, 0x47, 0x85, + 0x56, 0x7c, 0xe2, 0x13, 0xf9, 0xd7, 0x12, 0xff, 0xd2, 0x04, 0x97, 0xb0, 0x90, 0x30, 0x27, 0x09, + 0x24, 0x17, 0x2a, 0xb4, 0x96, 0x5c, 0x59, 0x21, 0xf3, 0x85, 0xf5, 0x90, 0xf9, 0xa9, 0x4a, 0xdc, + 0x70, 0x2d, 0x97, 0x50, 0x64, 0xb9, 0x01, 0x46, 0x11, 0x17, 0xd1, 0xe4, 0x9f, 0x02, 0xec, 0x0e, + 0x53, 0xca, 0xac, 0x50, 0x49, 0x8e, 0x25, 0x48, 0x03, 0xec, 0x37, 0x79, 0x42, 0xc5, 0x2c, 0x8e, + 0x22, 0x0f, 0xd1, 0x10, 0x27, 0x13, 0x74, 0xaf, 0x52, 0x15, 0xb9, 0x38, 0xef, 0xc4, 0x88, 0x59, + 0x48, 0xf0, 0x45, 0x2e, 0x4a, 0x00, 0xb5, 0xbf, 0x6a, 0x60, 0xe5, 0x98, 0xf9, 0xfb, 0x8c, 0x61, + 0x3f, 0x3a, 0x24, 0x11, 0x6b, 0x85, 0x88, 0x7e, 0x1b, 0x75, 0xf4, 0x75, 0x50, 0x48, 0xb4, 0x61, + 0xaf, 0xac, 0x6d, 0x6a, 0xdb, 0x45, 0xfb, 0x96, 0xbc, 0x3e, 0xf2, 0xf4, 0xb7, 0xc0, 0x7c, 0xaa, + 0xcb, 0x81, 0x9e, 0x47, 0xcb, 0x93, 0x22, 0x7e, 0xa0, 0xff, 0xfb, 0x59, 0x75, 0xa1, 0x03, 0xc3, + 0x60, 0xaf, 0x26, 0x46, 0x11, 0x63, 0x35, 0x7b, 0x2e, 0x05, 0xee, 0x7b, 0x1e, 0xd5, 0xb7, 0xc0, + 0x9c, 0xab, 0xa6, 0x70, 0x1e, 0xa3, 0x4e, 0x79, 0x4a, 0xf2, 0x96, 0xdc, 0xdc, 0xb4, 0x6f, 0x80, + 0x59, 0xa1, 0x04, 0xd1, 0xf2, 0xb4, 0x24, 0x2d, 0x7f, 0xf2, 0xd1, 0xce, 0x8a, 0xaa, 0xf8, 0x7e, + 0xc2, 0xfa, 0x88, 0x53, 0x1c, 0xf9, 0xb6, 0xc2, 0xed, 0xdd, 0xfe, 0xc9, 0x87, 0xd5, 0x89, 0x7f, + 0x7d, 0x58, 0x9d, 0x78, 0xff, 0xd3, 0x27, 0x77, 0xd4, 0x60, 0xad, 0x02, 0x36, 0xfa, 0xb9, 0xb2, + 0x11, 0x8b, 0x49, 0xc4, 0x50, 0xed, 0x4f, 0x1a, 0x78, 0xf9, 0x98, 0xf9, 0x8f, 0x5a, 0x8d, 0x10, + 0xf3, 0x14, 0x70, 0x8c, 0x59, 0x03, 0x35, 0x61, 0x1b, 0x93, 0x16, 0xd5, 0xef, 0x81, 0x22, 0x93, + 0x51, 0x8e, 0x68, 0x52, 0x80, 0x01, 0x5a, 0xba, 0x50, 0xfd, 0x14, 0xcc, 0x85, 0x39, 0x1e, 0x59, + 0x9b, 0xd2, 0xee, 0xeb, 0x26, 0x6e, 0xb8, 0x66, 0xfe, 0xce, 0x99, 0xb9, 0x7b, 0xd5, 0xbe, 0x6b, + 0xe6, 0xe7, 0xb6, 0x7b, 0x18, 0xf6, 0x3e, 0x97, 0x37, 0xd8, 0x9d, 0xa9, 0xf6, 0x1a, 0xf8, 0xc2, + 0x40, 0x0b, 0x99, 0xd9, 0x27, 0x93, 0x7d, 0xcc, 0xd6, 0x49, 0xab, 0x11, 0xa0, 0x77, 0x09, 0xc7, + 0x91, 0x3f, 0xb6, 0x59, 0x07, 0xac, 0x79, 0xad, 0x38, 0xc0, 0x2e, 0xe4, 0xc8, 0x69, 0x13, 0x8e, + 0x9c, 0xf4, 0xf1, 0x52, 0xbe, 0x5f, 0xcb, 0xdb, 0x94, 0x0f, 0xa0, 0x59, 0x4f, 0x13, 0xde, 0x25, + 0x1c, 0xbd, 0xa3, 0xe0, 0xf6, 0xaa, 0xd7, 0x6f, 0x58, 0xff, 0x11, 0x58, 0xc3, 0xd1, 0x39, 0x85, + 0xae, 0x58, 0xbe, 0x4e, 0x23, 0x20, 0xee, 0x63, 0xa7, 0x89, 0xa0, 0x87, 0xa8, 0x7c, 0x78, 0x4a, + 0xbb, 0xaf, 0x7e, 0x56, 0x61, 0xef, 0x4b, 0xb4, 0xbd, 0xda, 0xa5, 0x39, 0x10, 0x2c, 0xc9, 0xf0, + 0x48, 0xb5, 0xcd, 0x57, 0x2c, 0xab, 0xed, 0xaf, 0x35, 0xb0, 0x78, 0xcc, 0xfc, 0xef, 0xc5, 0x1e, + 0xe4, 0xe8, 0x14, 0x52, 0x18, 0x32, 0x51, 0x4d, 0xd8, 0xe2, 0x4d, 0x22, 0x56, 0xf4, 0x67, 0x57, + 0x33, 0x83, 0xea, 0x47, 0x60, 0x36, 0x96, 0x0c, 0xaa, 0x78, 0x5f, 0x34, 0x87, 0xe8, 0x9f, 0x66, + 0x32, 0xe9, 0xc1, 0xf4, 0xd3, 0x67, 0xd5, 0x09, 0x5b, 0x11, 0xec, 0x2d, 0x48, 0x3f, 0x19, 0x75, + 0x6d, 0x1d, 0xac, 0x5d, 0x52, 0x99, 0x39, 0xf8, 0x59, 0x01, 0xdc, 0x3e, 0x66, 0x7e, 0xea, 0x72, + 0xdf, 0xf3, 0xb0, 0xa8, 0xd2, 0xa0, 0x06, 0xf0, 0x2d, 0xb0, 0x80, 0x23, 0xcc, 0x31, 0x0c, 0x9c, + 0x26, 0x12, 0xa5, 0x57, 0x82, 0x0d, 0x79, 0x33, 0x44, 0xd3, 0x33, 0x55, 0xab, 0x93, 0x37, 0x40, + 0x20, 0x94, 0xbe, 0x79, 0x95, 0x97, 0x0c, 0x8a, 0x86, 0xe0, 0xa3, 0x08, 0x31, 0xcc, 0x9c, 0x26, + 0x64, 0x4d, 0x79, 0x4f, 0xe7, 0xec, 0x92, 0x1a, 0xbb, 0x0f, 0x59, 0x53, 0xaf, 0x82, 0x52, 0x03, + 0x47, 0x90, 0x76, 0x12, 0xc4, 0xb4, 0x44, 0x80, 0x64, 0x48, 0x02, 0x0e, 0x01, 0x60, 0x31, 0xbc, + 0x88, 0x1c, 0xb1, 0x0d, 0x94, 0x67, 0x94, 0x90, 0xa4, 0xc5, 0x9b, 0x69, 0x8b, 0x37, 0xcf, 0xd2, + 0x3d, 0xe2, 0xa0, 0x20, 0x84, 0x7c, 0xf0, 0x8f, 0xaa, 0x66, 0x17, 0x65, 0x9e, 0x88, 0xe8, 0x0f, + 0xc1, 0x52, 0x2b, 0x6a, 0x90, 0xc8, 0xc3, 0x91, 0xef, 0xc4, 0x88, 0x62, 0xe2, 0x95, 0x67, 0x25, + 0xd5, 0xfa, 0x15, 0xaa, 0xba, 0xda, 0x4d, 0x12, 0xa6, 0x5f, 0x0a, 0xa6, 0xc5, 0x2c, 0xf9, 0x54, + 0xe6, 0xea, 0xdf, 0x05, 0xba, 0xeb, 0xb6, 0xa5, 0x24, 0xd2, 0xe2, 0x29, 0xe3, 0xad, 0xe1, 0x19, + 0x97, 0x5c, 0xb7, 0x7d, 0x96, 0x64, 0x2b, 0xca, 0x1f, 0x82, 0x35, 0x4e, 0x61, 0xc4, 0xce, 0x11, + 0xbd, 0xcc, 0x5b, 0x18, 0x9e, 0x77, 0x35, 0xe5, 0xe8, 0x25, 0xbf, 0x0f, 0x36, 0xb3, 0xce, 0x4c, + 0x91, 0x87, 0x19, 0xa7, 0xb8, 0xd1, 0x92, 0x8b, 0x2e, 0x5d, 0x36, 0xe5, 0xa2, 0x7c, 0x08, 0x2a, + 0x29, 0xce, 0xee, 0x81, 0x7d, 0x53, 0xa1, 0xf4, 0x13, 0xf0, 0x8a, 0x5c, 0xa6, 0x4c, 0x88, 0x73, + 0x7a, 0x98, 0xe4, 0xd4, 0x21, 0x66, 0x4c, 0xb0, 0x81, 0x4d, 0x6d, 0x7b, 0xca, 0xde, 0x4a, 0xb0, + 0xa7, 0x88, 0xd6, 0x73, 0xc8, 0xb3, 0x1c, 0x50, 0xdf, 0x01, 0x7a, 0x13, 0x33, 0x4e, 0x28, 0x76, + 0x61, 0xe0, 0xa0, 0x88, 0x53, 0x8c, 0x58, 0xb9, 0x24, 0xd3, 0x97, 0xbb, 0x91, 0x77, 0x92, 0x80, + 0xfe, 0x00, 0x6c, 0x5d, 0x3b, 0xa9, 0xe3, 0x36, 0x61, 0x14, 0xa1, 0xa0, 0x3c, 0x27, 0xad, 0x54, + 0xbd, 0x6b, 0xe6, 0x3c, 0x4c, 0x60, 0xfa, 0x6d, 0x30, 0xc3, 0x49, 0xec, 0x3c, 0x2c, 0xcf, 0x6f, + 0x6a, 0xdb, 0xf3, 0xf6, 0x34, 0x27, 0xf1, 0x43, 0xfd, 0x0d, 0xb0, 0xd2, 0x86, 0x01, 0xf6, 0x20, + 0x27, 0x94, 0x39, 0x31, 0xb9, 0x40, 0xd4, 0x71, 0x61, 0x5c, 0x5e, 0x90, 0x18, 0xbd, 0x1b, 0x3b, + 0x15, 0xa1, 0x43, 0x18, 0xeb, 0x77, 0xc0, 0x72, 0x36, 0xea, 0x30, 0xc4, 0x25, 0x7c, 0x51, 0xc2, + 0x17, 0xb3, 0xc0, 0x23, 0xc4, 0x05, 0x76, 0x03, 0x14, 0x61, 0x10, 0x90, 0x8b, 0x00, 0x33, 0x5e, + 0x5e, 0xda, 0x9c, 0xda, 0x2e, 0xda, 0xdd, 0x01, 0xdd, 0x00, 0x05, 0x0f, 0x45, 0x1d, 0x19, 0x5c, + 0x96, 0xc1, 0xec, 0xba, 0xb7, 0xeb, 0xe8, 0x43, 0x77, 0x9d, 0x2b, 0xad, 0xe2, 0x65, 0xf0, 0x52, + 0x9f, 0x76, 0x90, 0xb5, 0x8b, 0x3f, 0x6a, 0x40, 0xcf, 0xc5, 0x6d, 0x14, 0x92, 0x36, 0x0c, 0x06, + 0x75, 0x8b, 0x7d, 0x50, 0x64, 0xa2, 0x8c, 0x72, 0x7d, 0x4e, 0x8e, 0xb0, 0x3e, 0x0b, 0x22, 0x4d, + 0x2e, 0xcf, 0x1e, 0x6f, 0x53, 0xe3, 0x7b, 0xdb, 0x00, 0xc6, 0x55, 0xed, 0x99, 0xb5, 0x3f, 0x68, + 0x60, 0x55, 0x84, 0x9b, 0x30, 0xf2, 0x91, 0x8d, 0x2e, 0x20, 0xf5, 0xea, 0x28, 0x22, 0x21, 0xd3, + 0x6b, 0x60, 0xde, 0x93, 0xff, 0x1c, 0x4e, 0xc4, 0x91, 0xa7, 0xac, 0xc9, 0xe2, 0x97, 0x92, 0xc1, + 0x33, 0xb2, 0xef, 0x79, 0xfa, 0x36, 0x58, 0xea, 0x62, 0xa8, 0xa0, 0x16, 0x6e, 0x05, 0x6c, 0x21, + 0x85, 0xc9, 0x09, 0xff, 0x7b, 0x6e, 0xaa, 0x72, 0x5b, 0xbf, 0x2a, 0x37, 0x33, 0xf4, 0x54, 0x03, + 0x85, 0x63, 0xe6, 0x9f, 0xc4, 0xfc, 0x28, 0xfa, 0x3f, 0x3f, 0xd0, 0xe9, 0x60, 0x29, 0x75, 0x92, + 0xd9, 0xfb, 0x8d, 0x06, 0x8a, 0xc9, 0xe0, 0x49, 0x8b, 0xff, 0x4f, 0xfc, 0x75, 0xc5, 0x4f, 0xdd, + 0x44, 0xfc, 0x6d, 0xb0, 0x9c, 0xe9, 0xcc, 0xdf, 0x1c, 0x71, 0x46, 0x15, 0xeb, 0x5e, 0x95, 0xeb, + 0x90, 0x84, 0xaa, 0x01, 0xd9, 0x90, 0xa3, 0xab, 0xaa, 0xb5, 0x21, 0x55, 0xe7, 0x2b, 0x31, 0xd9, + 0x5b, 0x89, 0x07, 0x60, 0x9a, 0x42, 0x8e, 0x94, 0x9d, 0x7b, 0x62, 0xa9, 0xfd, 0xfd, 0x59, 0xf5, + 0xa5, 0xc4, 0x12, 0xf3, 0x1e, 0x9b, 0x98, 0x58, 0x21, 0xe4, 0x4d, 0xf3, 0x3b, 0xc8, 0x87, 0x6e, + 0xa7, 0x8e, 0xdc, 0x4f, 0x3e, 0xda, 0x01, 0xca, 0x71, 0x1d, 0xb9, 0xbf, 0xfd, 0xf4, 0xc9, 0x1d, + 0xcd, 0x96, 0x1c, 0x7b, 0x85, 0xd4, 0x6a, 0xed, 0x55, 0xf0, 0xca, 0x20, 0x27, 0x99, 0xe5, 0xbf, + 0x4c, 0xca, 0x63, 0x48, 0x76, 0x58, 0x25, 0x1e, 0x3e, 0x17, 0x67, 0x3e, 0xd1, 0xe6, 0x57, 0xc0, + 0x0c, 0xc7, 0x3c, 0x40, 0xea, 0xde, 0x25, 0x17, 0xfa, 0x26, 0x28, 0x79, 0x88, 0xb9, 0x14, 0xc7, + 0x72, 0x0b, 0x4a, 0xdc, 0xe4, 0x87, 0x7a, 0xcc, 0x4e, 0xf5, 0x9a, 0xcd, 0xda, 0xf7, 0xf4, 0x10, + 0xed, 0x7b, 0x66, 0xb4, 0xf6, 0x3d, 0x3b, 0x44, 0xfb, 0xbe, 0x35, 0xa8, 0x7d, 0x17, 0x06, 0xb5, + 0xef, 0xe2, 0xd0, 0x4d, 0xa1, 0xb6, 0x05, 0xaa, 0xd7, 0x94, 0x34, 0x2d, 0xfb, 0xee, 0x9f, 0x4b, + 0x60, 0xea, 0x98, 0xf9, 0xfa, 0x2f, 0x34, 0xb0, 0x7c, 0xf5, 0x45, 0xef, 0xab, 0x43, 0x9d, 0x32, + 0xfb, 0xbd, 0x4d, 0x19, 0xfb, 0x63, 0xa7, 0xa6, 0xda, 0xf4, 0xdf, 0x6b, 0xc0, 0x18, 0xf0, 0x16, + 0x76, 0x30, 0xec, 0x0c, 0xd7, 0x73, 0x18, 0x0f, 0x6e, 0xce, 0x31, 0x40, 0x6e, 0xcf, 0x7b, 0xd4, + 0x98, 0x72, 0xf3, 0x1c, 0xe3, 0xca, 0xed, 0xf7, 0x76, 0xa2, 0xff, 0x5c, 0x03, 0x4b, 0x57, 0x0e, + 0xf6, 0x5f, 0x19, 0x76, 0x82, 0xcb, 0x99, 0xc6, 0x37, 0xc6, 0xcd, 0xcc, 0x04, 0xfd, 0x54, 0x03, + 0x8b, 0x97, 0x8f, 0x0e, 0x6f, 0x8d, 0xca, 0xaa, 0x12, 0x8d, 0xaf, 0x8f, 0x99, 0x98, 0xa9, 0x79, + 0x5f, 0x03, 0x73, 0x3d, 0x6f, 0x6e, 0x5f, 0x1e, 0x96, 0x31, 0x9f, 0x65, 0xbc, 0x3d, 0x4e, 0x56, + 0x26, 0x22, 0x04, 0x33, 0xc9, 0x06, 0xbd, 0x33, 0x2c, 0x8d, 0x84, 0x1b, 0x6f, 0x8e, 0x04, 0xcf, + 0xa6, 0x8b, 0xc1, 0xac, 0xda, 0x30, 0xcd, 0x11, 0x08, 0x4e, 0x5a, 0xdc, 0xb8, 0x37, 0x1a, 0x3e, + 0x9b, 0xf1, 0x77, 0x1a, 0x58, 0xbf, 0x7e, 0x97, 0x1b, 0xba, 0x87, 0x5c, 0x4b, 0x61, 0x1c, 0xdd, + 0x98, 0x22, 0xd3, 0xfa, 0x2b, 0x0d, 0xac, 0xf4, 0xdd, 0x9e, 0xde, 0x1e, 0xf5, 0x59, 0xcb, 0x67, + 0x1b, 0xf5, 0x9b, 0x64, 0xa7, 0xe2, 0x8c, 0x99, 0x1f, 0x8b, 0xdd, 0xf7, 0xe0, 0xfb, 0x4f, 0x9f, + 0x57, 0xb4, 0x8f, 0x9f, 0x57, 0xb4, 0x7f, 0x3e, 0xaf, 0x68, 0x1f, 0xbc, 0xa8, 0x4c, 0x7c, 0xfc, + 0xa2, 0x32, 0xf1, 0xb7, 0x17, 0x95, 0x89, 0x1f, 0x7c, 0xcd, 0xc7, 0xbc, 0xd9, 0x6a, 0x98, 0x2e, + 0x09, 0xd5, 0x57, 0x4a, 0xab, 0x3b, 0xef, 0x4e, 0xf6, 0x91, 0xb1, 0xfd, 0xa6, 0xf5, 0x5e, 0xef, + 0x97, 0x46, 0xf9, 0x65, 0xa6, 0x31, 0x2b, 0x4f, 0xe3, 0x5f, 0xfa, 0x4f, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xcb, 0x72, 0xac, 0x84, 0xe5, 0x15, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -926,6 +1422,10 @@ type MsgClient interface { ConsumerAddition(ctx context.Context, in *MsgConsumerAddition, opts ...grpc.CallOption) (*MsgConsumerAdditionResponse, error) ConsumerRemoval(ctx context.Context, in *MsgConsumerRemoval, opts ...grpc.CallOption) (*MsgConsumerRemovalResponse, error) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) + OptIn(ctx context.Context, in *MsgOptIn, opts ...grpc.CallOption) (*MsgOptInResponse, error) + OptOut(ctx context.Context, in *MsgOptOut, opts ...grpc.CallOption) (*MsgOptOutResponse, error) + SetConsumerCommissionRate(ctx context.Context, in *MsgSetConsumerCommissionRate, opts ...grpc.CallOption) (*MsgSetConsumerCommissionRateResponse, error) + ConsumerModification(ctx context.Context, in *MsgConsumerModification, opts ...grpc.CallOption) (*MsgConsumerModificationResponse, error) } type msgClient struct { @@ -990,14 +1490,54 @@ func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts return out, nil } -// MsgServer is the server API for Msg service. -type MsgServer interface { - AssignConsumerKey(context.Context, *MsgAssignConsumerKey) (*MsgAssignConsumerKeyResponse, error) - SubmitConsumerMisbehaviour(context.Context, *MsgSubmitConsumerMisbehaviour) (*MsgSubmitConsumerMisbehaviourResponse, error) - SubmitConsumerDoubleVoting(context.Context, *MsgSubmitConsumerDoubleVoting) (*MsgSubmitConsumerDoubleVotingResponse, error) +func (c *msgClient) OptIn(ctx context.Context, in *MsgOptIn, opts ...grpc.CallOption) (*MsgOptInResponse, error) { + out := new(MsgOptInResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Msg/OptIn", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) OptOut(ctx context.Context, in *MsgOptOut, opts ...grpc.CallOption) (*MsgOptOutResponse, error) { + out := new(MsgOptOutResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Msg/OptOut", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) SetConsumerCommissionRate(ctx context.Context, in *MsgSetConsumerCommissionRate, opts ...grpc.CallOption) (*MsgSetConsumerCommissionRateResponse, error) { + out := new(MsgSetConsumerCommissionRateResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Msg/SetConsumerCommissionRate", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) ConsumerModification(ctx context.Context, in *MsgConsumerModification, opts ...grpc.CallOption) (*MsgConsumerModificationResponse, error) { + out := new(MsgConsumerModificationResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Msg/ConsumerModification", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + AssignConsumerKey(context.Context, *MsgAssignConsumerKey) (*MsgAssignConsumerKeyResponse, error) + SubmitConsumerMisbehaviour(context.Context, *MsgSubmitConsumerMisbehaviour) (*MsgSubmitConsumerMisbehaviourResponse, error) + SubmitConsumerDoubleVoting(context.Context, *MsgSubmitConsumerDoubleVoting) (*MsgSubmitConsumerDoubleVotingResponse, error) ConsumerAddition(context.Context, *MsgConsumerAddition) (*MsgConsumerAdditionResponse, error) ConsumerRemoval(context.Context, *MsgConsumerRemoval) (*MsgConsumerRemovalResponse, error) UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) + OptIn(context.Context, *MsgOptIn) (*MsgOptInResponse, error) + OptOut(context.Context, *MsgOptOut) (*MsgOptOutResponse, error) + SetConsumerCommissionRate(context.Context, *MsgSetConsumerCommissionRate) (*MsgSetConsumerCommissionRateResponse, error) + ConsumerModification(context.Context, *MsgConsumerModification) (*MsgConsumerModificationResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -1022,6 +1562,18 @@ func (*UnimplementedMsgServer) ConsumerRemoval(ctx context.Context, req *MsgCons func (*UnimplementedMsgServer) UpdateParams(ctx context.Context, req *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") } +func (*UnimplementedMsgServer) OptIn(ctx context.Context, req *MsgOptIn) (*MsgOptInResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method OptIn not implemented") +} +func (*UnimplementedMsgServer) OptOut(ctx context.Context, req *MsgOptOut) (*MsgOptOutResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method OptOut not implemented") +} +func (*UnimplementedMsgServer) SetConsumerCommissionRate(ctx context.Context, req *MsgSetConsumerCommissionRate) (*MsgSetConsumerCommissionRateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetConsumerCommissionRate not implemented") +} +func (*UnimplementedMsgServer) ConsumerModification(ctx context.Context, req *MsgConsumerModification) (*MsgConsumerModificationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConsumerModification not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -1135,6 +1687,78 @@ func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Msg_OptIn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgOptIn) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).OptIn(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Msg/OptIn", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).OptIn(ctx, req.(*MsgOptIn)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_OptOut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgOptOut) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).OptOut(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Msg/OptOut", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).OptOut(ctx, req.(*MsgOptOut)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_SetConsumerCommissionRate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSetConsumerCommissionRate) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).SetConsumerCommissionRate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Msg/SetConsumerCommissionRate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).SetConsumerCommissionRate(ctx, req.(*MsgSetConsumerCommissionRate)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_ConsumerModification_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgConsumerModification) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ConsumerModification(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Msg/ConsumerModification", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ConsumerModification(ctx, req.(*MsgConsumerModification)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "interchain_security.ccv.provider.v1.Msg", HandlerType: (*MsgServer)(nil), @@ -1163,6 +1787,22 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "UpdateParams", Handler: _Msg_UpdateParams_Handler, }, + { + MethodName: "OptIn", + Handler: _Msg_OptIn_Handler, + }, + { + MethodName: "OptOut", + Handler: _Msg_OptOut_Handler, + }, + { + MethodName: "SetConsumerCommissionRate", + Handler: _Msg_SetConsumerCommissionRate_Handler, + }, + { + MethodName: "ConsumerModification", + Handler: _Msg_ConsumerModification_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "interchain_security/ccv/provider/v1/tx.proto", @@ -1472,7 +2112,46 @@ func (m *MsgConsumerAddition) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Authority) i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) i-- - dAtA[i] = 0x6a + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x92 + } + if len(m.Denylist) > 0 { + for iNdEx := len(m.Denylist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Denylist[iNdEx]) + copy(dAtA[i:], m.Denylist[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.Denylist[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x8a + } + } + if len(m.Allowlist) > 0 { + for iNdEx := len(m.Allowlist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Allowlist[iNdEx]) + copy(dAtA[i:], m.Allowlist[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.Allowlist[iNdEx]))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x82 + } + } + if m.ValidatorSetCap != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.ValidatorSetCap)) + i-- + dAtA[i] = 0x78 + } + if m.ValidatorsPowerCap != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.ValidatorsPowerCap)) + i-- + dAtA[i] = 0x70 + } + if m.Top_N != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Top_N)) + i-- + dAtA[i] = 0x68 } if len(m.DistributionTransmissionChannel) > 0 { i -= len(m.DistributionTransmissionChannel) @@ -1726,99 +2405,417 @@ func (m *MsgChangeRewardDenomsResponse) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } -func encodeVarintTx(dAtA []byte, offset int, v uint64) int { - offset -= sovTx(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *MsgOptIn) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *MsgAssignConsumerKey) Size() (n int) { - if m == nil { - return 0 - } + +func (m *MsgOptIn) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgOptIn) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.ChainId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x22 } - l = len(m.ProviderAddr) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if len(m.ConsumerKey) > 0 { + i -= len(m.ConsumerKey) + copy(dAtA[i:], m.ConsumerKey) + i = encodeVarintTx(dAtA, i, uint64(len(m.ConsumerKey))) + i-- + dAtA[i] = 0x1a } - l = len(m.ConsumerKey) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if len(m.ProviderAddr) > 0 { + i -= len(m.ProviderAddr) + copy(dAtA[i:], m.ProviderAddr) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProviderAddr))) + i-- + dAtA[i] = 0x12 } - l = len(m.Signer) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *MsgAssignConsumerKeyResponse) Size() (n int) { - if m == nil { - return 0 +func (m *MsgOptInResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - return n + return dAtA[:n], nil } -func (m *MsgSubmitConsumerMisbehaviour) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Submitter) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - if m.Misbehaviour != nil { - l = m.Misbehaviour.Size() - n += 1 + l + sovTx(uint64(l)) - } - return n +func (m *MsgOptInResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MsgSubmitConsumerMisbehaviourResponse) Size() (n int) { - if m == nil { - return 0 - } +func (m *MsgOptInResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - return n + return len(dAtA) - i, nil } -func (m *MsgSubmitConsumerDoubleVoting) Size() (n int) { - if m == nil { - return 0 +func (m *MsgOptOut) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } + return dAtA[:n], nil +} + +func (m *MsgOptOut) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgOptOut) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.Submitter) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x1a } - if m.DuplicateVoteEvidence != nil { - l = m.DuplicateVoteEvidence.Size() - n += 1 + l + sovTx(uint64(l)) + if len(m.ProviderAddr) > 0 { + i -= len(m.ProviderAddr) + copy(dAtA[i:], m.ProviderAddr) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProviderAddr))) + i-- + dAtA[i] = 0x12 } - if m.InfractionBlockHeader != nil { - l = m.InfractionBlockHeader.Size() - n += 1 + l + sovTx(uint64(l)) + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *MsgSubmitConsumerDoubleVotingResponse) Size() (n int) { +func (m *MsgOptOutResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgOptOutResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgOptOutResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgSetConsumerCommissionRate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgSetConsumerCommissionRate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetConsumerCommissionRate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.Rate.Size() + i -= size + if _, err := m.Rate.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0x12 + } + if len(m.ProviderAddr) > 0 { + i -= len(m.ProviderAddr) + copy(dAtA[i:], m.ProviderAddr) + i = encodeVarintTx(dAtA, i, uint64(len(m.ProviderAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgSetConsumerCommissionRateResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgSetConsumerCommissionRateResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetConsumerCommissionRateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgConsumerModification) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgConsumerModification) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgConsumerModification) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0x4a + } + if len(m.Denylist) > 0 { + for iNdEx := len(m.Denylist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Denylist[iNdEx]) + copy(dAtA[i:], m.Denylist[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.Denylist[iNdEx]))) + i-- + dAtA[i] = 0x42 + } + } + if len(m.Allowlist) > 0 { + for iNdEx := len(m.Allowlist) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Allowlist[iNdEx]) + copy(dAtA[i:], m.Allowlist[iNdEx]) + i = encodeVarintTx(dAtA, i, uint64(len(m.Allowlist[iNdEx]))) + i-- + dAtA[i] = 0x3a + } + } + if m.ValidatorSetCap != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.ValidatorSetCap)) + i-- + dAtA[i] = 0x30 + } + if m.ValidatorsPowerCap != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.ValidatorsPowerCap)) + i-- + dAtA[i] = 0x28 + } + if m.Top_N != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Top_N)) + i-- + dAtA[i] = 0x20 + } + if len(m.ChainId) > 0 { + i -= len(m.ChainId) + copy(dAtA[i:], m.ChainId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ChainId))) + i-- + dAtA[i] = 0x1a + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintTx(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if len(m.Title) > 0 { + i -= len(m.Title) + copy(dAtA[i:], m.Title) + i = encodeVarintTx(dAtA, i, uint64(len(m.Title))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgConsumerModificationResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgConsumerModificationResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgConsumerModificationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgAssignConsumerKey) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProviderAddr) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ConsumerKey) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgAssignConsumerKeyResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgSubmitConsumerMisbehaviour) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Submitter) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.Misbehaviour != nil { + l = m.Misbehaviour.Size() + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgSubmitConsumerMisbehaviourResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgSubmitConsumerDoubleVoting) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Submitter) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.DuplicateVoteEvidence != nil { + l = m.DuplicateVoteEvidence.Size() + n += 1 + l + sovTx(uint64(l)) + } + if m.InfractionBlockHeader != nil { + l = m.InfractionBlockHeader.Size() + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgSubmitConsumerDoubleVotingResponse) Size() (n int) { if m == nil { return 0 } @@ -1893,9 +2890,30 @@ func (m *MsgConsumerAddition) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + if m.Top_N != 0 { + n += 1 + sovTx(uint64(m.Top_N)) + } + if m.ValidatorsPowerCap != 0 { + n += 1 + sovTx(uint64(m.ValidatorsPowerCap)) + } + if m.ValidatorSetCap != 0 { + n += 1 + sovTx(uint64(m.ValidatorSetCap)) + } + if len(m.Allowlist) > 0 { + for _, s := range m.Allowlist { + l = len(s) + n += 2 + l + sovTx(uint64(l)) + } + } + if len(m.Denylist) > 0 { + for _, s := range m.Denylist { + l = len(s) + n += 2 + l + sovTx(uint64(l)) + } + } l = len(m.Authority) if l > 0 { - n += 1 + l + sovTx(uint64(l)) + n += 2 + l + sovTx(uint64(l)) } return n } @@ -1971,6 +2989,153 @@ func (m *MsgChangeRewardDenomsResponse) Size() (n int) { return n } +func (m *MsgOptIn) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProviderAddr) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ConsumerKey) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgOptInResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgOptOut) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ProviderAddr) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgOptOutResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgSetConsumerCommissionRate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ProviderAddr) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Rate.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgSetConsumerCommissionRateResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgConsumerModification) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Title) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ChainId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.Top_N != 0 { + n += 1 + sovTx(uint64(m.Top_N)) + } + if m.ValidatorsPowerCap != 0 { + n += 1 + sovTx(uint64(m.ValidatorsPowerCap)) + } + if m.ValidatorSetCap != 0 { + n += 1 + sovTx(uint64(m.ValidatorSetCap)) + } + if len(m.Allowlist) > 0 { + for _, s := range m.Allowlist { + l = len(s) + n += 1 + l + sovTx(uint64(l)) + } + } + if len(m.Denylist) > 0 { + for _, s := range m.Denylist { + l = len(s) + n += 1 + l + sovTx(uint64(l)) + } + } + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgConsumerModificationResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2036,13 +3201,1113 @@ func (m *MsgAssignConsumerKey) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainId = string(dAtA[iNdEx:postIndex]) + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProviderAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerKey", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConsumerKey = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgAssignConsumerKeyResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgAssignConsumerKeyResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAssignConsumerKeyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSubmitConsumerMisbehaviour) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviour: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviour: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Submitter", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Submitter = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Misbehaviour", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Misbehaviour == nil { + m.Misbehaviour = &_07_tendermint.Misbehaviour{} + } + if err := m.Misbehaviour.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSubmitConsumerMisbehaviourResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviourResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviourResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSubmitConsumerDoubleVoting) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSubmitConsumerDoubleVoting: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSubmitConsumerDoubleVoting: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Submitter", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Submitter = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DuplicateVoteEvidence", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.DuplicateVoteEvidence == nil { + m.DuplicateVoteEvidence = &types.DuplicateVoteEvidence{} + } + if err := m.DuplicateVoteEvidence.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InfractionBlockHeader", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.InfractionBlockHeader == nil { + m.InfractionBlockHeader = &_07_tendermint.Header{} + } + if err := m.InfractionBlockHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSubmitConsumerDoubleVotingResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSubmitConsumerDoubleVotingResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSubmitConsumerDoubleVotingResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateParams) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgConsumerAddition) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgConsumerAddition: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgConsumerAddition: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InitialHeight", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.InitialHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GenesisHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GenesisHash = append(m.GenesisHash[:0], dAtA[iNdEx:postIndex]...) + if m.GenesisHash == nil { + m.GenesisHash = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BinaryHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BinaryHash = append(m.BinaryHash[:0], dAtA[iNdEx:postIndex]...) + if m.BinaryHash == nil { + m.BinaryHash = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpawnTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.SpawnTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UnbondingPeriod", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.UnbondingPeriod, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CcvTimeoutPeriod", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.CcvTimeoutPeriod, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TransferTimeoutPeriod", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.TransferTimeoutPeriod, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerRedistributionFraction", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConsumerRedistributionFraction = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlocksPerDistributionTransmission", wireType) + } + m.BlocksPerDistributionTransmission = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlocksPerDistributionTransmission |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HistoricalEntries", wireType) + } + m.HistoricalEntries = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.HistoricalEntries |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DistributionTransmissionChannel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DistributionTransmissionChannel = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddr", wireType) + case 13: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Top_N", wireType) } - var stringLen uint64 + m.Top_N = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -2052,29 +4317,16 @@ func (m *MsgAssignConsumerKey) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Top_N |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ProviderAddr = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConsumerKey", wireType) + case 14: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorsPowerCap", wireType) } - var stringLen uint64 + m.ValidatorsPowerCap = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -2084,27 +4336,33 @@ func (m *MsgAssignConsumerKey) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.ValidatorsPowerCap |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTx + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorSetCap", wireType) } - if postIndex > l { - return io.ErrUnexpectedEOF + m.ValidatorSetCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorSetCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } } - m.ConsumerKey = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: + case 16: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Allowlist", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2132,111 +4390,11 @@ func (m *MsgAssignConsumerKey) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Signer = string(dAtA[iNdEx:postIndex]) + m.Allowlist = append(m.Allowlist, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTx(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTx - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *MsgAssignConsumerKeyResponse) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MsgAssignConsumerKeyResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MsgAssignConsumerKeyResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipTx(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTx - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *MsgSubmitConsumerMisbehaviour) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviour: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviour: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 17: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Submitter", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Denylist", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2264,13 +4422,13 @@ func (m *MsgSubmitConsumerMisbehaviour) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Submitter = string(dAtA[iNdEx:postIndex]) + m.Denylist = append(m.Denylist, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 2: + case 18: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Misbehaviour", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -2280,27 +4438,23 @@ func (m *MsgSubmitConsumerMisbehaviour) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Misbehaviour == nil { - m.Misbehaviour = &_07_tendermint.Misbehaviour{} - } - if err := m.Misbehaviour.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Authority = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -2323,7 +4477,7 @@ func (m *MsgSubmitConsumerMisbehaviour) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgSubmitConsumerMisbehaviourResponse) Unmarshal(dAtA []byte) error { +func (m *MsgConsumerAdditionResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2346,10 +4500,10 @@ func (m *MsgSubmitConsumerMisbehaviourResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviourResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgConsumerAdditionResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgSubmitConsumerMisbehaviourResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgConsumerAdditionResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -2373,7 +4527,7 @@ func (m *MsgSubmitConsumerMisbehaviourResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgSubmitConsumerDoubleVoting) Unmarshal(dAtA []byte) error { +func (m *MsgConsumerRemoval) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2396,15 +4550,15 @@ func (m *MsgSubmitConsumerDoubleVoting) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgSubmitConsumerDoubleVoting: wiretype end group for non-group") + return fmt.Errorf("proto: MsgConsumerRemoval: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgSubmitConsumerDoubleVoting: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgConsumerRemoval: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Submitter", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2432,11 +4586,11 @@ func (m *MsgSubmitConsumerDoubleVoting) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Submitter = string(dAtA[iNdEx:postIndex]) + m.ChainId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DuplicateVoteEvidence", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field StopTime", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -2463,18 +4617,15 @@ func (m *MsgSubmitConsumerDoubleVoting) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.DuplicateVoteEvidence == nil { - m.DuplicateVoteEvidence = &types.DuplicateVoteEvidence{} - } - if err := m.DuplicateVoteEvidence.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.StopTime, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InfractionBlockHeader", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -2484,27 +4635,23 @@ func (m *MsgSubmitConsumerDoubleVoting) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - if m.InfractionBlockHeader == nil { - m.InfractionBlockHeader = &_07_tendermint.Header{} - } - if err := m.InfractionBlockHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Authority = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -2527,7 +4674,7 @@ func (m *MsgSubmitConsumerDoubleVoting) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgSubmitConsumerDoubleVotingResponse) Unmarshal(dAtA []byte) error { +func (m *MsgConsumerRemovalResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2550,10 +4697,10 @@ func (m *MsgSubmitConsumerDoubleVotingResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgSubmitConsumerDoubleVotingResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgConsumerRemovalResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgSubmitConsumerDoubleVotingResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgConsumerRemovalResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -2577,7 +4724,7 @@ func (m *MsgSubmitConsumerDoubleVotingResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgUpdateParams) Unmarshal(dAtA []byte) error { +func (m *MsgChangeRewardDenoms) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2600,15 +4747,47 @@ func (m *MsgUpdateParams) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgUpdateParams: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChangeRewardDenoms: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChangeRewardDenoms: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DenomsToAdd", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DenomsToAdd = append(m.DenomsToAdd, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DenomsToRemove", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2636,13 +4815,13 @@ func (m *MsgUpdateParams) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Authority = string(dAtA[iNdEx:postIndex]) + m.DenomsToRemove = append(m.DenomsToRemove, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -2652,24 +4831,23 @@ func (m *MsgUpdateParams) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Authority = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -2692,7 +4870,7 @@ func (m *MsgUpdateParams) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgUpdateParamsResponse) Unmarshal(dAtA []byte) error { +func (m *MsgChangeRewardDenomsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2715,10 +4893,10 @@ func (m *MsgUpdateParamsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgUpdateParamsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgChangeRewardDenomsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgChangeRewardDenomsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -2742,7 +4920,7 @@ func (m *MsgUpdateParamsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgConsumerAddition) Unmarshal(dAtA []byte) error { +func (m *MsgOptIn) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2765,10 +4943,10 @@ func (m *MsgConsumerAddition) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgConsumerAddition: wiretype end group for non-group") + return fmt.Errorf("proto: MsgOptIn: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgConsumerAddition: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgOptIn: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -2805,9 +4983,9 @@ func (m *MsgConsumerAddition) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InitialHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddr", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -2817,30 +4995,29 @@ func (m *MsgConsumerAddition) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.InitialHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ProviderAddr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GenesisHash", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsumerKey", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -2850,31 +5027,29 @@ func (m *MsgConsumerAddition) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.GenesisHash = append(m.GenesisHash[:0], dAtA[iNdEx:postIndex]...) - if m.GenesisHash == nil { - m.GenesisHash = []byte{} - } + m.ConsumerKey = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BinaryHash", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -2884,161 +5059,127 @@ func (m *MsgConsumerAddition) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - m.BinaryHash = append(m.BinaryHash[:0], dAtA[iNdEx:postIndex]...) - if m.BinaryHash == nil { - m.BinaryHash = []byte{} - } + m.Signer = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SpawnTime", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.SpawnTime, dAtA[iNdEx:postIndex]); err != nil { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { return err } - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UnbondingPeriod", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + msglen - if postIndex < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTx } - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.UnbondingPeriod, dAtA[iNdEx:postIndex]); err != nil { - return err + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgOptInResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx } - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CcvTimeoutPeriod", wireType) + if iNdEx >= l { + return io.ErrUnexpectedEOF } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - if msglen < 0 { - return ErrInvalidLengthTx + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgOptInResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgOptInResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err } - postIndex := iNdEx + msglen - if postIndex < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthTx } - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.CcvTimeoutPeriod, dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TransferTimeoutPeriod", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTx + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgOptOut) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx } - if postIndex > l { + if iNdEx >= l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.TransferTimeoutPeriod, dAtA[iNdEx:postIndex]); err != nil { - return err + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - iNdEx = postIndex - case 9: + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgOptOut: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgOptOut: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConsumerRedistributionFraction", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3066,49 +5207,11 @@ func (m *MsgConsumerAddition) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ConsumerRedistributionFraction = string(dAtA[iNdEx:postIndex]) + m.ChainId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 10: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BlocksPerDistributionTransmission", wireType) - } - m.BlocksPerDistributionTransmission = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.BlocksPerDistributionTransmission |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 11: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field HistoricalEntries", wireType) - } - m.HistoricalEntries = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.HistoricalEntries |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 12: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DistributionTransmissionChannel", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddr", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3136,11 +5239,11 @@ func (m *MsgConsumerAddition) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DistributionTransmissionChannel = string(dAtA[iNdEx:postIndex]) + m.ProviderAddr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 13: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3168,7 +5271,7 @@ func (m *MsgConsumerAddition) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Authority = string(dAtA[iNdEx:postIndex]) + m.Signer = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -3191,7 +5294,7 @@ func (m *MsgConsumerAddition) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgConsumerAdditionResponse) Unmarshal(dAtA []byte) error { +func (m *MsgOptOutResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3214,10 +5317,10 @@ func (m *MsgConsumerAdditionResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgConsumerAdditionResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgOptOutResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgConsumerAdditionResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgOptOutResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -3241,7 +5344,7 @@ func (m *MsgConsumerAdditionResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgConsumerRemoval) Unmarshal(dAtA []byte) error { +func (m *MsgSetConsumerCommissionRate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3264,15 +5367,15 @@ func (m *MsgConsumerRemoval) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgConsumerRemoval: wiretype end group for non-group") + return fmt.Errorf("proto: MsgSetConsumerCommissionRate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgConsumerRemoval: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgSetConsumerCommissionRate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProviderAddr", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3300,13 +5403,13 @@ func (m *MsgConsumerRemoval) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainId = string(dAtA[iNdEx:postIndex]) + m.ProviderAddr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StopTime", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowTx @@ -3316,28 +5419,27 @@ func (m *MsgConsumerRemoval) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthTx } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthTx } if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.StopTime, dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ChainId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Rate", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3365,7 +5467,9 @@ func (m *MsgConsumerRemoval) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Authority = string(dAtA[iNdEx:postIndex]) + if err := m.Rate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -3388,7 +5492,7 @@ func (m *MsgConsumerRemoval) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgConsumerRemovalResponse) Unmarshal(dAtA []byte) error { +func (m *MsgSetConsumerCommissionRateResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3411,10 +5515,10 @@ func (m *MsgConsumerRemovalResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgConsumerRemovalResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgSetConsumerCommissionRateResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgConsumerRemovalResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgSetConsumerCommissionRateResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -3438,7 +5542,7 @@ func (m *MsgConsumerRemovalResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgChangeRewardDenoms) Unmarshal(dAtA []byte) error { +func (m *MsgConsumerModification) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3461,15 +5565,15 @@ func (m *MsgChangeRewardDenoms) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgChangeRewardDenoms: wiretype end group for non-group") + return fmt.Errorf("proto: MsgConsumerModification: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgChangeRewardDenoms: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgConsumerModification: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DenomsToAdd", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Title", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3497,11 +5601,11 @@ func (m *MsgChangeRewardDenoms) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DenomsToAdd = append(m.DenomsToAdd, string(dAtA[iNdEx:postIndex])) + m.Title = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DenomsToRemove", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3529,9 +5633,162 @@ func (m *MsgChangeRewardDenoms) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DenomsToRemove = append(m.DenomsToRemove, string(dAtA[iNdEx:postIndex])) + m.Description = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChainId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Top_N", wireType) + } + m.Top_N = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Top_N |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorsPowerCap", wireType) + } + m.ValidatorsPowerCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorsPowerCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorSetCap", wireType) + } + m.ValidatorSetCap = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValidatorSetCap |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Allowlist", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Allowlist = append(m.Allowlist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denylist", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Denylist = append(m.Denylist, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 9: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) } @@ -3584,7 +5841,7 @@ func (m *MsgChangeRewardDenoms) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgChangeRewardDenomsResponse) Unmarshal(dAtA []byte) error { +func (m *MsgConsumerModificationResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3607,10 +5864,10 @@ func (m *MsgChangeRewardDenomsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgChangeRewardDenomsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgConsumerModificationResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgChangeRewardDenomsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgConsumerModificationResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: diff --git a/x/ccv/types/expected_keepers.go b/x/ccv/types/expected_keepers.go index f7456c7e3b..fbfbd61111 100644 --- a/x/ccv/types/expected_keepers.go +++ b/x/ccv/types/expected_keepers.go @@ -11,7 +11,6 @@ import ( ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" "cosmossdk.io/math" - storetypes "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" @@ -48,11 +47,14 @@ type StakingKeeper interface { Delegation(ctx context.Context, addr sdk.AccAddress, valAddr sdk.ValAddress) (stakingtypes.DelegationI, error) MaxValidators(ctx context.Context) (uint32, error) GetLastTotalPower(ctx context.Context) (math.Int, error) - GetLastValidators(ctx context.Context) ([]stakingtypes.Validator, error) BondDenom(ctx context.Context) (string, error) GetUnbondingDelegationsFromValidator(ctx context.Context, valAddr sdk.ValAddress) ([]stakingtypes.UnbondingDelegation, error) GetRedelegationsFromSrcValidator(ctx context.Context, valAddr sdk.ValAddress) ([]stakingtypes.Redelegation, error) GetUnbondingType(ctx context.Context, id uint64) (stakingtypes.UnbondingType, error) + MinCommissionRate(ctx context.Context) (math.LegacyDec, error) + GetUnbondingDelegationByUnbondingID(ctx context.Context, id uint64) (stakingtypes.UnbondingDelegation, error) + GetRedelegationByUnbondingID(ctx context.Context, id uint64) (stakingtypes.Redelegation, error) + GetValidatorByUnbondingID(ctx context.Context, id uint64) (stakingtypes.Validator, error) } // SlashingKeeper defines the contract expected to perform ccv slashing @@ -109,6 +111,8 @@ type ClientKeeper interface { // DistributionKeeper defines the expected interface of the distribution keeper type DistributionKeeper interface { FundCommunityPool(ctx context.Context, amount sdk.Coins, sender sdk.AccAddress) error + GetCommunityTax(ctx context.Context) (math.LegacyDec, error) + AllocateTokensToValidator(ctx context.Context, validator stakingtypes.ValidatorI, reward sdk.DecCoins) error } // ConsumerHooks event hooks for newly bonded cross-chain validators @@ -134,7 +138,7 @@ type IBCTransferKeeper interface { Transfer(context.Context, *transfertypes.MsgTransfer) (*transfertypes.MsgTransferResponse, error) } -// IBCKeeper defines the expected interface needed for opening a +// IBCCoreKeeper defines the expected interface needed for opening a // channel type IBCCoreKeeper interface { ChannelOpenInit( diff --git a/x/ccv/types/utils.go b/x/ccv/types/utils.go index a7030090bd..cb174168e8 100644 --- a/x/ccv/types/utils.go +++ b/x/ccv/types/utils.go @@ -7,15 +7,16 @@ import ( "strings" "time" + errorsmod "cosmossdk.io/errors" + "cosmossdk.io/log" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" host "github.com/cosmos/ibc-go/v8/modules/core/24-host" - errorsmod "cosmossdk.io/errors" - cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/bech32" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" abci "github.com/cometbft/cometbft/abci/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" @@ -123,3 +124,46 @@ func GetConsAddrFromBech32(bech32str string) (sdk.ConsAddress, error) { } return sdk.ConsAddress(addr), nil } + +func GetLastBondedValidatorsUtil(ctx sdk.Context, stakingKeeper StakingKeeper, logger log.Logger) ([]stakingtypes.Validator, error) { + maxVals, err := stakingKeeper.MaxValidators(ctx) + if err != nil { + return nil, err + } + + lastPowers := make([]stakingtypes.LastValidatorPower, maxVals) + + i := 0 + err = stakingKeeper.IterateLastValidatorPowers(ctx, func(addr sdk.ValAddress, power int64) (stop bool) { + lastPowers[i] = stakingtypes.LastValidatorPower{Address: addr.String(), Power: power} + i++ + return i >= int(maxVals) // stop iteration if true + }) + + if err != nil { + return nil, err + } + + // truncate the lastPowers + lastPowers = lastPowers[:i] + + bondedValidators := make([]stakingtypes.Validator, len(lastPowers)) + + for index, p := range lastPowers { + addr, err := sdk.ValAddressFromBech32(p.Address) + if err != nil { + logger.Error("Invalid validator address", "address", p.Address, "error", err) + continue + } + + val, err := stakingKeeper.GetValidator(ctx, addr) + if err != nil { + logger.Error(err.Error(), addr.String()) + continue + } + + // gather all the bonded validators in order to construct the consumer validator set for consumer chain `chainID` + bondedValidators[index] = val + } + return bondedValidators, nil +} From 9ee031266fe52164f6050d1902e57bbfd886aead Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 2 Jul 2024 15:20:56 +0200 Subject: [PATCH 21/35] fix!: typo in error codes (#2004) fix typo in error code --- x/ccv/provider/types/errors.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x/ccv/provider/types/errors.go b/x/ccv/provider/types/errors.go index 7cee0716ba..5109489d76 100644 --- a/x/ccv/provider/types/errors.go +++ b/x/ccv/provider/types/errors.go @@ -27,9 +27,9 @@ var ( ErrInvalidConsumerCommissionRate = errorsmod.Register(ModuleName, 19, "consumer commission rate is invalid") ErrCannotOptOutFromTopN = errorsmod.Register(ModuleName, 20, "cannot opt out from a Top N chain") ErrNoUnconfirmedVSCPacket = errorsmod.Register(ModuleName, 21, "no unconfirmed vsc packet for this chain id") - ErrInvalidConsumerModificationProposal = errorsmod.Register(ModuleName, 23, "invalid consumer modification proposal") - ErrNoUnbondingTime = errorsmod.Register(ModuleName, 24, "provider unbonding time not found") - ErrInvalidAddress = errorsmod.Register(ModuleName, 25, "invalid address") - ErrUnauthorized = errorsmod.Register(ModuleName, 26, "unauthorized") - ErrBlankConsumerChainID = errorsmod.Register(ModuleName, 27, "consumer chain id must not be blank") + ErrInvalidConsumerModificationProposal = errorsmod.Register(ModuleName, 22, "invalid consumer modification proposal") + ErrNoUnbondingTime = errorsmod.Register(ModuleName, 23, "provider unbonding time not found") + ErrInvalidAddress = errorsmod.Register(ModuleName, 24, "invalid address") + ErrUnauthorized = errorsmod.Register(ModuleName, 25, "unauthorized") + ErrBlankConsumerChainID = errorsmod.Register(ModuleName, 26, "consumer chain id must not be blank") ) From 135c4d9fc4f4e86c43ae65f5a243b15801a316ad Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 3 Jul 2024 09:33:57 +0200 Subject: [PATCH 22/35] Merge branch 'release/v5.1.x' into main --- .../unreleased/dependencies/1924-bump-ibc.md | 3 - .../unreleased/dependencies/xxx-bump-comet.md | 3 + .../unreleased/dependencies/xxx-bump-ibc.md | 3 + .../unreleased/dependencies/xxx-bump-sdk.md | 3 + .../provider/1925-apply-audit-suggestions.md | 3 - .../state-breaking/xxx-bump-comet.md | 3 + .../unreleased/state-breaking/xxx-bump-ibc.md | 3 + .../unreleased/state-breaking/xxx-bump-sdk.md | 3 + .../bug-fixes/1921-write-stderr.md | 0 .../provider/1925-apply-audit-suggestions.md | 3 + .../provider/1946-get-consumer-chains.md | 0 .../v4.3.0/dependencies/1974-bump-ibc.md | 3 + .../provider/1932-allow-pss-params-changes.md | 2 + ...ards-to-long-term-validating-validators.md | 0 .../v4.3.0/state-breaking/1974-bump-ibc.md | 3 + .../provider/1925-apply-audit-suggestions.md | 3 +- ...ards-to-long-term-validating-validators.md | 0 .../provider/1932-allow-pss-params-changes.md | 2 + .changelog/v4.3.0/summary.md | 1 + .github/dependabot.yml | 20 +- .github/workflows/docker-publish.yml | 2 +- .github/workflows/proto-registry.yml | 2 +- .github/workflows/proto.yml | 2 +- .mergify.yml | 33 ++- CHANGELOG.md | 139 ++++++++++ CONTRIBUTING.md | 4 +- FEATURES.md | 33 +-- RELEASES.md | 37 +-- RELEASE_NOTES.md | 4 +- RELEASE_PROCESS.md | 78 +++++- UPGRADING.md | 4 +- app/consumer-democracy/app.go | 1 - app/consumer/app.go | 1 - app/consumer/genesis.go | 3 + app/consumer/genesis_test.go | 9 +- app/provider/app.go | 2 - docs/build_deploy.sh | 11 +- docs/docs/adrs/adr-004-denom-dos-fixes.md | 2 +- ...cryptographic-equivocation-verification.md | 2 +- .../adr-007-pause-unbonding-on-eqv-prop.md | 2 +- docs/docs/adrs/adr-008-throttle-retries.md | 2 +- docs/docs/adrs/adr-009-soft-opt-out.md | 5 +- .../adrs/adr-010-standalone-changeover.md | 4 +- .../adr-017-allowing-inactive-validators.md | 2 +- docs/docs/adrs/intro.md | 10 +- .../docs/adrs/{ => templates}/adr-template.md | 0 .../consumer-development/app-integration.md | 5 +- .../changeover-procedure.md | 35 ++- docs/docs/features/democracy-modules.md | 4 + docs/docs/features/partial-set-security.md | 2 +- docs/docs/features/power-shaping.md | 4 + docs/docs/features/proposals.md | 8 - docs/docs/features/reward-distribution.md | 2 +- docs/docs/frequently-asked-questions.md | 2 +- docs/docs/index.mdx | 2 +- docs/docs/introduction/terminology.md | 6 +- docs/docs/validators/changeover-procedure.md | 6 +- docs/docs/validators/joining-testnet.md | 2 +- docs/docs/validators/overview.md | 15 +- docs/docs/validators/withdraw_rewards.md | 2 +- docs/docusaurus.config.js | 1 + .../ccv/consumer/v1/consumer.proto | 5 +- .../ccv/provider/v1/query.proto | 5 +- .../ccv/provider/v1/tx.proto | 3 +- .../ccv/v1/shared_consumer.proto | 7 +- tests/e2e/actions.go | 12 +- tests/e2e/main.go | 11 +- tests/e2e/state.go | 2 +- tests/e2e/step_delegation.go | 115 +------- tests/e2e/steps.go | 16 +- tests/e2e/steps_compatibility.go | 6 - tests/e2e/steps_consumer_misbehaviour.go | 26 +- tests/e2e/steps_double_sign.go | 12 +- tests/e2e/steps_downtime.go | 161 ++++------- tests/e2e/steps_light_client_attack.go | 24 +- tests/e2e/steps_sovereign_changeover.go | 1 - tests/e2e/steps_start_chains.go | 6 - tests/e2e/test_runner.go | 20 +- .../e2e/tracehandler_testdata/changeover.json | 2 +- .../consumer-double-sign.json | 2 +- .../consumer-misbehaviour.json | 20 +- .../e2e/tracehandler_testdata/democracy.json | 2 +- .../democracyRewardsSteps.json | 2 +- .../e2e/tracehandler_testdata/happyPath.json | 76 +++--- .../multipleConsumers.json | 4 +- .../e2e/tracehandler_testdata/shorthappy.json | 78 +++--- .../tracehandler_testdata/slashThrottle.json | 2 +- tests/mbt/driver/setup.go | 2 +- tests/mbt/model/ccv.qnt | 2 +- testutil/integration/debug_test.go | 8 - x/ccv/consumer/keeper/validators.go | 2 +- x/ccv/consumer/types/consumer.pb.go | 61 +++-- x/ccv/consumer/types/keys_test.go | 3 +- x/ccv/consumer/types/params_test.go | 8 - x/ccv/consumer/types/validator.go | 7 +- x/ccv/provider/ibc_middleware.go | 2 +- .../provider/keeper/consumer_equivocation.go | 6 +- .../{migrations_test.go => migration_test.go} | 0 x/ccv/provider/types/query.pb.go | 257 +++++++++--------- x/ccv/provider/types/tx.pb.go | 210 +++++++------- x/ccv/types/params.go | 11 +- x/ccv/types/shared_consumer.pb.go | 111 ++++---- 102 files changed, 978 insertions(+), 883 deletions(-) delete mode 100644 .changelog/unreleased/dependencies/1924-bump-ibc.md create mode 100644 .changelog/unreleased/dependencies/xxx-bump-comet.md create mode 100644 .changelog/unreleased/dependencies/xxx-bump-ibc.md create mode 100644 .changelog/unreleased/dependencies/xxx-bump-sdk.md delete mode 100644 .changelog/unreleased/state-breaking/provider/1925-apply-audit-suggestions.md create mode 100644 .changelog/unreleased/state-breaking/xxx-bump-comet.md create mode 100644 .changelog/unreleased/state-breaking/xxx-bump-ibc.md create mode 100644 .changelog/unreleased/state-breaking/xxx-bump-sdk.md rename .changelog/{unreleased => v4.3.0}/bug-fixes/1921-write-stderr.md (100%) create mode 100644 .changelog/v4.3.0/bug-fixes/provider/1925-apply-audit-suggestions.md rename .changelog/{unreleased => v4.3.0}/bug-fixes/provider/1946-get-consumer-chains.md (100%) create mode 100644 .changelog/v4.3.0/dependencies/1974-bump-ibc.md create mode 100644 .changelog/v4.3.0/features/provider/1932-allow-pss-params-changes.md rename .changelog/{unreleased => v4.3.0}/improvements/provider/1929-distribute-rewards-to-long-term-validating-validators.md (100%) create mode 100644 .changelog/v4.3.0/state-breaking/1974-bump-ibc.md rename .changelog/{unreleased/bug-fixes => v4.3.0/state-breaking}/provider/1925-apply-audit-suggestions.md (81%) rename .changelog/{unreleased => v4.3.0}/state-breaking/provider/1929-distribute-rewards-to-long-term-validating-validators.md (100%) create mode 100644 .changelog/v4.3.0/state-breaking/provider/1932-allow-pss-params-changes.md create mode 100644 .changelog/v4.3.0/summary.md rename docs/docs/adrs/{ => templates}/adr-template.md (100%) rename x/ccv/provider/migrations/v5/{migrations_test.go => migration_test.go} (100%) diff --git a/.changelog/unreleased/dependencies/1924-bump-ibc.md b/.changelog/unreleased/dependencies/1924-bump-ibc.md deleted file mode 100644 index 8980dd3b9a..0000000000 --- a/.changelog/unreleased/dependencies/1924-bump-ibc.md +++ /dev/null @@ -1,3 +0,0 @@ -- Bump [ibc-go](https://github.com/cosmos/ibc-go) to - [v7.5.1](https://github.com/cosmos/ibc-go/releases/tag/v7.5.1). - ([\#1924](https://github.com/cosmos/interchain-security/pull/1924)) \ No newline at end of file diff --git a/.changelog/unreleased/dependencies/xxx-bump-comet.md b/.changelog/unreleased/dependencies/xxx-bump-comet.md new file mode 100644 index 0000000000..045e29ce3d --- /dev/null +++ b/.changelog/unreleased/dependencies/xxx-bump-comet.md @@ -0,0 +1,3 @@ +- Bump [CometBFT](https://github.com/cometbft/cometbft) to + [v0.38.7](https://github.com/cometbft/cometbft/releases/tag/v0.38.7). + ([\#xxx](https://github.com/cosmos/interchain-security/pull/xxx)) \ No newline at end of file diff --git a/.changelog/unreleased/dependencies/xxx-bump-ibc.md b/.changelog/unreleased/dependencies/xxx-bump-ibc.md new file mode 100644 index 0000000000..494a69911b --- /dev/null +++ b/.changelog/unreleased/dependencies/xxx-bump-ibc.md @@ -0,0 +1,3 @@ +- Bump [ibc-go](https://github.com/cosmos/ibc-go) to + [v8.2.1](https://github.com/cosmos/ibc-go/releases/tag/v8.2.1). + ([\#xx](https://github.com/cosmos/interchain-security/pull/1698)) \ No newline at end of file diff --git a/.changelog/unreleased/dependencies/xxx-bump-sdk.md b/.changelog/unreleased/dependencies/xxx-bump-sdk.md new file mode 100644 index 0000000000..9c38164b12 --- /dev/null +++ b/.changelog/unreleased/dependencies/xxx-bump-sdk.md @@ -0,0 +1,3 @@ +- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to +[v0.50.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.5) +([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) \ No newline at end of file diff --git a/.changelog/unreleased/state-breaking/provider/1925-apply-audit-suggestions.md b/.changelog/unreleased/state-breaking/provider/1925-apply-audit-suggestions.md deleted file mode 100644 index 3d12033a4e..0000000000 --- a/.changelog/unreleased/state-breaking/provider/1925-apply-audit-suggestions.md +++ /dev/null @@ -1,3 +0,0 @@ -- Apply audit suggestions that include a bug fix in the way we compute the - maximum capped power. ([\#1925](https://github.com/cosmos/interchain- - security/pull/1925)) diff --git a/.changelog/unreleased/state-breaking/xxx-bump-comet.md b/.changelog/unreleased/state-breaking/xxx-bump-comet.md new file mode 100644 index 0000000000..045e29ce3d --- /dev/null +++ b/.changelog/unreleased/state-breaking/xxx-bump-comet.md @@ -0,0 +1,3 @@ +- Bump [CometBFT](https://github.com/cometbft/cometbft) to + [v0.38.7](https://github.com/cometbft/cometbft/releases/tag/v0.38.7). + ([\#xxx](https://github.com/cosmos/interchain-security/pull/xxx)) \ No newline at end of file diff --git a/.changelog/unreleased/state-breaking/xxx-bump-ibc.md b/.changelog/unreleased/state-breaking/xxx-bump-ibc.md new file mode 100644 index 0000000000..494a69911b --- /dev/null +++ b/.changelog/unreleased/state-breaking/xxx-bump-ibc.md @@ -0,0 +1,3 @@ +- Bump [ibc-go](https://github.com/cosmos/ibc-go) to + [v8.2.1](https://github.com/cosmos/ibc-go/releases/tag/v8.2.1). + ([\#xx](https://github.com/cosmos/interchain-security/pull/1698)) \ No newline at end of file diff --git a/.changelog/unreleased/state-breaking/xxx-bump-sdk.md b/.changelog/unreleased/state-breaking/xxx-bump-sdk.md new file mode 100644 index 0000000000..9c38164b12 --- /dev/null +++ b/.changelog/unreleased/state-breaking/xxx-bump-sdk.md @@ -0,0 +1,3 @@ +- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to +[v0.50.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.5) +([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) \ No newline at end of file diff --git a/.changelog/unreleased/bug-fixes/1921-write-stderr.md b/.changelog/v4.3.0/bug-fixes/1921-write-stderr.md similarity index 100% rename from .changelog/unreleased/bug-fixes/1921-write-stderr.md rename to .changelog/v4.3.0/bug-fixes/1921-write-stderr.md diff --git a/.changelog/v4.3.0/bug-fixes/provider/1925-apply-audit-suggestions.md b/.changelog/v4.3.0/bug-fixes/provider/1925-apply-audit-suggestions.md new file mode 100644 index 0000000000..5c9d04c2e7 --- /dev/null +++ b/.changelog/v4.3.0/bug-fixes/provider/1925-apply-audit-suggestions.md @@ -0,0 +1,3 @@ +- Apply audit suggestions that include a bug fix in the way we compute the + maximum capped power. + ([\#1925](https://github.com/cosmos/interchain-security/pull/1925)) diff --git a/.changelog/unreleased/bug-fixes/provider/1946-get-consumer-chains.md b/.changelog/v4.3.0/bug-fixes/provider/1946-get-consumer-chains.md similarity index 100% rename from .changelog/unreleased/bug-fixes/provider/1946-get-consumer-chains.md rename to .changelog/v4.3.0/bug-fixes/provider/1946-get-consumer-chains.md diff --git a/.changelog/v4.3.0/dependencies/1974-bump-ibc.md b/.changelog/v4.3.0/dependencies/1974-bump-ibc.md new file mode 100644 index 0000000000..f8b953459e --- /dev/null +++ b/.changelog/v4.3.0/dependencies/1974-bump-ibc.md @@ -0,0 +1,3 @@ +- Bump [ibc-go](https://github.com/cosmos/ibc-go) to + [v7.6.0](https://github.com/cosmos/ibc-go/releases/tag/v7.6.0). + ([\#1974](https://github.com/cosmos/interchain-security/pull/1974)) \ No newline at end of file diff --git a/.changelog/v4.3.0/features/provider/1932-allow-pss-params-changes.md b/.changelog/v4.3.0/features/provider/1932-allow-pss-params-changes.md new file mode 100644 index 0000000000..0bbbac5ffa --- /dev/null +++ b/.changelog/v4.3.0/features/provider/1932-allow-pss-params-changes.md @@ -0,0 +1,2 @@ +- Allow consumer chains to change their PSS parameters. + ([\#1932](https://github.com/cosmos/interchain-security/pull/1932)) diff --git a/.changelog/unreleased/improvements/provider/1929-distribute-rewards-to-long-term-validating-validators.md b/.changelog/v4.3.0/improvements/provider/1929-distribute-rewards-to-long-term-validating-validators.md similarity index 100% rename from .changelog/unreleased/improvements/provider/1929-distribute-rewards-to-long-term-validating-validators.md rename to .changelog/v4.3.0/improvements/provider/1929-distribute-rewards-to-long-term-validating-validators.md diff --git a/.changelog/v4.3.0/state-breaking/1974-bump-ibc.md b/.changelog/v4.3.0/state-breaking/1974-bump-ibc.md new file mode 100644 index 0000000000..f8b953459e --- /dev/null +++ b/.changelog/v4.3.0/state-breaking/1974-bump-ibc.md @@ -0,0 +1,3 @@ +- Bump [ibc-go](https://github.com/cosmos/ibc-go) to + [v7.6.0](https://github.com/cosmos/ibc-go/releases/tag/v7.6.0). + ([\#1974](https://github.com/cosmos/interchain-security/pull/1974)) \ No newline at end of file diff --git a/.changelog/unreleased/bug-fixes/provider/1925-apply-audit-suggestions.md b/.changelog/v4.3.0/state-breaking/provider/1925-apply-audit-suggestions.md similarity index 81% rename from .changelog/unreleased/bug-fixes/provider/1925-apply-audit-suggestions.md rename to .changelog/v4.3.0/state-breaking/provider/1925-apply-audit-suggestions.md index 3d12033a4e..018c0eafb1 100644 --- a/.changelog/unreleased/bug-fixes/provider/1925-apply-audit-suggestions.md +++ b/.changelog/v4.3.0/state-breaking/provider/1925-apply-audit-suggestions.md @@ -1,3 +1,2 @@ - Apply audit suggestions that include a bug fix in the way we compute the - maximum capped power. ([\#1925](https://github.com/cosmos/interchain- - security/pull/1925)) + maximum capped power. ([\#1925](https://github.com/cosmos/interchain-security/pull/1925)) diff --git a/.changelog/unreleased/state-breaking/provider/1929-distribute-rewards-to-long-term-validating-validators.md b/.changelog/v4.3.0/state-breaking/provider/1929-distribute-rewards-to-long-term-validating-validators.md similarity index 100% rename from .changelog/unreleased/state-breaking/provider/1929-distribute-rewards-to-long-term-validating-validators.md rename to .changelog/v4.3.0/state-breaking/provider/1929-distribute-rewards-to-long-term-validating-validators.md diff --git a/.changelog/v4.3.0/state-breaking/provider/1932-allow-pss-params-changes.md b/.changelog/v4.3.0/state-breaking/provider/1932-allow-pss-params-changes.md new file mode 100644 index 0000000000..0bbbac5ffa --- /dev/null +++ b/.changelog/v4.3.0/state-breaking/provider/1932-allow-pss-params-changes.md @@ -0,0 +1,2 @@ +- Allow consumer chains to change their PSS parameters. + ([\#1932](https://github.com/cosmos/interchain-security/pull/1932)) diff --git a/.changelog/v4.3.0/summary.md b/.changelog/v4.3.0/summary.md new file mode 100644 index 0000000000..f633d1635e --- /dev/null +++ b/.changelog/v4.3.0/summary.md @@ -0,0 +1 @@ +*June 20, 2024* diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0a55a2d111..61976cf2f3 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -22,7 +22,7 @@ updates: directory: "/" schedule: interval: daily - target-branch: "release/v4.1.x" + target-branch: "release/v4.2.x" # Only allow automated security-related dependency updates on release branches. open-pull-requests-limit: 0 labels: @@ -32,17 +32,17 @@ updates: directory: "/" schedule: interval: daily - target-branch: "release/v4.1.x-lsm" + target-branch: "release/v4.2.x-lsm" # Only allow automated security-related dependency updates on release branches. open-pull-requests-limit: 0 labels: - dependencies - - package-ecosystem: gomod + - package-ecosystem: gomod directory: "/" schedule: interval: daily - target-branch: "release/v4.2.x" + target-branch: "release/v4.3.x" # Only allow automated security-related dependency updates on release branches. open-pull-requests-limit: 0 labels: @@ -52,7 +52,7 @@ updates: directory: "/" schedule: interval: daily - target-branch: "release/v4.2.x-lsm" + target-branch: "release/v4.3.x-lsm" # Only allow automated security-related dependency updates on release branches. open-pull-requests-limit: 0 labels: @@ -68,3 +68,13 @@ updates: labels: - dependencies + - package-ecosystem: gomod + directory: "/" + schedule: + interval: daily + target-branch: "release/v5.1.x" + # Only allow automated security-related dependency updates on release branches. + open-pull-requests-limit: 0 + labels: + - dependencies + diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index bb9c86a3f9..b04cc8d6ff 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -80,7 +80,7 @@ jobs: # https://github.com/docker/build-push-action - name: Build and push Docker image id: build-and-push - uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 #v5.3.0 + uses: docker/build-push-action@31159d49c0d4756269a0940a750801a1ea5d7003 #v6.1.0 with: context: . file: ./Dockerfile diff --git a/.github/workflows/proto-registry.yml b/.github/workflows/proto-registry.yml index 0dd39a112c..f1f52b55c7 100644 --- a/.github/workflows/proto-registry.yml +++ b/.github/workflows/proto-registry.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: bufbuild/buf-setup-action@v1.32.2 + - uses: bufbuild/buf-setup-action@v1.34.0 - uses: bufbuild/buf-push-action@v1 with: input: "proto" diff --git a/.github/workflows/proto.yml b/.github/workflows/proto.yml index 68f31f2b67..e9f040fc44 100644 --- a/.github/workflows/proto.yml +++ b/.github/workflows/proto.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: bufbuild/buf-setup-action@v1.32.2 + - uses: bufbuild/buf-setup-action@v1.34.0 - uses: bufbuild/buf-breaking-action@v1 with: input: "proto" diff --git a/.mergify.yml b/.mergify.yml index d373fe3fb9..c5825b5bf8 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -10,38 +10,39 @@ queue_rules: - "#approved-reviews-by>1" pull_request_rules: - - name: Backport patches to the release/v4.1.x branch + - name: Backport patches to the release/v4.2.x branch conditions: - base=main - - label=A:backport/v4.1.x + - label=A:backport/v4.2.x actions: backport: branches: - - release/v4.1.x - - name: Backport patches to the release/v4.1.x-lsm branch + - release/v4.2.x + - name: Backport patches to the release/v4.2.x-lsm branch conditions: - base=main - - label=A:backport/v4.1.x-lsm + - label=A:backport/v4.2.x-lsm actions: backport: branches: - - release/v4.1.x-lsm - - name: Backport patches to the release/v4.2.x branch + - release/v4.2.x-lsm +pull_request_rules: + - name: Backport patches to the release/v4.3.x branch conditions: - base=main - - label=A:backport/v4.2.x + - label=A:backport/v4.3.x actions: backport: branches: - - release/v4.2.x - - name: Backport patches to the release/v4.2.x-lsm branch + - release/v4.3.x + - name: Backport patches to the release/v4.3.x-lsm branch conditions: - base=main - - label=A:backport/v4.2.x-lsm + - label=A:backport/v4.3.x-lsm actions: backport: branches: - - release/v4.2.x-lsm + - release/v4.3.x-lsm - name: Backport patches to the release/v5.x branch conditions: - base=main @@ -50,3 +51,11 @@ pull_request_rules: backport: branches: - release/v5.x + - name: Backport patches to the release/v5.1.x branch + conditions: + - base=main + - label=A:backport/v5.1.x + actions: + backport: + branches: + - release/v5.1.x diff --git a/CHANGELOG.md b/CHANGELOG.md index 666321b346..e431bb8dfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,143 @@ # CHANGELOG +## v5.0.0 + +❗ *The provider module should not be used with this version.* + +*May 9, 2024* + +### DEPENDENCIES + +- Bump [ibc-go](https://github.com/cosmos/ibc-go) to + [v8.1.x](https://github.com/cosmos/ibc-go/releases/tag/v8.1.0). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) +- Bump [CometBFT](https://github.com/cometbft/cometbft) to + [v0.38.4\5](https://github.com/cometbft/cometbft/releases/tag/v0.38.5). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) +- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to +[v0.50.x](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.4) +([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) + +### FEATURES + +- [Consumer](x/ccv/consumer) + - Add consumer `MsgUpdateParams` from [cosmos-sdk](https://github.com/cosmos/cosmos-sdk). + ([\#1814](https://github.com/cosmos/interchain-security/pull/1814)). +- [Provider](x/ccv/provider) + - Add provider `MsgUpdateParams` from [cosmos-sdk](https://github.com/cosmos/cosmos-sdk). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)). + +### STATE BREAKING + +- Bump [ibc-go](https://github.com/cosmos/ibc-go) to + [v8.1.x](https://github.com/cosmos/ibc-go/releases/tag/v8.1.0). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) +- Bump [CometBFT](https://github.com/cometbft/cometbft) to + [v0.38.4\5](https://github.com/cometbft/cometbft/releases/tag/v0.38.5). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) +- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to +[v0.50.x](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.4) +([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) +- Revert `PutUnbondingOnHold` behavior to ICS@v1 +([\#1819](https://github.com/cosmos/interchain-security/pull/1819)) + +## v4.3.0 + +*June 20, 2024* + +### BUG FIXES + +- General + - Write unbonding period advisory to stderr instead of stdout + ([\#1921](https://github.com/cosmos/interchain-security/pull/1921)) +- [Provider](x/ccv/provider) + - Apply audit suggestions that include a bug fix in the way we compute the + maximum capped power. + ([\#1925](https://github.com/cosmos/interchain-security/pull/1925)) + - Replace `GetAllConsumerChains` with lightweight version + (`GetAllRegisteredConsumerChainIDs`) that doesn't call into the staking module + ([\#1946](https://github.com/cosmos/interchain-security/pull/1946)) + +### DEPENDENCIES + +- Bump [ibc-go](https://github.com/cosmos/ibc-go) to + [v7.6.0](https://github.com/cosmos/ibc-go/releases/tag/v7.6.0). + ([\#1974](https://github.com/cosmos/interchain-security/pull/1974)) + +### FEATURES + +- [Provider](x/ccv/provider) + - Allow consumer chains to change their PSS parameters. + ([\#1932](https://github.com/cosmos/interchain-security/pull/1932)) + +### IMPROVEMENTS + +- [Provider](x/ccv/provider) + - Only start distributing rewards to validators after they have been validating + for a fixed number of blocks. Introduces the `NumberOfEpochsToStartReceivingRewards` param. + ([\#1929](https://github.com/cosmos/interchain-security/pull/1929)) + +### STATE BREAKING + +- General + - Bump [ibc-go](https://github.com/cosmos/ibc-go) to + [v7.6.0](https://github.com/cosmos/ibc-go/releases/tag/v7.6.0). + ([\#1974](https://github.com/cosmos/interchain-security/pull/1974)) +- [Provider](x/ccv/provider) + - Apply audit suggestions that include a bug fix in the way we compute the + maximum capped power. ([\#1925](https://github.com/cosmos/interchain-security/pull/1925)) + - Only start distributing rewards to validators after they have been validating + for a fixed number of blocks. Introduces the `NumberOfEpochsToStartReceivingRewards` param. + ([\#1929](https://github.com/cosmos/interchain-security/pull/1929)) + - Allow consumer chains to change their PSS parameters. + ([\#1932](https://github.com/cosmos/interchain-security/pull/1932)) + +## v4.2.0 + +May 17, 2024 + +### API BREAKING + +- [Provider](x/ccv/provider) + - Assigning a key that is already assigned by the same validator will now be a no-op instead of throwing an error. + ([\#1732](https://github.com/cosmos/interchain-security/pull/1732)) + - Changes the `list-consumer-chains` query to include a `min_power_in_top_N` field, as well as fields for all power shaping parameters of the consumer. + ([\#1863](https://github.com/cosmos/interchain-security/pull/1863)) + +### DEPENDENCIES + +- Bump [CometBFT](https://github.com/cometbft/cometbft) to + [v0.37.6](https://github.com/cometbft/cometbft/releases/tag/v0.37.6). + ([\#1876](https://github.com/cosmos/interchain-security/pull/1876)) +- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to + [v0.47.11](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.11). + ([\#1876](https://github.com/cosmos/interchain-security/pull/1876)) + +### FEATURES + +- [Provider](x/ccv/provider) + - Enable Opt In and Top N chains through gov proposals. + ([\#1587](https://github.com/cosmos/interchain-security/pull/1587)) + - Adding the Partial Set Security (PSS) feature cf. [ADR 015](https://cosmos.github.io/interchain-security/adrs/adr-015-partial-set-security). + PSS enables consumer chains to join ICS as _Top N_ or _Opt In_ chains and enables validators to opt to validate the consumer chains they want. + ([\#1809](https://github.com/cosmos/interchain-security/pull/1809)) + - Introduce power-shaping features for consumer chains. The features: (i) allow us to cap the total number of validators that can validate the consumer chain, (ii) set a cap on the maximum voting power (percentage-wise) a validator can have on a consumer chain, and (iii) introduce allowlist and denylists to restrict which validators are allowed or not to validate a consumer chain. + ([\#1830](https://github.com/cosmos/interchain-security/pull/1830)) + - Changes the `list-consumer-chains` query to include a `min_power_in_top_N` field, as well as fields for all power shaping parameters of the consumer. + ([\#1863](https://github.com/cosmos/interchain-security/pull/1863)) + - Introduces the `consumer-validators` query to retrieve the latest set consumer-validator set for a consumer chain. + ([\#1863](https://github.com/cosmos/interchain-security/pull/1867)) + +### STATE BREAKING + +- [Provider](x/ccv/provider) + - Enable Opt In and Top N chains through gov proposals. + ([\#1587](https://github.com/cosmos/interchain-security/pull/1587)) + - Assigning a key that is already assigned by the same validator will now be a no-op instead of throwing an error. + ([\#1732](https://github.com/cosmos/interchain-security/pull/1732)) + - Adding the Partial Set Security feature cf. [ADR 015](https://cosmos.github.io/interchain-security/adrs/adr-015-partial-set-security). + ([\#1809](https://github.com/cosmos/interchain-security/pull/1809)) + - Introduce power-shaping features for consumer chains. The features: (i) allow us to cap the total number of validators that can validate the consumer chain, (ii) set a cap on the maximum voting power (percentage-wise) a validator can have on a consumer chain, and (iii) introduce allowlist and denylists to restrict which validators are allowed or not to validate a consumer chain. + ([\#1830](https://github.com/cosmos/interchain-security/pull/1830)) ## v5.0.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8b8389315e..b6aa96afba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -109,7 +109,7 @@ If your architecture decision is a simple change, you may contribute directly wi In certain circumstances, the architecture decision may require changes to the ICS spec. Note that the spec is responsible for defining language-agnostic, implementation-agnostic behaviors for the ICS protocol. Whereas ADRs are responsible for communicating implementation decisions contained within this repo. -To create an ADR, follow the [template](docs/docs/adrs/adr-template.md) and [doc](docs/docs/adrs/intro.md). If you would like to see examples of how these are written, please refer to the current [ADRs](docs/docs/adrs). +To create an ADR, follow the [template](docs/docs/adrs/templates/adr-template.md) and [doc](docs/docs/adrs/intro.md). If you would like to see examples of how these are written, please refer to the current [ADRs](docs/docs/adrs). ### ADR Proposals @@ -179,7 +179,7 @@ Additionally, **each PR should only address a single issue**. ### Pull Request Templates -There are three PR templates. The [default template](./.github/PULL_REQUEST_TEMPLATE.md) contains links to the three templates. Please go the the `Preview` tab and select the appropriate sub-template: +There are three PR templates. The [default template](./.github/PULL_REQUEST_TEMPLATE.md) contains links to the three templates. Please go to the `Preview` tab and select the appropriate sub-template: - The [production template](./.github/PULL_REQUEST_TEMPLATE/production.md) is for types `fix`, `feat`, and `refactor`. - The [docs template](./.github/PULL_REQUEST_TEMPLATE/docs.md) is for documentation changes. diff --git a/FEATURES.md b/FEATURES.md index f9a54e0589..31d4066926 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -2,19 +2,20 @@ The following table indicates the major ICS features available in the [currently active releases](./RELEASES.md#version-matrix): -| Feature | `v3.2.0` | `v3.3.0` | `v3.3.3-lsm` | `v4.0.0` | `v4.1.1` | `v4.1.1-lsm` | -|---------|---------:|---------:|-------------:|---------:|---------:|-------------:| -| [Channel initialization: new chains](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#channel-initialization-new-chains) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Validator set update](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#validator-set-update) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Completion of unbonding operations](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#completion-of-unbonding-operations) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Consumer initiated slashing](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#consumer-initiated-slashing) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Reward distribution](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#reward-distribution) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Consumer chain removal](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#consumer-chain-removal) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Key assignment](https://github.com/cosmos/interchain-security/issues/26) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Jail throttling](https://github.com/cosmos/interchain-security/issues/404) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Soft opt-out](https://github.com/cosmos/interchain-security/issues/851) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Channel initialization: existing chains](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#channel-initialization-existing-chains) (aka [Standalone to consumer changeover](https://github.com/cosmos/interchain-security/issues/756)) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Cryptographic verification of equivocation](https://github.com/cosmos/interchain-security/issues/732) | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Jail throttling with retries](https://github.com/cosmos/interchain-security/issues/713) - consumer-side changes | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [Jail throttling with retries](https://github.com/cosmos/interchain-security/issues/713) - [provider-side changes](https://github.com/cosmos/interchain-security/issues/1102) | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | -| [ICS epochs](https://cosmos.github.io/interchain-security/adrs/adr-014-epochs) | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | +| Feature | `v3.2.0` | `v4.0.0` | `v4.2.0` | `v4.2.0-lsm` | `v5.0.0` | +|---------|---------:|---------:|---------:|-------------:|---------:| +| [Channel initialization: new chains](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#channel-initialization-new-chains) | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Validator set update](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#validator-set-update) | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Completion of unbonding operations](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#completion-of-unbonding-operations) | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Consumer initiated slashing](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#consumer-initiated-slashing) | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Reward distribution](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#reward-distribution) | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Consumer chain removal](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/methods.md#consumer-chain-removal) | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Key assignment](https://github.com/cosmos/interchain-security/issues/26) | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Jail throttling](https://github.com/cosmos/interchain-security/issues/404) | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Soft opt-out](https://github.com/cosmos/interchain-security/issues/851) | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Channel initialization: existing chains](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#channel-initialization-existing-chains) (aka [Standalone to consumer changeover](https://github.com/cosmos/interchain-security/issues/756)) | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Cryptographic verification of equivocation](https://github.com/cosmos/interchain-security/issues/732) | ❌ | ✅ | ✅ | ✅ | ✅ | +| [Jail throttling with retries](https://github.com/cosmos/interchain-security/issues/713) - consumer-side changes | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Jail throttling with retries](https://github.com/cosmos/interchain-security/issues/713) - [provider-side changes](https://github.com/cosmos/interchain-security/issues/1102) | ❌ | ✅ | ✅ | ✅ | ✅ | +| [ICS epochs](https://cosmos.github.io/interchain-security/adrs/adr-014-epochs) | ❌ | ❌ | ✅ | ✅ | ✅ | +| [Partial Set Security](https://cosmos.github.io/interchain-security/adrs/adr-015-partial-set-security) | ❌ | ❌ | ✅ | ✅ | ❌ | diff --git a/RELEASES.md b/RELEASES.md index b1d3eefa22..983af29995 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -7,7 +7,6 @@ - [Stable Release Policy](#stable-release-policy) - [Version Matrix](#version-matrix) - [Backwards Compatibility](#backwards-compatibility) - - [Notes](#notes) ## Semantic Versioning @@ -31,7 +30,7 @@ This includes events, queries, CLI interfaces. ## Release Cycle ICS follows a traditional release cycle involving release candidates (RCs) releases before finalizing a new version. -The stable release guarantees do not go into affect until a final release is performed. +The stable release guarantees do not go into effect until a final release is performed. ❗***It is never advisable to use a non-final release in production.*** @@ -60,13 +59,12 @@ All missing minor release versions have been discontinued. | Release | End of Life Date | |---------|------------------| | `v3.2.x` | July 10, 2024 | -| `v3.3.x` | July 10, 2024 | -| `v3.3.x-lsm` | July 10, 2024 | | `v4.0.x` | January 24, 2025 | -| `v4.1.x` | January 24, 2025 | +| `v4.2.x` | January 24, 2025 | +| `v5.0.x` | May 9, 2025 | -**Note**: As of [Gaia v15.1.0](https://github.com/cosmos/gaia/releases/tag/v15.1.0), -the Cosmos Hub uses a fork of Cosmos SDK ([v0.47.10-ics-lsm](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.10-ics-lsm)) +**Note**: As of [Gaia v17.2.0](https://github.com/cosmos/gaia/releases/tag/v17.2.0), +the Cosmos Hub uses a fork of Cosmos SDK ([v0.47.15-ics-lsm](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.15-ics-lsm)) that contains the Liquid Staking Module (LSM). This means the Cosmos Hub requires a fork of ICS. This fork is maintained by the development team and released using the `-lsm` prefix. @@ -79,11 +77,10 @@ Versions of Golang, IBC, Cosmos SDK and CometBFT used by ICS in the currently ac | ICS | Golang | IBC | Cosmos SDK | CometBFT | Note | |-----|--------|-----|------------|----------|------| | [v3.2.0](https://github.com/cosmos/interchain-security/releases/tag/v3.2.0) | 1.20 | v7.3.0 | v0.47.5 | v0.37.2 | -| [v3.3.0](https://github.com/cosmos/interchain-security/releases/tag/v3.3.0) | 1.20 | v7.3.0 | v0.47.5 | v0.37.2 | -| [v3.3.3-lsm](https://github.com/cosmos/interchain-security/releases/tag/v3.3.3-lsm) | 1.20 | v7.3.1 | v0.47.10-ics-lsm | v0.37.4 | Provider only (Cosmos Hub specific) | | [v4.0.0](https://github.com/cosmos/interchain-security/releases/tag/v4.0.0) | 1.21 | v7.3.1 | v0.47.7 | v0.37.4 | Provider on >= v4.0.0 backwards compatible with consumers >= v3.2.0 | -| [v4.1.1](https://github.com/cosmos/interchain-security/releases/tag/v4.1.1) | 1.21 | v7.4.0 | v0.47.10 | v0.37.4 | -| [v4.1.1-lsm](https://github.com/cosmos/interchain-security/releases/tag/v4.1.1-lsm) | 1.21 | v7.4.0 | v0.47.12-ics-lsm | v0.37.4 | Provider only (Cosmos Hub specific) | +| [v4.2.0](https://github.com/cosmos/interchain-security/releases/tag/v4.2.0) | 1.21 | v7.4.0 | v0.47.11 | v0.37.6 | +| [v4.2.0-lsm](https://github.com/cosmos/interchain-security/releases/tag/v4.2.0-lsm) | 1.21 | v7.4.0 | v0.47.13-ics-lsm | v0.37.6 | Provider only (Cosmos Hub specific) | +| [v5.0.0](https://github.com/cosmos/interchain-security/releases/tag/v5.0.0) | 1.21 | v8.1.0 | v0.50.4 | v0.38.5 | **Note:** For a list of major ICS features available in the currently active releases, see [FEATURES.md](./FEATURES.md). @@ -93,15 +90,9 @@ A MAJOR version of ICS will always be backwards compatible with the previous MAJ The following table indicates the compatibility of currently active releases: -| Consumer | Provider | `v3.2.0` | `v3.3.0` | `v3.3.3-lsm` | `v4.0.0` | `v4.1.1-lsm` | -|----------|----------|----------|----------|--------------|----------|--------------| -| `v3.2.0` || ✅ | ✅ (1) | ✅ | ✅ | ✅ | -| `v3.3.0` || ✅ (1) | ✅ | ✅ | ✅ | ✅ | -| `v4.0.0` || ✅ (1)| ✅ (1)| ✅ (1) | ✅ | ✅ | -| `v4.1.1` || ✅ (1)| ✅ (1)| ✅ (1) | ✅ | ✅ | - -#### Notes - -The following adjustments must be made to the CCV consumer genesis state that is obtained from the provider chain after the spawn time is reached in order for the consumer chain to start without errors. - -- (1) Use `interchain-security-cd genesis transform` to transform the consumer genesis file obtained from the provider. \ No newline at end of file +| Consumer | Provider | `v4.2.0-lsm` | +|----------|----------|--------------| +| `v3.2.0` || ✅ | +| `v4.0.0` || ✅ | +| `v4.2.0` || ✅ | +| `v5.0.0` || ✅ | diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 3a172a79c4..d4350c895f 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -6,7 +6,7 @@ - the last release branch: --> -# Replicated Security Release Notes +# Interchain Security Release Notes -Check out the [changelog](https://github.com/cosmos/interchain-security/blob//CHANGELOG.md) for a list of relevant changes or [compare all changes](https://github.com/cosmos/interchain-security/compare/release/...) from last release. +Check out the [changelog](https://github.com/cosmos/interchain-security/blob//CHANGELOG.md) for a list of relevant changes or [compare all changes](https://github.com/cosmos/interchain-security/compare/...) from last release. Refer to the [upgrading guide](https://github.com/cosmos/interchain-security/blob/release//UPGRADING.md) when migrating from `` to ``. diff --git a/RELEASE_PROCESS.md b/RELEASE_PROCESS.md index 04d7731a72..1c26c8c5ff 100644 --- a/RELEASE_PROCESS.md +++ b/RELEASE_PROCESS.md @@ -12,7 +12,7 @@ This document outlines the release process for Interchain Security (ICS). For details on ICS releases, see [RELEASES.md](./RELEASES.md). -The procedure of cutting a major or minor release consist of the following steps: +The procedure of cutting a major or minor release consists of the following steps: - Create a new version section in the `CHANGELOG.md` (follow the procedure described [below](#changelog)) - Create release notes, in `RELEASE_NOTES.md`, highlighting the new features and changes in the version. @@ -71,7 +71,7 @@ Before cutting a _**release candidate**_ (e.g., `v3.3.0-rc0`), the following ste unclog release v3.3.0 ``` - `unclog release` requires an editor. This can be set either by configuring - an `$EDITOR` environment variable or by manually specify an editor binary path + an `$EDITOR` environment variable or by manually specifying an editor binary path via the `--editor` flag. - add the date as the summary of the release (`unclog release` requires adding a summary), e.g., ```md @@ -107,6 +107,78 @@ Once the **final release** is cut, the new changelog section must be added to ma ``` - open a PR (from this new created branch) against `main` +## Updating published docs + +### Before tagging a new release + +On your release branch, clear the `docs/versions.json` file so it looks like this: +```json +[] +``` + +If this file is populated on a release branch it will cause the tag to have extra files that the docs deploy process does not expect. This could cause the deploy process to fail in some situations. + +### After tagging a new release + +Go to `main` branch and update the `docs/versions.json` to include all the versions you want to publish on the docs page: +```json +[ + "v4.3.0", + "v5.0.0" +] +``` + +This will cause the docs to be built with `main`, `v4.3.0` and `v5.0.0`. + +In `docs/docusaurus.config.js` change the `preset` section to display the versions you chose in `docs/versions.json`. + +For example, here we remove v4.2.0 and replace it with v4.3.0. + +```diff + presets: [ + [ + "classic", + /** @type {import('@docusaurus/preset-classic').Options} */ + ({ + docs: { + sidebarPath: require.resolve("./sidebars.js"), + routeBasePath: "/", + versions: { + current: { + path: "/", + label: "main", + banner: "unreleased", + }, + // v4.2.0-docs was a special tags for docs + // this is not usually necessary +- "v4.2.0-docs": { +- path: "/v4.2.0/", +- label: "v4.2.0", +- banner: "none", +- }, ++ "v4.3.0": { ++ banner: "none", ++ }, + "v5.0.0": { + banner: "unreleased", + }, + }, + remarkPlugins: [remarkMath], + rehypePlugins: [rehypeKatex], + }, + + theme: { + customCss: require.resolve("./src/css/custom.css"), + }, + }), + ], + ], +``` + +The documentation is updated automatically whenever `main` is changed. + +To learn how to work with docs locally check the docs [README.md on main branch](https://github.com/cosmos/interchain-security/blob/main/docs/README.md) + ## Tagging Procedure **Important**: _**Always create tags from your local machine**_ since all release @@ -136,4 +208,4 @@ git push origin v3.2.0 ``` For final releases, once the tag is created, use the GitHub interface to create a release. -Note that this is not necessary for release candidates. \ No newline at end of file +Note that this is not necessary for release candidates. diff --git a/UPGRADING.md b/UPGRADING.md index 425fd511a3..9dbd730032 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -80,7 +80,7 @@ Upgrading the provider from `v2.x.y` to `v3.3.0` will not require state migratio ## [v3.2.x](https://github.com/cosmos/interchain-security/tree/release/v3.2.x) -`v3.2.0` bumps IBC to `v7.3`. As a result, `legacy_ibc_testing` is not longer required and was removed, see https://github.com/cosmos/interchain-security/pull/1185. This means that when upgrading to `v3.2.0`, any customized tests relying on `legacy_ibc_testing` need to be updated. +`v3.2.0` bumps IBC to `v7.3`. As a result, `legacy_ibc_testing` is no longer required and was removed, see https://github.com/cosmos/interchain-security/pull/1185. This means that when upgrading to `v3.2.0`, any customized tests relying on `legacy_ibc_testing` need to be updated. ### Consumer @@ -124,7 +124,7 @@ Legacy APIs of the `AppModule` interface have been removed from ccv modules. For #### Imports -Imports for ics23 have been updated as the repository have been migrated from confio to cosmos. +Imports for ics23 have been updated as the repository has been migrated from confio to cosmos. ```diff import ( diff --git a/app/consumer-democracy/app.go b/app/consumer-democracy/app.go index b7506eb0c7..50c2c1da29 100644 --- a/app/consumer-democracy/app.go +++ b/app/consumer-democracy/app.go @@ -582,7 +582,6 @@ func New( // CanWithdrawInvariant invariant. // NOTE: staking module is required if HistoricalEntries param > 0 // NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC) - // NOTE: the soft opt-out requires that the consumer module's beginblocker comes after the slashing module's beginblocker app.MM.SetOrderBeginBlockers( capabilitytypes.ModuleName, minttypes.ModuleName, diff --git a/app/consumer/app.go b/app/consumer/app.go index 3bf468b22f..ab86ec8b42 100644 --- a/app/consumer/app.go +++ b/app/consumer/app.go @@ -516,7 +516,6 @@ func New( // NOTE: Capability module must occur first so that it can initialize any capabilities // so that other modules that want to create or claim capabilities afterwards in InitChain // can do so safely. - // NOTE: the soft opt-out requires that the consumer module's beginblocker comes after the slashing module's beginblocker app.MM.SetOrderInitGenesis( capabilitytypes.ModuleName, authtypes.ModuleName, diff --git a/app/consumer/genesis.go b/app/consumer/genesis.go index 466c9df753..ed7e1e7831 100644 --- a/app/consumer/genesis.go +++ b/app/consumer/genesis.go @@ -80,6 +80,9 @@ func transformToNew(jsonRaw []byte, ctx client.Context) (json.RawMessage, error) oldConsumerGenesis.Params.RetryDelayPeriod = types.DefaultRetryDelayPeriod } + // `SoftOptOutThreshold` is deprecated in the current consumer implementation, so set to zero + oldConsumerGenesis.Params.SoftOptOutThreshold = "0" + // Versions before v3.3.x of provider genesis data fills up deprecated fields // ProviderClientState, ConsensusState and InitialValSet in type GenesisState newGenesis := types.ConsumerGenesisState{ diff --git a/app/consumer/genesis_test.go b/app/consumer/genesis_test.go index 2dd29e1b71..e91c8a66d5 100644 --- a/app/consumer/genesis_test.go +++ b/app/consumer/genesis_test.go @@ -494,7 +494,9 @@ func TestConsumerGenesisTransformationFromV2ToCurrent(t *testing.T) { require.EqualValues(t, srcGenesis.Params.ConsumerRedistributionFraction, resultGenesis.Params.ConsumerRedistributionFraction) require.EqualValues(t, srcGenesis.Params.HistoricalEntries, resultGenesis.Params.HistoricalEntries) require.EqualValues(t, srcGenesis.Params.UnbondingPeriod, resultGenesis.Params.UnbondingPeriod) - require.EqualValues(t, srcGenesis.Params.SoftOptOutThreshold, resultGenesis.Params.SoftOptOutThreshold) + + // `SoftOptOutThreshold` is deprecated, so it should be set to zero the current version + require.EqualValues(t, "0", resultGenesis.Params.SoftOptOutThreshold) require.EqualValues(t, srcGenesis.Params.RewardDenoms, resultGenesis.Params.RewardDenoms) require.EqualValues(t, srcGenesis.Params.ProviderRewardDenoms, resultGenesis.Params.ProviderRewardDenoms) @@ -565,7 +567,10 @@ func TestConsumerGenesisTransformationV330ToCurrent(t *testing.T) { require.Equal(t, srcGenesis.Params.ConsumerRedistributionFraction, resultGenesis.Params.ConsumerRedistributionFraction) require.Equal(t, srcGenesis.Params.HistoricalEntries, resultGenesis.Params.HistoricalEntries) require.Equal(t, srcGenesis.Params.UnbondingPeriod, resultGenesis.Params.UnbondingPeriod) - require.Equal(t, srcGenesis.Params.SoftOptOutThreshold, resultGenesis.Params.SoftOptOutThreshold) + + // `SoftOptOutThreshold` is deprecated, so it should be set to zero the current version + require.Equal(t, "0", resultGenesis.Params.SoftOptOutThreshold) + require.Equal(t, srcGenesis.Params.RewardDenoms, resultGenesis.Params.RewardDenoms) require.Equal(t, srcGenesis.Params.ProviderRewardDenoms, resultGenesis.Params.ProviderRewardDenoms) diff --git a/app/provider/app.go b/app/provider/app.go index 4c998bdc13..8ba64f7928 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -678,8 +678,6 @@ func New( panic(err) } - // create the simulation manager and define the order of the modules for deterministic simulations - // Note this upgrade handler is just an example and may not be exactly what you need to implement. // See https://docs.cosmos.network/v0.45/building-modules/upgrade.html app.UpgradeKeeper.SetUpgradeHandler( diff --git a/docs/build_deploy.sh b/docs/build_deploy.sh index 2e948cb55d..ba262e43b2 100755 --- a/docs/build_deploy.sh +++ b/docs/build_deploy.sh @@ -1,12 +1,13 @@ #!/bin/sh -echo "######### BUILD DOCS #########" - -# pull in the versions from versions.json -source ./sync_versions.sh - +# build versioned docs prepared by sync_versions.sh echo "building docusaurus main docs" npm ci && npm run build + +# copy "legacy" docs directory into the final build directory +# the directory is in "docs/legacy" of the source branch (legacy-docs-page) +# the build environment must be in "./docs" for this to work as expected +git checkout origin/legacy-docs-page -- legacy cp -r ./legacy ./build/ mv build ~/output echo "done building docusaurus main docs" diff --git a/docs/docs/adrs/adr-004-denom-dos-fixes.md b/docs/docs/adrs/adr-004-denom-dos-fixes.md index 7ca260f4f6..354eac337f 100644 --- a/docs/docs/adrs/adr-004-denom-dos-fixes.md +++ b/docs/docs/adrs/adr-004-denom-dos-fixes.md @@ -1,6 +1,6 @@ --- sidebar_position: 2 -title: ADR Template +title: Denom DOS fixes --- # ADR 004: Denom DOS fixes diff --git a/docs/docs/adrs/adr-005-cryptographic-equivocation-verification.md b/docs/docs/adrs/adr-005-cryptographic-equivocation-verification.md index 1e1a3f08cf..f47a658f4c 100644 --- a/docs/docs/adrs/adr-005-cryptographic-equivocation-verification.md +++ b/docs/docs/adrs/adr-005-cryptographic-equivocation-verification.md @@ -87,7 +87,7 @@ The application will, in turn, punish the malicious validator through jailing, t In the first part of the feature, we introduce a new endpoint: `HandleConsumerMisbehaviour(ctx sdk.Context, misbehaviour ibctmtypes.Misbehaviour)`. The main idea is to leverage the current IBC misbehaviour handling and update it to solely jail and slash the validators that performed a light client attack. Note that in this context, we assume that chains connected via a light client -share the same validator set, as is the case with Replicated Security. +share a subset of the validator set of the provider. This endpoint reuses the IBC client libraries to verify that the misbehaviour headers would have fooled the light client. Additionally, it’s crucial that the endpoint logic results in the slashing and jailing of validators under the same conditions diff --git a/docs/docs/adrs/adr-007-pause-unbonding-on-eqv-prop.md b/docs/docs/adrs/adr-007-pause-unbonding-on-eqv-prop.md index ce23051582..2e8e95d67f 100644 --- a/docs/docs/adrs/adr-007-pause-unbonding-on-eqv-prop.md +++ b/docs/docs/adrs/adr-007-pause-unbonding-on-eqv-prop.md @@ -1,6 +1,6 @@ --- sidebar_position: 2 -title: ADR Template +title: Pause validator unbonding during equivocation proposal --- # ADR 007: Pause validator unbonding during equivocation proposal diff --git a/docs/docs/adrs/adr-008-throttle-retries.md b/docs/docs/adrs/adr-008-throttle-retries.md index 710443bb65..8aad6153d4 100644 --- a/docs/docs/adrs/adr-008-throttle-retries.md +++ b/docs/docs/adrs/adr-008-throttle-retries.md @@ -19,7 +19,7 @@ Accepted For context on why the throttling mechanism exists, see [ADR 002](./adr-002-throttle.md). -Note the terms slash throttling and jail throttling are synonymous, since in replicated security a `SlashPacket` simply jails a validator for downtime infractions. +Note the terms slash throttling and jail throttling are synonymous, since in Interchain Security a `SlashPacket` simply jails a validator for downtime infractions. Currently the throttling mechanism is designed so that provider logic (slash meter, etc.) dictates how many `SlashPackets` can be handled over time. Throttled `SlashPackets` are persisted on the provider, leading to multiple possible issues. Namely: diff --git a/docs/docs/adrs/adr-009-soft-opt-out.md b/docs/docs/adrs/adr-009-soft-opt-out.md index b8dbc27124..defe885a96 100644 --- a/docs/docs/adrs/adr-009-soft-opt-out.md +++ b/docs/docs/adrs/adr-009-soft-opt-out.md @@ -7,11 +7,12 @@ title: Soft Opt-Out ## Changelog * 6/13/23: Initial draft of ADR. Feature already implemented and in production. +* 6/19/24: Change status to deprecated ## Status -Accepted - +Deprecated +Deprecated by [Partial Set Security](adr-015-partial-set-security.md) ## Context Some small validators may not have the resources needed to validate all consumer chains. Therefore a need exists to allow the bottom `x%` of validators to opt-out of validating a consumer chain. Meaning downtime infractions for these validators are dropped without ever reaching the provider. diff --git a/docs/docs/adrs/adr-010-standalone-changeover.md b/docs/docs/adrs/adr-010-standalone-changeover.md index e181b4c1f1..ed320738f5 100644 --- a/docs/docs/adrs/adr-010-standalone-changeover.md +++ b/docs/docs/adrs/adr-010-standalone-changeover.md @@ -14,7 +14,7 @@ Implemented ## Context -[Stride](https://github.com/Stride-Labs/stride) will be the first consumer to "changeover" from a standalone cosmos blockchain, to a consumer chain secured by the Cosmos Hub. This document will outline the changes made to the replicated security protocol to support this changeover process. +[Stride](https://github.com/Stride-Labs/stride) will be the first consumer to "changeover" from a standalone cosmos blockchain, to a consumer chain secured by the Cosmos Hub. This document outlines the changes made to support this changeover process. ## Decision @@ -26,7 +26,7 @@ The first step in the changeover process is to submit a ConsumerAdditionProposal Next, the standalone consumer chain runs an upgrade which adds the CCV module, and is properly setup to execute changeover logic. -The consumer upgrade height must be reached after the provider has created the new IBC client. Any replicated security validators who will run the consumer, but are not a part of the sovereign validator set, must sync up a full node before the consumer upgrade height is reached. The disk state of said full node will be used to run the consumer chain after the changeover has completed. +The consumer upgrade height must be reached after the provider has created the new IBC client. Any Interchain Security validators who will run the consumer, but are not a part of the sovereign validator set, must sync up a full node before the consumer upgrade height is reached. The disk state of said full node will be used to run the consumer chain after the changeover has completed. The meat of the changeover logic is that the consumer chain validator set is updated to that which was specified by the provider via the queried consumer genesis. Validators which were a part of the old set, but not the new set, are given zero voting power. Once these validator updates are given to Comet, the set is committed, and in effect 2 blocks later (see [FirstConsumerHeight](https://github.com/cosmos/interchain-security/blob/f10e780df182158d95a30f7cf94588b2d0479309/x/ccv/consumer/keeper/changeover.go#L19)). diff --git a/docs/docs/adrs/adr-017-allowing-inactive-validators.md b/docs/docs/adrs/adr-017-allowing-inactive-validators.md index 9a3715f135..f76f5f7069 100644 --- a/docs/docs/adrs/adr-017-allowing-inactive-validators.md +++ b/docs/docs/adrs/adr-017-allowing-inactive-validators.md @@ -67,7 +67,7 @@ set of consumer chains. To mitigate risks from validators with little stake, we introduce a minimum stake requirement for validators to be able to validate on consumer chains, which can be set by each consumer chain independently, with a default value set by the provider chain. -Additionally, we indepdently allow individual consumer chains to disable this feature, which will disallow validators from outside the provider active set from validating on the consumer chain and revert them to the previous behaviour of only considering validators of the provider that are part of the active consensus validator set. +Additionally, we independently allow individual consumer chains to disable this feature, which will disallow validators from outside the provider active set from validating on the consumer chain and revert them to the previous behaviour of only considering validators of the provider that are part of the active consensus validator set. Additional risk mitigations are to increase the active set size slowly, and to monitor the effects on the network closely. For the first iteration, we propose to increase the active set size to 200 validators (while keeping the consensus validators to 180), thus letting the 20 validators with the most stake outside of the active set validate on consumer chains. diff --git a/docs/docs/adrs/intro.md b/docs/docs/adrs/intro.md index fc7d06a152..110698c518 100644 --- a/docs/docs/adrs/intro.md +++ b/docs/docs/adrs/intro.md @@ -1,13 +1,13 @@ --- sidebar_position: 1 -title: ADRs +title: Overview --- -# Architecture Decision Records (ADR) +# Overview This is a location to record all high-level architecture decisions in the Interchain Security project. -You can read more about the ADR concept in this [blog post](https://product.reverb.com/documenting-architecture-decisions-the-reverb-way-a3563bb24bd0#.78xhdix6t). +You can read more about the Architecture Decision Record (ADR) concept in this [blog post](https://product.reverb.com/documenting-architecture-decisions-the-reverb-way-a3563bb24bd0#.78xhdix6t). An ADR should provide: @@ -26,7 +26,7 @@ If recorded decisions turned out to be lacking, convene a discussion, record the Note the context/background should be written in the present tense. -To suggest an ADR, please make use of the [ADR template](./adr-template.md) provided. +To suggest an ADR, please make use of the [ADR template](./templates/adr-template.md) provided. ## Table of Contents @@ -37,7 +37,6 @@ To suggest an ADR, please make use of the [ADR template](./adr-template.md) prov - [ADR 004: Denom DOS fixes](./adr-004-denom-dos-fixes.md) - [ADR 005: Cryptographic verification of equivocation evidence](./adr-005-cryptographic-equivocation-verification.md) - [ADR 008: Throttle with retries](./adr-008-throttle-retries.md) -- [ADR 009: Soft Opt-Out](./adr-009-soft-opt-out.md) - [ADR 010: Standalone to Consumer Changeover](./adr-010-standalone-changeover.md) - [ADR 013: Slashing on the provider for consumer equivocation](./adr-013-equivocation-slashing.md) - [ADR 014: Epochs](./adr-014-epochs.md) @@ -57,3 +56,4 @@ To suggest an ADR, please make use of the [ADR template](./adr-template.md) prov ### Deprecated - [ADR 003: Equivocation governance proposal](./adr-003-equivocation-gov-proposal.md) +- [ADR 009: Soft Opt-Out](./adr-009-soft-opt-out.md) diff --git a/docs/docs/adrs/adr-template.md b/docs/docs/adrs/templates/adr-template.md similarity index 100% rename from docs/docs/adrs/adr-template.md rename to docs/docs/adrs/templates/adr-template.md diff --git a/docs/docs/consumer-development/app-integration.md b/docs/docs/consumer-development/app-integration.md index 73c034d073..0671db05a7 100644 --- a/docs/docs/consumer-development/app-integration.md +++ b/docs/docs/consumer-development/app-integration.md @@ -10,8 +10,9 @@ To help you on your journey, the ICS team has provided multiple examples of a mi The source code for the example app can be found [here](https://github.com/cosmos/interchain-security/tree/main/app/consumer). -Please note that consumer chains do not implement the staking module - the validator set is replicated from the provider, meaning that the provider and the consumer use the same validator set and their stake on the provider directly determines their stake on the consumer. -At present there is no opt-in mechanism available, so all validators of the provider must also validate on the provider chain. +Please note that consumer chains do not implement the staking module - part of the validator set of the provider is replicated over to the consumer, +meaning that the consumer uses a subset of provider validator set and the stake of the validators on the provider determines their stake on the consumer. +Note that after the introduction of [Partial Set Security](../adrs/adr-015-partial-set-security.md), not all the provider validators have to validate a consumer chain (e.g., if `top_N != 100`). Your chain should import the consumer module from `x/consumer` and register it in the correct places in your `app.go`. The `x/consumer` module will allow your chain to communicate with the provider using the ICS protocol. The module handles all IBC communication with the provider, and it is a simple drop-in. diff --git a/docs/docs/consumer-development/changeover-procedure.md b/docs/docs/consumer-development/changeover-procedure.md index 332bade599..72da738d49 100644 --- a/docs/docs/consumer-development/changeover-procedure.md +++ b/docs/docs/consumer-development/changeover-procedure.md @@ -4,7 +4,7 @@ sidebar_position: 5 # Changeover Procedure -Chains that were not initially launched as consumers of replicated security can still participate in the protocol and leverage the economic security of the provider chain. The process where a standalone chain transitions to being a replicated consumer chain is called the **changeover procedure** and is part of the interchain security protocol. After the changeover, the new consumer chain will retain all existing state, including the IBC clients, connections and channels already established by the chain. +Chains that were **not** initially launched as consumers of Interchain Security can still participate in the protocol and leverage the economic security of the provider chain. The process where a standalone chain transitions to being a replicated consumer chain is called the **changeover procedure** and is part of the interchain security protocol. After the changeover, the new consumer chain will retain all existing state, including the IBC clients, connections and channels already established by the chain. The relevant protocol specifications are available below: * [ICS-28 with existing chains](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#channel-initialization-existing-chains). @@ -90,7 +90,7 @@ This `ConsumerGenesis` must be available on the standalone chain during the on-c ### 4. standalone chain upgrade -Performing the on-chain upgrade on the standalone chain will add the `ccv/consumer` module and allow the chain to become a `consumer` of replicated security. +Performing the on-chain upgrade on the standalone chain will add the `ccv/consumer` module and allow the chain to become a `consumer` of Interchain Security. :::caution The `ConsumerGenesis` must be exported to a file and placed in the correct folder on the standalone chain before the upgrade. @@ -154,9 +154,9 @@ Example of a consumer chain addition proposal (compare with the [ConsumerAdditio ```js // ConsumerAdditionProposal is a governance proposal on the provider chain to spawn a new consumer chain or add a standalone chain. -// If it passes, then all validators on the provider chain are expected to validate the consumer chain at spawn time. -// It is recommended that spawn time occurs after the proposal end time and that it is scheduled to happen before the standalone chain upgrade -// that sill introduce the ccv module. +// If it passes, then a subset (i.e., depends on `top_N` and on the power shaping parameters) of validators on the provider chain are expected +// to validate the consumer chain at spawn time. It is recommended that spawn time occurs after the proposal end time and that it is +// scheduled to happen before the standalone chain upgrade that sill introduce the ccv module. { // Title of the proposal "title": "Changeover Standalone chain", @@ -212,9 +212,34 @@ Example of a consumer chain addition proposal (compare with the [ConsumerAdditio // it is most relevant for chains performing a standalone to consumer changeover // in order to maintain the existing ibc transfer channel "distribution_transmission_channel": "channel-123" // NOTE: use existing transfer channel if available + // Corresponds to the percentage of validators that have to validate the chain under the Top N case. + // For example, 53 corresponds to a Top 53% chain, meaning that the top 53% provider validators by voting power + // have to validate the proposed consumer chain. top_N can either be 0 or any value in [50, 100]. + // A chain can join with top_N == 0 as an Opt In chain, or with top_N ∈ [50, 100] as a Top N chain. + "top_N": 95, + // Corresponds to the maximum power (percentage-wise) a validator can have on the consumer chain. For instance, if + // `validators_power_cap` is set to 32, it means that no validator can have more than 32% of the voting power on the + // consumer chain. Note that this might not be feasible. For example, think of a consumer chain with only + // 5 validators and with `validators_power_cap` set to 10%. In such a scenario, at least one validator would need + // to have more than 20% of the total voting power. Therefore, `validators_power_cap` operates on a best-effort basis. + "validators_power_cap": 0, + // Corresponds to the maximum number of validators that can validate a consumer chain. + // Only applicable to Opt In chains. Setting `validator_set_cap` on a Top N chain is a no-op. + "validator_set_cap": 0, + // Corresponds to a list of provider consensus addresses of validators that are the ONLY ones that can validate + // the consumer chain. + "allowlist": [], + // Corresponds to a list of provider consensus addresses of validators that CANNOT validate the consumer chain. + "denylist": [] } ``` +:::info +As seen in the `ConsumerAdditionProposal` example above, the changeover procedure can be used together with [Partial Set Security](../adrs/adr-015-partial-set-security.md). +This means, that a standalone chain can choose to only be validated by some of the validators of the provider chain by setting `top_N` appropriately, or by +additionally setting a validators-power cap, validator-set cap, etc. by using the [power-shaping parameters](../features/power-shaping.md). +::: + ## 3. Submit an Upgrade Proposal & Prepare for Changeover This proposal should add the ccv `consumer` module to your chain. diff --git a/docs/docs/features/democracy-modules.md b/docs/docs/features/democracy-modules.md index 5add40c67e..a89466d863 100644 --- a/docs/docs/features/democracy-modules.md +++ b/docs/docs/features/democracy-modules.md @@ -1,3 +1,7 @@ +--- +sidebar_position: 5 +--- + # Democracy modules This section is relevant for chains transitioning from a standalone chain and new consumer chains that require some functionality from the `x/staking` module. diff --git a/docs/docs/features/partial-set-security.md b/docs/docs/features/partial-set-security.md index 6405fe092b..4e221583b5 100644 --- a/docs/docs/features/partial-set-security.md +++ b/docs/docs/features/partial-set-security.md @@ -1,5 +1,5 @@ --- -sidebar_position: 5 +sidebar_position: 6 --- # Partial Set Security diff --git a/docs/docs/features/power-shaping.md b/docs/docs/features/power-shaping.md index 2f51aef8f0..0b065c3ac0 100644 --- a/docs/docs/features/power-shaping.md +++ b/docs/docs/features/power-shaping.md @@ -1,3 +1,7 @@ +--- +sidebar_position: 7 +--- + # Power Shaping To give consumer chains more flexibility in choosing their validator set, Interchain Security offers diff --git a/docs/docs/features/proposals.md b/docs/docs/features/proposals.md index 5f5457fc0a..44ea4f0298 100644 --- a/docs/docs/features/proposals.md +++ b/docs/docs/features/proposals.md @@ -77,14 +77,6 @@ Minimal example: } ``` -:::warning -Before the introduction of Partial Set Security, consumer chains typically included a "soft opt-out mechanism" -which allows the bottom N% of the provider's validators to not validate the consumer chain, without being jailed for downtime on the provider. -After the introduction of Partial Set Security, the use of the soft opt-out mechanism is discouraged, and consumer chains are -encouraged to use the topN parameter to not force validators with little stake to validate the chain. -::: - - ## `ConsumerModificationProposal` Proposal type used to change the power shaping parameters of a running consumer chain, as well as to change a Top N running consumer chain to an Opt-In chain and vice versa. diff --git a/docs/docs/features/reward-distribution.md b/docs/docs/features/reward-distribution.md index cc055107c9..e042605cdd 100644 --- a/docs/docs/features/reward-distribution.md +++ b/docs/docs/features/reward-distribution.md @@ -8,7 +8,7 @@ sidebar_position: 2 Sending and distributing rewards from consumer chains to the provider chain is handled by the [Reward Distribution sub-protocol](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md#reward-distribution). Consumer chains have the option of sharing (a portion of) their block rewards (inflation tokens and fees) with the provider chain validators and delegators. -In replicated security, block rewards are periodically sent from the consumer to the provider according to consumer chain parameters using an IBC transfer channel. +In Interchain Security, block rewards are periodically sent from the consumer to the provider according to consumer chain parameters using an IBC transfer channel. This channel is created during consumer chain initialization, unless it is provided via the `ConsumerAdditionProposal` when adding a new consumer chain. For more details, see the [reward distribution parameters](../introduction/params.md#reward-distribution-parameters). diff --git a/docs/docs/frequently-asked-questions.md b/docs/docs/frequently-asked-questions.md index c78dc89f0f..27623d22f6 100644 --- a/docs/docs/frequently-asked-questions.md +++ b/docs/docs/frequently-asked-questions.md @@ -80,7 +80,7 @@ Consumer chain upgrades are unlikely to impact the provider chain, as long as th ## How can I connect to the testnets? -Check out the [Joining Replicated Security testnet](./validators/joining-testnet.md) section. +Check out the [Joining Interchain Security testnet](./validators/joining-testnet.md) section. ## How do I start using ICS? diff --git a/docs/docs/index.mdx b/docs/docs/index.mdx index 9ad9a3e2da..2086a4f384 100644 --- a/docs/docs/index.mdx +++ b/docs/docs/index.mdx @@ -10,6 +10,6 @@ import homeCards from '/src/components/Cards/card-data/home-cards'; Welcome to the official Interchain Security module documentation for Cosmos-SDK based chains. -Here you can find information about replicated security, consumer chain development and instructions for validator onboarding. +Here you can find information about Interchain Security, consumer chain development and instructions for validator onboarding. diff --git a/docs/docs/introduction/terminology.md b/docs/docs/introduction/terminology.md index dd9cd57602..63668c9b43 100644 --- a/docs/docs/introduction/terminology.md +++ b/docs/docs/introduction/terminology.md @@ -29,14 +29,14 @@ A protocol built on IBC that allows delegators on a cosmos chain to re-delegate ## Consumer Chain Chain that is secured by the validator set of the provider, instead of its own. -Replicated security allows the provider chain validator set to validate blocks on the consumer chain. +Interchain Security allows a subset of the provider chain's validator set to validate blocks on the consumer chain. ## Standalone Chain -Chain that is secured by its own validator set. This chain does not participate in replicated security. +Chain that is secured by its own validator set. This chain does not participate in Interchain Security. Standalone chains may sometimes be called "sovereign" - the terms are synonymous. ## Changeover Procedure -Chains that were not initially launched as consumers of replicated security can still participate in the protocol and leverage the economic security of the provider chain. The process where a standalone chain transitions to being a replicated consumer chain is called the **changeover procedure** and is part of the interchain security protocol. After the changeover, the new consumer chain will retain all existing state, including the IBC clients, connections and channels already established by the chain. +Chains that were not initially launched as consumers of Interchain Security can still participate in the protocol and leverage the economic security of the provider chain. The process where a standalone chain transitions to being a replicated consumer chain is called the **changeover procedure** and is part of the interchain security protocol. After the changeover, the new consumer chain will retain all existing state, including the IBC clients, connections and channels already established by the chain. diff --git a/docs/docs/validators/changeover-procedure.md b/docs/docs/validators/changeover-procedure.md index edb738bed4..4ce6cb4714 100644 --- a/docs/docs/validators/changeover-procedure.md +++ b/docs/docs/validators/changeover-procedure.md @@ -73,16 +73,16 @@ Yes. Please assign your consensus key as stated above. -### Can I set up a new node to validate the `standalone/consumer` chain after it transitions to replicated security? +### Can I set up a new node to validate the `standalone/consumer` chain after it transitions to Interchain Security? Yes. If you are planning to do this please make sure that the node is synced with `standalone` network and to submit `AssignConsumerKey` tx before `spawn_time`. -### What happens to the `standalone` validator set after it transitions to replicated security? +### What happens to the `standalone` validator set after it transitions to Interchain Security? -The `standalone` chain validators will stop being validators after the first 3 blocks are created while using replicated security. The `standalone` validators will become **governors** and still can receive delegations if the `consumer` chain is using the `consumer-democracy` module. +The `standalone` chain validators will stop being validators after the first 3 blocks are created while using Interchain Security. The `standalone` validators will become **governors** and still can receive delegations if the `consumer` chain is using the `consumer-democracy` module. **Governors DO NOT VALIDATE BLOCKS**. diff --git a/docs/docs/validators/joining-testnet.md b/docs/docs/validators/joining-testnet.md index e07a28e7c3..d61be07e12 100644 --- a/docs/docs/validators/joining-testnet.md +++ b/docs/docs/validators/joining-testnet.md @@ -12,7 +12,7 @@ The experience gained in the testnet will prepare you for validating interchain :::tip Provider and consumer chain represent distinct networks and infrastructures operated by the same validator set. -For general information about running cosmos-sdk based chains check out the [validator basics](https://hub.cosmos.network/main/validators/validator-setup) and [Running a Node section](https://docs.cosmos.network/main/run-node/run-node) of Cosmos SDK docs. +For general information about running cosmos-sdk based chains check out the [validator basics](https://hub.cosmos.network/main/validators/validator-setup) and [Running a Node section](https://docs.cosmos.network/main/run-node/run-node) of Cosmos SDK docs ::: ## Joining the provider chain diff --git a/docs/docs/validators/overview.md b/docs/docs/validators/overview.md index ff22edb560..c1dbaea0e2 100644 --- a/docs/docs/validators/overview.md +++ b/docs/docs/validators/overview.md @@ -4,17 +4,22 @@ sidebar_position: 1 # Overview :::tip -We advise that you join the [Replicated Security testnet](https://github.com/cosmos/testnets/tree/master/interchain-security) to gain hands-on experience with running consumer chains. +We advise that you join the [Interchain Security testnet](https://github.com/cosmos/testnets/tree/master/interchain-security) to gain hands-on experience with running consumer chains. ::: -At present, replicated security requires all validators of the provider chain (ie. Cosmos Hub) to run validator nodes for all governance-approved consumer chains. +At present, Interchain Security requires some or all the validators of the provider chain (ie. Cosmos Hub) to run validator nodes for a consumer chain. +Whether a validator has to run a validator node for a consumer chain depends on whether the consumer chain is a Top N or an +Opt-In chain and also on the [power-shaping features](../features/power-shaping.md). A validator can use the +[`has-to-validate` query](./partial-set-security-for-validators.md#which-chains-does-a-validator-have-to-validate) +to keep track of all the chains it has to validate. -Once a `ConsumerAdditionProposal` passes, validators need to prepare to run the consumer chain binaries (these will be linked in their proposals) and set up validator nodes on governance-approved consumer chains. -Provider chain and consumer chains represent standalone chains that only share the validator set ie. the same validator operators are tasked with running all chains. +Once a `ConsumerAdditionProposal` passes, relevant validators need to prepare to run the consumer chain binaries (these will be linked in their proposals) and set up validator nodes on governance-approved consumer chains. + +Provider chain and consumer chains represent standalone chains that only share part of the validator set. :::info -To validate a consumer chain and be eligible for rewards validators are required to be in the active set of the provider chain (first 180 validators for Cosmos Hub). +To validate a consumer chain and be eligible for rewards, validators are required to be in the active set of the provider chain (first 180 validators for Cosmos Hub). ::: ## Startup sequence overview diff --git a/docs/docs/validators/withdraw_rewards.md b/docs/docs/validators/withdraw_rewards.md index 15d27b3006..caf37f22c7 100644 --- a/docs/docs/validators/withdraw_rewards.md +++ b/docs/docs/validators/withdraw_rewards.md @@ -16,7 +16,7 @@ the actual values of the `NumberOfEpochsToStartReceivingRewards` and `BlocksPerE Here are example steps for withdrawing rewards from consumer chains in the provider chain :::info -The examples used are from `rs-testnet`, the replicated security persistent testnet. +The examples used are from `rs-testnet`, the Interchain Security persistent testnet. Validator operator address: `cosmosvaloper1e5yfpc8l6g4808fclmlyd38tjgxuwshnmjkrq6` Self-delegation address: `cosmos1e5yfpc8l6g4808fclmlyd38tjgxuwshn7xzkvf` diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index e73d5e2a21..17ff9aeb7b 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -56,6 +56,7 @@ const config = { }, remarkPlugins: [remarkMath], rehypePlugins: [rehypeKatex], + exclude: ["**/templates/*"], }, theme: { diff --git a/proto/interchain_security/ccv/consumer/v1/consumer.proto b/proto/interchain_security/ccv/consumer/v1/consumer.proto index 959d06c087..e77b5c9a13 100644 --- a/proto/interchain_security/ccv/consumer/v1/consumer.proto +++ b/proto/interchain_security/ccv/consumer/v1/consumer.proto @@ -27,7 +27,10 @@ message CrossChainValidator { (cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey", (gogoproto.moretags) = "yaml:\"consensus_pubkey\"" ]; - bool opted_out = 4; + + // !!! DEPRECATED !!! opted_out is deprecated because after the introduction of Partial Set Security (PSS) + // we removed the soft opt-out feature. + bool opted_out = 4 [deprecated = true]; } // A record storing the state of a slash packet sent to the provider chain diff --git a/proto/interchain_security/ccv/provider/v1/query.proto b/proto/interchain_security/ccv/provider/v1/query.proto index 9e922a6096..9ea3aa6bec 100644 --- a/proto/interchain_security/ccv/provider/v1/query.proto +++ b/proto/interchain_security/ccv/provider/v1/query.proto @@ -11,7 +11,6 @@ import "interchain_security/ccv/v1/shared_consumer.proto"; import "interchain_security/ccv/v1/wire.proto"; import "tendermint/crypto/keys.proto"; import "cosmos_proto/cosmos.proto"; -import "amino/amino.proto"; service Query { // ConsumerGenesis queries the genesis state needed to start a consumer chain @@ -316,10 +315,8 @@ message QueryValidatorConsumerCommissionRateRequest { message QueryValidatorConsumerCommissionRateResponse { // The rate to charge delegators on the consumer chain, as a fraction string rate = 1 [ - (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false, - (amino.dont_omitempty) = true + (gogoproto.nullable) = false ]; } diff --git a/proto/interchain_security/ccv/provider/v1/tx.proto b/proto/interchain_security/ccv/provider/v1/tx.proto index 63defef60f..a417aab3c0 100644 --- a/proto/interchain_security/ccv/provider/v1/tx.proto +++ b/proto/interchain_security/ccv/provider/v1/tx.proto @@ -279,8 +279,7 @@ message MsgSetConsumerCommissionRate { string rate = 3 [ (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false, - (amino.dont_omitempty) = true + (gogoproto.nullable) = false ]; } diff --git a/proto/interchain_security/ccv/v1/shared_consumer.proto b/proto/interchain_security/ccv/v1/shared_consumer.proto index ce65df04a6..f1535df010 100644 --- a/proto/interchain_security/ccv/v1/shared_consumer.proto +++ b/proto/interchain_security/ccv/v1/shared_consumer.proto @@ -62,11 +62,8 @@ message ConsumerParams { google.protobuf.Duration unbonding_period = 9 [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; - // The threshold for the percentage of validators at the bottom of the set who - // can opt out of running the consumer chain without being punished. For - // example, a value of 0.05 means that the validators in the bottom 5% of the - // set can opt out - string soft_opt_out_threshold = 10; + // !!! DEPRECATED !!! soft_opt_out_threshold is deprecated. see docs/docs/adrs/adr-015-partial-set-security.md + string soft_opt_out_threshold = 10 [deprecated = true]; // Reward denoms. These are the denominations which are allowed to be sent to // the provider as rewards. diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index f50f23b41a..4a3e59876d 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -602,7 +602,10 @@ func (tr *Chain) startConsumerChain( consumerGenesis := ".app_state.ccvconsumer = " + tr.getConsumerGenesis(action.ProviderChain, action.ConsumerChain) consumerGenesisChanges := tr.testConfig.chainConfigs[action.ConsumerChain].GenesisChanges if consumerGenesisChanges != "" { - consumerGenesis = consumerGenesis + " | " + consumerGenesisChanges + " | " + action.GenesisChanges + consumerGenesis = consumerGenesis + " | " + consumerGenesisChanges + } + if action.GenesisChanges != "" { + consumerGenesis = consumerGenesis + " | " + action.GenesisChanges } tr.startChain(StartChainAction{ @@ -832,7 +835,10 @@ func (tr Chain) changeoverChain( consumerGenesis := ".app_state.ccvconsumer = " + string(bz) consumerGenesisChanges := tr.testConfig.chainConfigs[action.SovereignChain].GenesisChanges if consumerGenesisChanges != "" { - consumerGenesis = consumerGenesis + " | " + consumerGenesisChanges + " | " + action.GenesisChanges + consumerGenesis = consumerGenesis + " | " + consumerGenesisChanges + } + if action.GenesisChanges != "" { + consumerGenesis = consumerGenesis + " | " + action.GenesisChanges } tr.startChangeover(ChangeoverChainAction{ @@ -2040,7 +2046,7 @@ func (tr Chain) invokeDoublesignSlash( if err != nil { log.Fatal(err, "\n", string(bz)) } - tr.waitBlocks("provi", 10, 2*time.Minute) + tr.waitBlocks("provi", 20, 4*time.Minute) } else { // tr.useCometMock validatorPrivateKeyAddress := tr.GetValidatorPrivateKeyAddress(action.Chain, action.Validator) diff --git a/tests/e2e/main.go b/tests/e2e/main.go index cf8fe70d89..d0b13ddd94 100644 --- a/tests/e2e/main.go +++ b/tests/e2e/main.go @@ -277,7 +277,7 @@ func parseArguments() (err error) { type testStepsWithConfig struct { config TestConfigType - steps []Step + steps StepChoice } func getTestCases(selectedPredefinedTests, selectedTestFiles TestSet, providerVersions, @@ -316,13 +316,12 @@ func getTestCases(selectedPredefinedTests, selectedTestFiles TestSet, providerVe log.Fatalf("Step choice '%s' not found.\nsee usage info:\n%s", tc, getTestCaseUsageString()) } - testSteps := stepChoices[tc].steps if testConfig == "" { testConfig = stepChoices[tc].testConfig } tests = append(tests, testStepsWithConfig{ config: testConfig, - steps: testSteps, + steps: stepChoices[tc], }, ) } @@ -351,7 +350,11 @@ func getTestCases(selectedPredefinedTests, selectedTestFiles TestSet, providerVe tests = append(tests, testStepsWithConfig{ config: testConfig, - steps: testCase, + steps: StepChoice{ + name: testFileName, + steps: testCase, + description: fmt.Sprintf("Steps from file %s", testFileName), + }, }) } diff --git a/tests/e2e/state.go b/tests/e2e/state.go index 1c1be7e95a..c7d5baf99f 100644 --- a/tests/e2e/state.go +++ b/tests/e2e/state.go @@ -888,7 +888,7 @@ func (tr Commands) GetTrustedHeight( var trustedHeight gjson.Result // iterate on the relayer's response - // and parse the the command "result" + // and parse the command "result" for scanner.Scan() { out := scanner.Text() if len(gjson.Get(out, "result").Array()) > 0 { diff --git a/tests/e2e/step_delegation.go b/tests/e2e/step_delegation.go index 102ee76fa2..531f0cbceb 100644 --- a/tests/e2e/step_delegation.go +++ b/tests/e2e/step_delegation.go @@ -220,58 +220,6 @@ func stepsCancelUnbond(consumerName string) []Step { } } -// stepsRedelegateForOptOut tests redelegation, and sets up voting powers s.t -// alice will have less than 5% of the total voting power. This is needed to -// test opt-out functionality. -func stepsRedelegateForOptOut(consumerName string) []Step { - return []Step{ - { - Action: RedelegateTokensAction{ - Chain: ChainID("provi"), - Src: ValidatorID("alice"), - Dst: ValidatorID("carol"), - TxSender: ValidatorID("alice"), - Amount: 450000000, - }, - State: State{ - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 60, - ValidatorID("bob"): 500, - ValidatorID("carol"): 950, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - // Voting power changes not seen by consumer yet - ValidatorID("alice"): 510, - ValidatorID("bob"): 500, - ValidatorID("carol"): 500, - }, - }, - }, - }, - { - Action: RelayPacketsAction{ - ChainA: ChainID("provi"), - ChainB: ChainID(consumerName), - Port: "provider", - Channel: 0, - }, - State: State{ - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - // Now power changes are seen by consumer - ValidatorID("alice"): 60, - ValidatorID("bob"): 500, - ValidatorID("carol"): 950, - }, - }, - }, - }, - } -} - // stepsRedelegate tests redelegation and resulting validator power changes. func stepsRedelegate(consumerName string) []Step { return []Step{ @@ -283,68 +231,15 @@ func stepsRedelegate(consumerName string) []Step { TxSender: ValidatorID("carol"), // redelegate s.t. alice has majority stake so non-faulty validators maintain more than // 2/3 voting power during downtime tests below, avoiding chain halt - Amount: 449000000, + Amount: 400000000, }, State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, // carol always uses a consumer assigned key - ValidatorID("carol"): 501, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - // Voting power changes not seen by consumer yet - ValidatorID("alice"): 60, - ValidatorID("bob"): 500, - ValidatorID("carol"): 950, - }, - }, - }, - }, - { - Action: RelayPacketsAction{ - ChainA: ChainID("provi"), - ChainB: ChainID(consumerName), - Port: "provider", - Channel: 0, - }, - State: State{ - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - // Now power changes are seen by consumer - ValidatorID("alice"): 509, - ValidatorID("bob"): 500, - ValidatorID("carol"): 501, - }, - }, - }, - }, - } -} - -// stepsRedelegate tests redelegation and resulting validator power changes. -func stepsRedelegateShort(consumerName string) []Step { - return []Step{ - { - Action: RedelegateTokensAction{ - Chain: ChainID("provi"), - Src: ValidatorID("alice"), - Dst: ValidatorID("carol"), - TxSender: ValidatorID("alice"), - // Leave alice with majority stake so non-faulty validators maintain more than - // 2/3 voting power during downtime tests below, avoiding chain halt - Amount: 1000000, - }, - State: State{ - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, - ValidatorID("bob"): 500, - // carol always uses a consumer assigned key - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ @@ -368,9 +263,9 @@ func stepsRedelegateShort(consumerName string) []Step { ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ // Now power changes are seen by consumer - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, diff --git a/tests/e2e/steps.go b/tests/e2e/steps.go index 4a6f40333e..5e16a61776 100644 --- a/tests/e2e/steps.go +++ b/tests/e2e/steps.go @@ -18,7 +18,7 @@ var compatibilitySteps = concatSteps( compstepsStartChains([]string{"consu"}, false), stepsDelegate("consu"), stepsUnbond("consu"), - stepsRedelegateShort("consu"), + stepsRedelegate("consu"), stepsDowntime("consu"), stepsDoubleSignOnProvider("consu"), // carol double signs on provider stepsStartRelayer(), @@ -32,8 +32,6 @@ var happyPathSteps = concatSteps( stepsAssignConsumerKeyOnStartedChain("consu", "bob"), stepsUnbond("consu"), stepsCancelUnbond("consu"), - stepsRedelegateForOptOut("consu"), - stepsDowntimeWithOptOut("consu"), stepsRedelegate("consu"), stepsDowntime("consu"), stepsDoubleSignOnProvider("consu"), // carol double signs on provider @@ -46,7 +44,7 @@ var shortHappyPathSteps = concatSteps( stepsStartChains([]string{"consu"}, false), stepsDelegate("consu"), stepsUnbond("consu"), - stepsRedelegateShort("consu"), + stepsRedelegate("consu"), stepsDowntime("consu"), stepsDoubleSignOnProvider("consu"), // carol double signs on provider stepsStartRelayer(), @@ -58,12 +56,12 @@ var lightClientAttackSteps = concatSteps( stepsStartChains([]string{"consu"}, false), stepsDelegate("consu"), stepsUnbond("consu"), - stepsRedelegateShort("consu"), + stepsRedelegate("consu"), stepsDowntime("consu"), stepsLightClientAttackOnProviderAndConsumer("consu"), // carol double signs on provider, bob double signs on consumer stepsStartRelayer(), - stepsConsumerRemovalPropNotPassing("consu", 3), // submit removal prop but vote no on it - chain should stay - stepsStopChain("consu", 4), // stop chain + stepsConsumerRemovalPropNotPassing("consu", 2), // submit removal prop but vote no on it - chain should stay + stepsStopChain("consu", 3), // stop chain ) var slashThrottleSteps = concatSteps( @@ -121,7 +119,7 @@ var changeoverSteps = concatSteps( var consumerMisbehaviourSteps = concatSteps( // start provider and consumer chain - stepsStartChainsWithSoftOptOut("consu"), + stepsStartChainsForConsumerMisbehaviour("consu"), // make a consumer validator to misbehave and get jailed stepsCauseConsumerMisbehaviour("consu"), ) @@ -137,6 +135,6 @@ var consumerDoubleDowntimeSteps = concatSteps( stepsStartChains([]string{"consu"}, false), stepsDelegate("consu"), stepsUnbond("consu"), - stepsRedelegateShort("consu"), + stepsRedelegate("consu"), stepsDoubleDowntime("consu"), ) diff --git a/tests/e2e/steps_compatibility.go b/tests/e2e/steps_compatibility.go index a51a34fed3..dfcf14cd58 100644 --- a/tests/e2e/steps_compatibility.go +++ b/tests/e2e/steps_compatibility.go @@ -146,12 +146,6 @@ func compstepsStartConsumerChain(consumerName string, proposalIndex, chainIndex {Id: ValidatorID("alice"), Stake: 500000000, Allocation: 10000000000}, {Id: ValidatorID("carol"), Stake: 500000000, Allocation: 10000000000}, }, - // For consumers that're launching with the provider being on an earlier version - // of ICS before the soft opt-out threshold was introduced, we need to set the - // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the - // consumer binary doesn't panic. Sdk requires that all params are set to valid - // values from the genesis file. - GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{ ChainID("provi"): ChainState{ diff --git a/tests/e2e/steps_consumer_misbehaviour.go b/tests/e2e/steps_consumer_misbehaviour.go index 56e093e668..1071da368a 100644 --- a/tests/e2e/steps_consumer_misbehaviour.go +++ b/tests/e2e/steps_consumer_misbehaviour.go @@ -7,10 +7,8 @@ import ( clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" ) -// starts a provider chain and a consumer chain with two validators, -// where the voting power is distributed in order that the smallest validator -// can soft opt-out of validating the consumer chain. -func stepsStartChainsWithSoftOptOut(consumerName string) []Step { +// starts a provider chain and an Opt-In consumer chain with one validator +func stepsStartChainsForConsumerMisbehaviour(consumerName string) []Step { s := []Step{ { // Create a provider chain with two validators, where one validator holds 96% of the voting power @@ -82,6 +80,13 @@ func stepsStartChainsWithSoftOptOut(consumerName string) []Step { }, }, }, + { + Action: OptInAction{ + Chain: ChainID(consumerName), + Validator: ValidatorID("alice"), + }, + State: State{}, + }, { Action: VoteGovProposalAction{ Chain: ChainID("provi"), @@ -109,19 +114,12 @@ func stepsStartChainsWithSoftOptOut(consumerName string) []Step { }, { // start a consumer chain using a single big validator knowing that it holds more than 2/3 of the voting power - // and that the other validators hold less than 5% so they won't get jailed thanks to the sof opt-out mechanism. Action: StartConsumerChainAction{ ConsumerChain: ChainID(consumerName), ProviderChain: ChainID("provi"), Validators: []StartChainValidator{ {Id: ValidatorID("alice"), Stake: 500000000, Allocation: 10000000000}, }, - // For consumers that're launching with the provider being on an earlier version - // of ICS before the soft opt-out threshold was introduced, we need to set the - // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the - // consumer binary doesn't panic. Sdk requires that all params are set to valid - // values from the genesis file. - GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{ ChainID("provi"): ChainState{ @@ -176,7 +174,6 @@ func stepsStartChainsWithSoftOptOut(consumerName string) []Step { ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 500, - ValidatorID("bob"): 20, }, }, }, @@ -192,7 +189,6 @@ func stepsStartChainsWithSoftOptOut(consumerName string) []Step { ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, - ValidatorID("bob"): 20, }, }, }, @@ -242,7 +238,7 @@ func stepsCauseConsumerMisbehaviour(consumerName string) []Step { ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, - ValidatorID("bob"): 20, + ValidatorID("bob"): 0, }, }, }, @@ -282,7 +278,7 @@ func stepsCauseConsumerMisbehaviour(consumerName string) []Step { // since its light client is frozen on the provider ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, - ValidatorID("bob"): 20, + ValidatorID("bob"): 0, }, }, }, diff --git a/tests/e2e/steps_double_sign.go b/tests/e2e/steps_double_sign.go index 353de13761..bdc4a68cb4 100644 --- a/tests/e2e/steps_double_sign.go +++ b/tests/e2e/steps_double_sign.go @@ -13,16 +13,16 @@ func stepsDoubleSignOnProvider(consumerName string) []Step { // slash on provider ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 0, // from 500 to 0 + ValidatorID("carol"): 0, // from 99 to 0 }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 495, // not tombstoned on consumerName yet + ValidatorID("carol"): 99, // not tombstoned on consumerName yet }, }, }, @@ -38,14 +38,14 @@ func stepsDoubleSignOnProvider(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, // tombstoning visible on consumerName }, diff --git a/tests/e2e/steps_downtime.go b/tests/e2e/steps_downtime.go index a8506bf518..70fd81c130 100644 --- a/tests/e2e/steps_downtime.go +++ b/tests/e2e/steps_downtime.go @@ -23,16 +23,16 @@ func stepsDowntime(consumerName string) []Step { // validator should be slashed on consumer, powers not affected on either chain yet ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -47,18 +47,18 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // Downtime jailing and corresponding voting power change are processed by provider ValidatorID("bob"): 0, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // Bob's stake may or may not be slashed at this point depending on comet vs cometmock // See https://github.com/cosmos/interchain-security/issues/1304 - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -75,10 +75,10 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // VSC now seen on consumer ValidatorID("bob"): 0, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -91,18 +91,18 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // bob's stake should not be slashed // since the slash was initiated from consumer ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 0, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -117,11 +117,11 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // bob's stake should not be slashed // since the slash was initiated from consumer ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -136,7 +136,7 @@ func stepsDowntime(consumerName string) []Step { ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ // Non faulty validators still maintain just above 2/3 power here - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, // Carol's stake should be slashed and jailed // downtime slash was initiated from provider @@ -145,9 +145,9 @@ func stepsDowntime(consumerName string) []Step { }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -162,7 +162,7 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, @@ -177,14 +177,14 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 495, + ValidatorID("carol"): 99, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, @@ -201,9 +201,9 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 495, + ValidatorID("carol"): 99, }, }, }, @@ -211,7 +211,7 @@ func stepsDowntime(consumerName string) []Step { } } -// stepsDowstepsDoubleDowntime time tests that a validator can get jailed twice +// stepsDoubleDowntime time tests that a validator can get jailed twice // on a consumer. // These are the steps: // - a validator is down on a consumer @@ -233,16 +233,16 @@ func stepsDoubleDowntime(consumerName string) []Step { // validator should be slashed on consumer, powers not affected on either chain yet ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -257,18 +257,18 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // Downtime jailing and corresponding voting power change are processed by provider ValidatorID("bob"): 0, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // Bob's stake may or may not be slashed at this point depending on comet vs cometmock // See https://github.com/cosmos/interchain-security/issues/1304 - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -285,10 +285,10 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // VSC now seen on consumer ValidatorID("bob"): 0, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -301,18 +301,18 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // bob's stake should not be slashed // since the slash was initiated from consumer ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 0, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -327,11 +327,11 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // bob's stake should not be slashed // since the slash was initiated from consumer ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -346,16 +346,16 @@ func stepsDoubleDowntime(consumerName string) []Step { // validator should be slashed on consumer, powers not affected on either chain yet ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -370,18 +370,18 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // Downtime jailing and corresponding voting power change are processed by provider ValidatorID("bob"): 0, - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // Bob's stake may or may not be slashed at this point depending on comet vs cometmock // See https://github.com/cosmos/interchain-security/issues/1304 - ValidatorID("carol"): 501, + ValidatorID("carol"): 100, }, }, }, @@ -398,67 +398,10 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, // VSC now seen on consumer ValidatorID("bob"): 0, - ValidatorID("carol"): 501, - }, - }, - }, - }, - } -} - -// stepsDowntimeWithOptOut returns steps validating that alice can incur downtime -// and not be slashed/jailed, since her voting power is less than 5% of the total. -// -// Note: 60 / (60 + 500 + 950) ~= 0.04 -func stepsDowntimeWithOptOut(consumerName string) []Step { - return []Step{ - { - Action: DowntimeSlashAction{ - Chain: ChainID(consumerName), - Validator: ValidatorID("alice"), - }, - State: State{ - // powers not affected on either chain - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 60, - ValidatorID("bob"): 500, - ValidatorID("carol"): 950, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 60, - ValidatorID("bob"): 500, - ValidatorID("carol"): 950, - }, - }, - }, - }, - { - Action: RelayPacketsAction{ - ChainA: ChainID("provi"), - ChainB: ChainID(consumerName), - Port: "provider", - Channel: 0, - }, - State: State{ - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - // alice is not slashed or jailed due to soft opt out - ValidatorID("alice"): 60, - ValidatorID("bob"): 500, - ValidatorID("carol"): 950, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 60, - ValidatorID("bob"): 500, - ValidatorID("carol"): 950, + ValidatorID("carol"): 100, }, }, }, diff --git a/tests/e2e/steps_light_client_attack.go b/tests/e2e/steps_light_client_attack.go index 65481157b1..afe1356c51 100644 --- a/tests/e2e/steps_light_client_attack.go +++ b/tests/e2e/steps_light_client_attack.go @@ -13,16 +13,16 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { // Slash on provider ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 0, // from 500 to 0 + ValidatorID("carol"): 0, // from 100 to 0 }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, - ValidatorID("carol"): 495, // not tombstoned on consumerName yet + ValidatorID("carol"): 99, // not tombstoned on consumerName yet }, }, }, @@ -38,14 +38,14 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, // tombstoning visible on consumerName }, @@ -62,14 +62,14 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, @@ -86,14 +86,14 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, // not tombstoned ValidatorID("carol"): 0, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, // not tombstoned ValidatorID("carol"): 0, }, @@ -111,14 +111,14 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 910, ValidatorID("bob"): 500, // not tombstoned ValidatorID("carol"): 0, }, diff --git a/tests/e2e/steps_sovereign_changeover.go b/tests/e2e/steps_sovereign_changeover.go index 68ed5c8505..500120bbf0 100644 --- a/tests/e2e/steps_sovereign_changeover.go +++ b/tests/e2e/steps_sovereign_changeover.go @@ -107,7 +107,6 @@ func stepsChangeoverToConsumer(consumerName string) []Step { {Id: ValidatorID("bob"), Stake: 500000000, Allocation: 10000000000}, {Id: ValidatorID("carol"), Stake: 500000000, Allocation: 10000000000}, }, - GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{ ChainID("provi"): ChainState{ diff --git a/tests/e2e/steps_start_chains.go b/tests/e2e/steps_start_chains.go index e358862590..898f562dc0 100644 --- a/tests/e2e/steps_start_chains.go +++ b/tests/e2e/steps_start_chains.go @@ -162,12 +162,6 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint {Id: ValidatorID("alice"), Stake: 500000000, Allocation: 10000000000}, {Id: ValidatorID("carol"), Stake: 500000000, Allocation: 10000000000}, }, - // For consumers that're launching with the provider being on an earlier version - // of ICS before the soft opt-out threshold was introduced, we need to set the - // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the - // consumer binary doesn't panic. Sdk requires that all params are set to valid - // values from the genesis file. - GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{ ChainID("provi"): ChainState{ diff --git a/tests/e2e/test_runner.go b/tests/e2e/test_runner.go index 7c02dd6d2d..c3ced5ab61 100644 --- a/tests/e2e/test_runner.go +++ b/tests/e2e/test_runner.go @@ -19,7 +19,7 @@ const ( // It sets up the test environment and the test driver to run the tests type TestRunner struct { config TestConfig - steps []Step + stepChoice StepChoice testDriver TestCaseDriver target ExecutionTarget verbose bool @@ -86,7 +86,7 @@ func (tr *TestRunner) Run() error { } tr.testDriver = GetTestCaseDriver(tr.config) - err = tr.testDriver.Run(tr.steps, tr.target, tr.verbose) + err = tr.testDriver.Run(tr.stepChoice.steps, tr.target, tr.verbose) if err != nil { tr.result.Failed() // not tearing down environment for troubleshooting reasons on container @@ -118,13 +118,13 @@ func (tr *TestRunner) Setup(testCfg TestConfig) error { return nil } -func CreateTestRunner(config TestConfig, steps []Step, target ExecutionTarget, verbose bool) TestRunner { +func CreateTestRunner(config TestConfig, stepChoice StepChoice, target ExecutionTarget, verbose bool) TestRunner { return TestRunner{ - target: target, - steps: steps, - config: config, - verbose: verbose, - result: TestResult{Status: TEST_STATUS_NOTRUN}, + target: target, + stepChoice: stepChoice, + config: config, + verbose: verbose, + result: TestResult{Status: TEST_STATUS_NOTRUN}, } } @@ -133,8 +133,10 @@ func (tr *TestRunner) Info() string { return fmt.Sprintf(` ------------------------------------------ Test name : %s +Config: %s Target: %s ------------------------------------------`, + tr.stepChoice.name, tr.config.name, tr.target.Info(), ) @@ -144,12 +146,14 @@ func (tr *TestRunner) Report() string { return fmt.Sprintf(` ------------------------------------------ Test name : %s +Config: %s Target: %s - Status: %s - Result: %s - Duration: %s - StartTime: %s ------------------------------------------`, + tr.stepChoice.name, tr.config.name, tr.target.Info(), tr.result.Status, diff --git a/tests/e2e/tracehandler_testdata/changeover.json b/tests/e2e/tracehandler_testdata/changeover.json index b115680878..91b53a87cd 100644 --- a/tests/e2e/tracehandler_testdata/changeover.json +++ b/tests/e2e/tracehandler_testdata/changeover.json @@ -345,7 +345,7 @@ "Stake": 500000000 } ], - "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" + "GenesisChanges": "" }, "State": { "provi": { diff --git a/tests/e2e/tracehandler_testdata/consumer-double-sign.json b/tests/e2e/tracehandler_testdata/consumer-double-sign.json index 7744bc5b03..7551c2c77d 100644 --- a/tests/e2e/tracehandler_testdata/consumer-double-sign.json +++ b/tests/e2e/tracehandler_testdata/consumer-double-sign.json @@ -271,7 +271,7 @@ "Stake": 500000000 } ], - "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" + "GenesisChanges": "" }, "State": { "consu": { diff --git a/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json b/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json index 90f009fb7e..c7f68b5273 100644 --- a/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json +++ b/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json @@ -123,6 +123,14 @@ } } }, + { + "ActionType": "main.OptInAction", + "Action": { + "Chain": "consu", + "Validator": "alice" + }, + "State": {} + }, { "ActionType": "main.VoteGovProposalAction", "Action": { @@ -184,7 +192,7 @@ "Stake": 500000000 } ], - "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" + "GenesisChanges": "" }, "State": { "consu": { @@ -262,8 +270,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 500, - "bob": 20 + "alice": 500 }, "StakedTokens": null, "IBCTransferParams": null, @@ -311,8 +318,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 511, - "bob": 20 + "alice": 511 }, "StakedTokens": null, "IBCTransferParams": null, @@ -354,7 +360,7 @@ "ProposedConsumerChains": null, "ValPowers": { "alice": 511, - "bob": 20 + "bob": 0 }, "StakedTokens": null, "IBCTransferParams": null, @@ -406,7 +412,7 @@ "ProposedConsumerChains": null, "ValPowers": { "alice": 511, - "bob": 20 + "bob": 0 }, "StakedTokens": null, "IBCTransferParams": null, diff --git a/tests/e2e/tracehandler_testdata/democracy.json b/tests/e2e/tracehandler_testdata/democracy.json index 633e13ee08..2dc179c0da 100644 --- a/tests/e2e/tracehandler_testdata/democracy.json +++ b/tests/e2e/tracehandler_testdata/democracy.json @@ -271,7 +271,7 @@ "Stake": 500000000 } ], - "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" + "GenesisChanges": "" }, "State": { "democ": { diff --git a/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json b/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json index 75487915de..b270031542 100644 --- a/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json +++ b/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json @@ -271,7 +271,7 @@ "Stake": 500000000 } ], - "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" + "GenesisChanges": "" }, "State": { "democ": { diff --git a/tests/e2e/tracehandler_testdata/happyPath.json b/tests/e2e/tracehandler_testdata/happyPath.json index e5f732eaf0..fea88c2e92 100644 --- a/tests/e2e/tracehandler_testdata/happyPath.json +++ b/tests/e2e/tracehandler_testdata/happyPath.json @@ -271,7 +271,7 @@ "Stake": 500000000 } ], - "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" + "GenesisChanges": "" }, "State": { "consu": { @@ -1033,16 +1033,16 @@ "Src": "carol", "Dst": "alice", "TxSender": "carol", - "Amount": 449000000 + "Amount": 400000000 }, "State": { "consu": { "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 60, + "alice": 510, "bob": 500, - "carol": 950 + "carol": 500 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1060,9 +1060,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1091,9 +1091,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1120,9 +1120,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1140,9 +1140,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1171,8 +1171,8 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, - "carol": 501 + "alice": 910, + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1190,9 +1190,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 0, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1221,9 +1221,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 0, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1250,9 +1250,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 0, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1270,9 +1270,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1301,9 +1301,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1330,9 +1330,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1350,7 +1350,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, "carol": 0 }, @@ -1381,7 +1381,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, "carol": 0 }, @@ -1410,7 +1410,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, "carol": 0 }, @@ -1430,9 +1430,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 495 + "carol": 99 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1461,9 +1461,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 495 + "carol": 99 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1490,9 +1490,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 495 + "carol": 99 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1510,7 +1510,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, "carol": 0 }, @@ -1541,7 +1541,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, "carol": 0 }, @@ -1561,7 +1561,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, "carol": 0 }, diff --git a/tests/e2e/tracehandler_testdata/multipleConsumers.json b/tests/e2e/tracehandler_testdata/multipleConsumers.json index 504e742a60..3dbac1f88d 100644 --- a/tests/e2e/tracehandler_testdata/multipleConsumers.json +++ b/tests/e2e/tracehandler_testdata/multipleConsumers.json @@ -271,7 +271,7 @@ "Stake": 500000000 } ], - "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" + "GenesisChanges": "" }, "State": { "consu": { @@ -564,7 +564,7 @@ "Stake": 500000000 } ], - "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" + "GenesisChanges": "" }, "State": { "densu": { diff --git a/tests/e2e/tracehandler_testdata/shorthappy.json b/tests/e2e/tracehandler_testdata/shorthappy.json index 60c645e8c9..4a93c4b713 100644 --- a/tests/e2e/tracehandler_testdata/shorthappy.json +++ b/tests/e2e/tracehandler_testdata/shorthappy.json @@ -271,7 +271,7 @@ "Stake": 500000000 } ], - "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" + "GenesisChanges": "" }, "State": { "consu": { @@ -567,10 +567,10 @@ "ActionType": "main.RedelegateTokensAction", "Action": { "Chain": "provi", - "Src": "alice", - "Dst": "carol", - "TxSender": "alice", - "Amount": 1000000 + "Src": "carol", + "Dst": "alice", + "TxSender": "carol", + "Amount": 400000000 }, "State": { "consu": { @@ -597,9 +597,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -628,9 +628,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -657,9 +657,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -677,9 +677,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -708,8 +708,8 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, - "carol": 501 + "alice": 910, + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -727,9 +727,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 0, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -758,9 +758,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 0, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -787,9 +787,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 0, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -807,9 +807,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -838,9 +838,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -867,9 +867,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 501 + "carol": 100 }, "StakedTokens": null, "IBCTransferParams": null, @@ -887,7 +887,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, "carol": 0 }, @@ -918,7 +918,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, "carol": 0 }, @@ -947,7 +947,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, "carol": 0 }, @@ -967,9 +967,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 495 + "carol": 99 }, "StakedTokens": null, "IBCTransferParams": null, @@ -998,9 +998,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 495 + "carol": 99 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1027,9 +1027,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, - "carol": 495 + "carol": 99 }, "StakedTokens": null, "IBCTransferParams": null, @@ -1047,7 +1047,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, "carol": 0 }, @@ -1078,7 +1078,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, "carol": 0 }, @@ -1098,7 +1098,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 509, + "alice": 910, "bob": 500, "carol": 0 }, diff --git a/tests/e2e/tracehandler_testdata/slashThrottle.json b/tests/e2e/tracehandler_testdata/slashThrottle.json index e325113cc4..68ce3a0c6d 100644 --- a/tests/e2e/tracehandler_testdata/slashThrottle.json +++ b/tests/e2e/tracehandler_testdata/slashThrottle.json @@ -271,7 +271,7 @@ "Stake": 500000000 } ], - "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" + "GenesisChanges": "" }, "State": { "consu": { diff --git a/tests/mbt/driver/setup.go b/tests/mbt/driver/setup.go index 81d39d5e70..87b7b16e62 100644 --- a/tests/mbt/driver/setup.go +++ b/tests/mbt/driver/setup.go @@ -499,7 +499,7 @@ func createConsumerGenesis(modelParams ModelParams, providerChain *ibctesting.Te ccvtypes.DefaultConsumerRedistributeFrac, ccvtypes.DefaultHistoricalEntries, modelParams.UnbondingPeriodPerChain[ChainId(consumerClientState.ChainId)], - "0", // disable soft opt-out + ccvtypes.DefaultSoftOptOutThreshold, []string{}, []string{}, ccvtypes.DefaultRetryDelayPeriod, diff --git a/tests/mbt/model/ccv.qnt b/tests/mbt/model/ccv.qnt index 80aed91ec2..83adcea357 100644 --- a/tests/mbt/model/ccv.qnt +++ b/tests/mbt/model/ccv.qnt @@ -396,7 +396,7 @@ module ccv { } // Delivers the next queued VscMaturedPacket from a consumer chain to the provider chain. - // Arguments are the currentState and the the consumer chain, from which the packet will be delivered. + // Arguments are the currentState and the consumer chain, from which the packet will be delivered. // If this packet will time out on the provider on delivery, // the consumer will be dropped. // The first return is the result of the operation, the second result is a boolean diff --git a/testutil/integration/debug_test.go b/testutil/integration/debug_test.go index 15036416e6..d26246dcf5 100644 --- a/testutil/integration/debug_test.go +++ b/testutil/integration/debug_test.go @@ -153,14 +153,6 @@ func TestCISBeforeCCVEstablished(t *testing.T) { runCCVTestByName(t, "TestCISBeforeCCVEstablished") } -// -// Soft opt out tests -// - -func TestSoftOptOut(t *testing.T) { - runCCVTestByName(t, "TestSoftOptOut") -} - // // Stop consumer tests // diff --git a/x/ccv/consumer/keeper/validators.go b/x/ccv/consumer/keeper/validators.go index b1b62a3a40..2c4f0d79ab 100644 --- a/x/ccv/consumer/keeper/validators.go +++ b/x/ccv/consumer/keeper/validators.go @@ -124,7 +124,7 @@ func (k Keeper) Slash(ctx context.Context, addr sdk.ConsAddress, infractionHeigh return k.SlashWithInfractionReason(ctx, addr, infractionHeight, power, slashFactor, stakingtypes.Infraction_INFRACTION_UNSPECIFIED) } -// Slash queues a slashing request for the the provider chain +// Slash queues a slashing request for the provider chain // All queued slashing requests will be cleared in EndBlock // Called by Slashing keeper in SlashWithInfractionReason func (k Keeper) SlashWithInfractionReason(goCtx context.Context, addr sdk.ConsAddress, infractionHeight, power int64, slashFactor math.LegacyDec, infraction stakingtypes.Infraction) (math.Int, error) { diff --git a/x/ccv/consumer/types/consumer.pb.go b/x/ccv/consumer/types/consumer.pb.go index 6df35dd174..5e0c9488ba 100644 --- a/x/ccv/consumer/types/consumer.pb.go +++ b/x/ccv/consumer/types/consumer.pb.go @@ -39,8 +39,10 @@ type CrossChainValidator struct { Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` Power int64 `protobuf:"varint,2,opt,name=power,proto3" json:"power,omitempty"` // pubkey is the consensus public key of the validator, as a Protobuf Any. - Pubkey *types.Any `protobuf:"bytes,3,opt,name=pubkey,proto3" json:"pubkey,omitempty" yaml:"consensus_pubkey"` - OptedOut bool `protobuf:"varint,4,opt,name=opted_out,json=optedOut,proto3" json:"opted_out,omitempty"` + Pubkey *types.Any `protobuf:"bytes,3,opt,name=pubkey,proto3" json:"pubkey,omitempty" yaml:"consensus_pubkey"` + // !!! DEPRECATED !!! opted_out is deprecated because after the introduction of Partial Set Security (PSS) + // we removed the soft opt-out feature. + OptedOut bool `protobuf:"varint,4,opt,name=opted_out,json=optedOut,proto3" json:"opted_out,omitempty"` // Deprecated: Do not use. } func (m *CrossChainValidator) Reset() { *m = CrossChainValidator{} } @@ -97,6 +99,7 @@ func (m *CrossChainValidator) GetPubkey() *types.Any { return nil } +// Deprecated: Do not use. func (m *CrossChainValidator) GetOptedOut() bool { if m != nil { return m.OptedOut @@ -170,35 +173,35 @@ func init() { } var fileDescriptor_5b27a82b276e7f93 = []byte{ - // 434 bytes of a gzipped FileDescriptorProto + // 436 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0xcd, 0x6e, 0xd3, 0x40, - 0x10, 0xce, 0x52, 0x28, 0xee, 0x06, 0x21, 0x64, 0x22, 0xe1, 0x06, 0xc9, 0x89, 0xcc, 0xc5, 0x97, + 0x10, 0xce, 0xb6, 0x50, 0xdc, 0x0d, 0x42, 0xc8, 0x44, 0xc2, 0xcd, 0xc1, 0x8e, 0xc2, 0xc5, 0x97, 0xda, 0x6a, 0x2a, 0x2e, 0x48, 0x1c, 0x9a, 0x1e, 0x39, 0x14, 0x19, 0x04, 0x12, 0x17, 0x6b, 0xbd, - 0x5e, 0x1c, 0x0b, 0x7b, 0x67, 0xb5, 0x3f, 0x2e, 0xcb, 0x53, 0xf4, 0x61, 0x78, 0x05, 0xa4, 0x8a, - 0x53, 0x8f, 0x9c, 0x0a, 0x4a, 0xde, 0x80, 0x27, 0x40, 0xfe, 0x49, 0x10, 0x3f, 0xb7, 0x99, 0x6f, - 0xf6, 0x9b, 0xf9, 0x66, 0xf6, 0xc3, 0x8b, 0x92, 0x6b, 0x26, 0xe9, 0x8a, 0x94, 0x3c, 0x55, 0x8c, - 0x1a, 0x59, 0x6a, 0x1b, 0x53, 0xda, 0xc4, 0x14, 0xb8, 0x32, 0x35, 0x93, 0x71, 0x73, 0xbc, 0x8b, - 0x23, 0x21, 0x41, 0x83, 0xfb, 0xe4, 0x3f, 0x9c, 0x88, 0xd2, 0x26, 0xda, 0xbd, 0x6b, 0x8e, 0xa7, - 0x87, 0x05, 0x40, 0x51, 0xb1, 0xb8, 0xa3, 0x64, 0xe6, 0x7d, 0x4c, 0xb8, 0xed, 0xf9, 0xd3, 0x49, - 0x01, 0x05, 0x74, 0x61, 0xdc, 0x46, 0x03, 0x7a, 0x48, 0x41, 0xd5, 0xa0, 0xd2, 0xbe, 0xd0, 0x27, - 0x43, 0x69, 0xf6, 0x77, 0x2f, 0x5d, 0xd6, 0x4c, 0x69, 0x52, 0x8b, 0xfe, 0x41, 0xf0, 0x05, 0xe1, - 0x87, 0x67, 0x12, 0x94, 0x3a, 0x6b, 0x45, 0xbd, 0x21, 0x55, 0x99, 0x13, 0x0d, 0xd2, 0xf5, 0xf0, - 0x5d, 0x92, 0xe7, 0x92, 0x29, 0xe5, 0xa1, 0x39, 0x0a, 0xef, 0x25, 0xdb, 0xd4, 0x9d, 0xe0, 0x3b, - 0x02, 0x2e, 0x98, 0xf4, 0x6e, 0xcd, 0x51, 0xb8, 0x97, 0xf4, 0x89, 0x4b, 0xf0, 0xbe, 0x30, 0xd9, - 0x07, 0x66, 0xbd, 0xbd, 0x39, 0x0a, 0xc7, 0x8b, 0x49, 0xd4, 0x4f, 0x8e, 0xb6, 0x93, 0xa3, 0x53, - 0x6e, 0x97, 0x27, 0x3f, 0x6f, 0x66, 0x8f, 0x2c, 0xa9, 0xab, 0x67, 0x41, 0xbb, 0x31, 0xe3, 0xca, - 0xa8, 0xb4, 0xe7, 0x05, 0x5f, 0x3f, 0x1f, 0x4d, 0x06, 0xed, 0x54, 0x5a, 0xa1, 0x21, 0x7a, 0x69, - 0xb2, 0x17, 0xcc, 0x26, 0x43, 0x63, 0xf7, 0x31, 0x3e, 0x00, 0xa1, 0x59, 0x9e, 0x82, 0xd1, 0xde, - 0xed, 0x39, 0x0a, 0x9d, 0xc4, 0xe9, 0x80, 0x73, 0xa3, 0x83, 0x4f, 0x78, 0xfc, 0xaa, 0x22, 0x6a, - 0x95, 0x30, 0x0a, 0x32, 0x77, 0x43, 0xfc, 0xe0, 0x82, 0x94, 0xba, 0xe4, 0x45, 0x0a, 0x3c, 0x95, - 0x4c, 0x54, 0xb6, 0xdb, 0xc3, 0x49, 0xee, 0x0f, 0xf8, 0x39, 0x4f, 0x5a, 0xd4, 0x3d, 0xc5, 0x07, - 0x8a, 0xf1, 0x3c, 0x6d, 0x0f, 0xd3, 0xad, 0x34, 0x5e, 0x4c, 0xff, 0xd1, 0xfe, 0x7a, 0x7b, 0xb5, - 0xa5, 0x73, 0x75, 0x33, 0x1b, 0x5d, 0x7e, 0x9f, 0xa1, 0xc4, 0x69, 0x69, 0x6d, 0x61, 0xf9, 0xf6, - 0x6a, 0xed, 0xa3, 0xeb, 0xb5, 0x8f, 0x7e, 0xac, 0x7d, 0x74, 0xb9, 0xf1, 0x47, 0xd7, 0x1b, 0x7f, - 0xf4, 0x6d, 0xe3, 0x8f, 0xde, 0x3d, 0x2f, 0x4a, 0xbd, 0x32, 0x59, 0x44, 0xa1, 0x1e, 0xfe, 0x25, - 0xfe, 0xed, 0x80, 0xa3, 0x9d, 0x6b, 0x9a, 0xa7, 0xf1, 0xc7, 0x3f, 0xad, 0xa3, 0xad, 0x60, 0x2a, - 0xdb, 0xef, 0x04, 0x9c, 0xfc, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x28, 0x12, 0xc5, 0x22, 0x6b, 0x02, - 0x00, 0x00, + 0x5e, 0x1c, 0x0b, 0x7b, 0x67, 0xb5, 0x3f, 0x2e, 0xcb, 0x53, 0xf4, 0x61, 0x78, 0x88, 0xc2, 0xa9, + 0x47, 0x4e, 0x05, 0x25, 0x6f, 0xc0, 0x13, 0x20, 0xff, 0x24, 0x88, 0x9f, 0xdb, 0xcc, 0x37, 0xfb, + 0xcd, 0x7c, 0x33, 0xfb, 0xe1, 0x45, 0xc9, 0x35, 0x93, 0x74, 0x45, 0x4a, 0x9e, 0x2a, 0x46, 0x8d, + 0x2c, 0xb5, 0x8d, 0x29, 0x6d, 0x62, 0x0a, 0x5c, 0x99, 0x9a, 0xc9, 0xb8, 0x39, 0xd9, 0xc5, 0x91, + 0x90, 0xa0, 0xc1, 0x7d, 0xf2, 0x1f, 0x4e, 0x44, 0x69, 0x13, 0xed, 0xde, 0x35, 0x27, 0xd3, 0xa3, + 0x02, 0xa0, 0xa8, 0x58, 0xdc, 0x51, 0x32, 0xf3, 0x3e, 0x26, 0xdc, 0xf6, 0xfc, 0xe9, 0xa4, 0x80, + 0x02, 0xba, 0x30, 0x6e, 0xa3, 0x01, 0x3d, 0xa2, 0xa0, 0x6a, 0x50, 0x69, 0x5f, 0xe8, 0x93, 0xa1, + 0x14, 0xfc, 0xdd, 0x4b, 0x97, 0x35, 0x53, 0x9a, 0xd4, 0xa2, 0x7f, 0x30, 0xff, 0x82, 0xf0, 0xa3, + 0x73, 0x09, 0x4a, 0x9d, 0xb7, 0xa2, 0xde, 0x90, 0xaa, 0xcc, 0x89, 0x06, 0xe9, 0x7a, 0xf8, 0x1e, + 0xc9, 0x73, 0xc9, 0x94, 0xf2, 0xd0, 0x0c, 0x85, 0xf7, 0x93, 0x6d, 0xea, 0x4e, 0xf0, 0x5d, 0x01, + 0x97, 0x4c, 0x7a, 0x7b, 0x33, 0x14, 0xee, 0x27, 0x7d, 0xe2, 0x12, 0x7c, 0x20, 0x4c, 0xf6, 0x81, + 0x59, 0x6f, 0x7f, 0x86, 0xc2, 0xf1, 0x62, 0x12, 0xf5, 0x93, 0xa3, 0xed, 0xe4, 0xe8, 0x8c, 0xdb, + 0xe5, 0xe9, 0xcf, 0xdb, 0xe0, 0xb1, 0x25, 0x75, 0xf5, 0x6c, 0xde, 0x6e, 0xcc, 0xb8, 0x32, 0x2a, + 0xed, 0x79, 0xf3, 0xaf, 0x9f, 0x8f, 0x27, 0x83, 0x76, 0x2a, 0xad, 0xd0, 0x10, 0xbd, 0x34, 0xd9, + 0x0b, 0x66, 0x93, 0xa1, 0xb1, 0x1b, 0xe0, 0x43, 0x10, 0x9a, 0xe5, 0x29, 0x18, 0xed, 0xdd, 0x99, + 0xa1, 0xd0, 0x59, 0xee, 0x79, 0x28, 0x71, 0x3a, 0xf0, 0xc2, 0xe8, 0xf9, 0x27, 0x3c, 0x7e, 0x55, + 0x11, 0xb5, 0x4a, 0x18, 0x05, 0x99, 0xbb, 0x21, 0x7e, 0x78, 0x49, 0x4a, 0x5d, 0xf2, 0x22, 0x05, + 0x9e, 0x4a, 0x26, 0x2a, 0xdb, 0xed, 0xe2, 0x24, 0x0f, 0x06, 0xfc, 0x82, 0x27, 0x2d, 0xea, 0x9e, + 0xe1, 0x43, 0xc5, 0x78, 0x9e, 0xb6, 0xc7, 0xe9, 0xd6, 0x1a, 0x2f, 0xa6, 0xff, 0xe8, 0x7f, 0xbd, + 0xbd, 0xdc, 0xd2, 0xb9, 0xbe, 0x0d, 0x46, 0x57, 0xdf, 0x03, 0x94, 0x38, 0x2d, 0xad, 0x2d, 0x2c, + 0xdf, 0x5e, 0xaf, 0x7d, 0x74, 0xb3, 0xf6, 0xd1, 0x8f, 0xb5, 0x8f, 0xae, 0x36, 0xfe, 0xe8, 0x66, + 0xe3, 0x8f, 0xbe, 0x6d, 0xfc, 0xd1, 0xbb, 0xe7, 0x45, 0xa9, 0x57, 0x26, 0x8b, 0x28, 0xd4, 0xc3, + 0xdf, 0xc4, 0xbf, 0x5d, 0x70, 0xbc, 0x73, 0x4e, 0xf3, 0x34, 0xfe, 0xf8, 0xa7, 0x7d, 0xb4, 0x15, + 0x4c, 0x65, 0x07, 0x9d, 0x80, 0xd3, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x83, 0x9f, 0x58, 0x42, + 0x6f, 0x02, 0x00, 0x00, } func (m *CrossChainValidator) Marshal() (dAtA []byte, err error) { diff --git a/x/ccv/consumer/types/keys_test.go b/x/ccv/consumer/types/keys_test.go index e1fcbcf733..7ca5ce2a10 100644 --- a/x/ccv/consumer/types/keys_test.go +++ b/x/ccv/consumer/types/keys_test.go @@ -69,8 +69,7 @@ func getAllFullyDefinedKeys() [][]byte { // PendingDataPacketsKey() does not use duplicated prefix with value of 0x06 PreCCVKey(), InitialValSetKey(), - // LastStandaloneHeightKey() is depreciated - SmallestNonOptOutPowerKey(), + // LastStandaloneHeightKey() is deprecated HistoricalInfoKey(0), PacketMaturityTimeKey(0, time.Time{}), HeightValsetUpdateIDKey(0), diff --git a/x/ccv/consumer/types/params_test.go b/x/ccv/consumer/types/params_test.go index caff4db0b1..ee4d45a80d 100644 --- a/x/ccv/consumer/types/params_test.go +++ b/x/ccv/consumer/types/params_test.go @@ -57,14 +57,6 @@ func TestValidateParams(t *testing.T) { "custom invalid params, negative unbonding period", ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, -24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, - { - "custom invalid params, invalid soft opt out threshold", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "-0.05", []string{"u"}, []string{}, 2*time.Hour), false, - }, - { - "custom invalid params, invalid soft opt out threshold", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.5", []string{"u"}, []string{}, 2*time.Hour), false, - }, { "custom invalid params, invalid reward denom", ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"u"}, []string{}, 2*time.Hour), false, diff --git a/x/ccv/consumer/types/validator.go b/x/ccv/consumer/types/validator.go index f1f9fa260b..b134dde078 100644 --- a/x/ccv/consumer/types/validator.go +++ b/x/ccv/consumer/types/validator.go @@ -15,10 +15,9 @@ func NewCCValidator(address []byte, power int64, pubKey cryptotypes.PubKey) (Cro } return CrossChainValidator{ - Address: address, - Power: power, - Pubkey: pkAny, - OptedOut: false, + Address: address, + Power: power, + Pubkey: pkAny, }, nil } diff --git a/x/ccv/provider/ibc_middleware.go b/x/ccv/provider/ibc_middleware.go index f4128260e1..d9d816ab93 100644 --- a/x/ccv/provider/ibc_middleware.go +++ b/x/ccv/provider/ibc_middleware.go @@ -212,7 +212,7 @@ func (im IBCMiddleware) GetAppVersion(ctx sdk.Context, portID, channelID string) // It follows the same logic than the OnRecvPacket method of the IBC transfer module // see https://github.com/cosmos/ibc-go/blob/v7.3.2/modules/apps/transfer/keeper/relay.go#L162 func GetProviderDenom(denom string, packet channeltypes.Packet) (providerDenom string) { - // If the the prefix denom corresponds to the packet's source port and channel, + // If the prefix denom corresponds to the packet's source port and channel, // returns the base denom if ibctransfertypes.ReceiverChainIsSource(packet.GetSourcePort(), packet.GetSourceChannel(), denom) { voucherPrefix := ibctransfertypes.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) diff --git a/x/ccv/provider/keeper/consumer_equivocation.go b/x/ccv/provider/keeper/consumer_equivocation.go index 127a3987a5..cbe7080ca7 100644 --- a/x/ccv/provider/keeper/consumer_equivocation.go +++ b/x/ccv/provider/keeper/consumer_equivocation.go @@ -478,7 +478,7 @@ func (k Keeper) SlashValidator(ctx sdk.Context, providerAddr types.ProviderConsA // CRUD section // -// SetEquivocationEvidenceMinHeight sets the the minimum height +// SetEquivocationEvidenceMinHeight sets the minimum height // of a valid consumer equivocation evidence for a given consumer chain ID func (k Keeper) SetEquivocationEvidenceMinHeight(ctx sdk.Context, chainID string, height uint64) { store := ctx.KVStore(k.storeKey) @@ -488,7 +488,7 @@ func (k Keeper) SetEquivocationEvidenceMinHeight(ctx sdk.Context, chainID string store.Set(types.EquivocationEvidenceMinHeightKey(chainID), heightBytes) } -// GetEquivocationEvidenceMinHeight returns the the minimum height +// GetEquivocationEvidenceMinHeight returns the minimum height // of a valid consumer equivocation evidence for a given consumer chain ID func (k Keeper) GetEquivocationEvidenceMinHeight(ctx sdk.Context, chainID string) uint64 { store := ctx.KVStore(k.storeKey) @@ -500,7 +500,7 @@ func (k Keeper) GetEquivocationEvidenceMinHeight(ctx sdk.Context, chainID string return binary.BigEndian.Uint64(bz) } -// DeleteEquivocationEvidenceMinHeight deletes the the minimum height +// DeleteEquivocationEvidenceMinHeight deletes the minimum height // of a valid consumer equivocation evidence for a given consumer chain ID func (k Keeper) DeleteEquivocationEvidenceMinHeight(ctx sdk.Context, chainID string) { store := ctx.KVStore(k.storeKey) diff --git a/x/ccv/provider/migrations/v5/migrations_test.go b/x/ccv/provider/migrations/v5/migration_test.go similarity index 100% rename from x/ccv/provider/migrations/v5/migrations_test.go rename to x/ccv/provider/migrations/v5/migration_test.go diff --git a/x/ccv/provider/types/query.pb.go b/x/ccv/provider/types/query.pb.go index e8c13f7d3c..84e610776e 100644 --- a/x/ccv/provider/types/query.pb.go +++ b/x/ccv/provider/types/query.pb.go @@ -9,7 +9,6 @@ import ( fmt "fmt" crypto "github.com/cometbft/cometbft/proto/tendermint/crypto" _ "github.com/cosmos/cosmos-proto" - _ "github.com/cosmos/cosmos-sdk/types/tx/amino" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" @@ -1789,135 +1788,133 @@ func init() { } var fileDescriptor_422512d7b7586cd7 = []byte{ - // 2045 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xcf, 0x6f, 0xdc, 0xc6, - 0xf5, 0x17, 0x57, 0x3f, 0x22, 0x8d, 0xe2, 0x5f, 0x63, 0x7d, 0x13, 0x99, 0x52, 0x76, 0x15, 0xe6, - 0xdb, 0x56, 0x96, 0x9d, 0xa5, 0x24, 0xc3, 0xad, 0x63, 0x57, 0x91, 0xb5, 0x5a, 0xdb, 0xd9, 0xda, - 0x89, 0x15, 0x5a, 0x56, 0x0b, 0xb7, 0x28, 0x3d, 0x26, 0x27, 0x2b, 0xc2, 0x24, 0x87, 0xe2, 0x50, - 0xeb, 0x6c, 0x8d, 0x1c, 0xd2, 0x43, 0x9b, 0x53, 0x11, 0xf4, 0x07, 0xd0, 0x63, 0x2e, 0x05, 0x7a, - 0x29, 0x50, 0x14, 0x45, 0x91, 0x3f, 0x21, 0xb7, 0xa6, 0xcd, 0xa5, 0xe8, 0xc1, 0x2d, 0xec, 0x02, - 0x2d, 0x7a, 0x28, 0x8a, 0xa0, 0x40, 0x4f, 0x05, 0x0a, 0x0e, 0x87, 0xbf, 0x76, 0xb9, 0xbb, 0xe4, - 0xae, 0x7a, 0x11, 0x96, 0x33, 0x6f, 0x3e, 0xf3, 0xde, 0x9b, 0xf7, 0xde, 0xbc, 0xcf, 0x08, 0xc8, - 0x86, 0xed, 0x61, 0x57, 0xdb, 0x47, 0x86, 0xad, 0x52, 0xac, 0x1d, 0xba, 0x86, 0xd7, 0x96, 0x35, - 0xad, 0x25, 0x3b, 0x2e, 0x69, 0x19, 0x3a, 0x76, 0xe5, 0xd6, 0x9a, 0x7c, 0x70, 0x88, 0xdd, 0x76, - 0xd5, 0x71, 0x89, 0x47, 0xe0, 0x2b, 0x19, 0x0b, 0xaa, 0x9a, 0xd6, 0xaa, 0x86, 0x0b, 0xaa, 0xad, - 0x35, 0x71, 0xb1, 0x49, 0x48, 0xd3, 0xc4, 0x32, 0x72, 0x0c, 0x19, 0xd9, 0x36, 0xf1, 0x90, 0x67, - 0x10, 0x9b, 0x06, 0x10, 0xe2, 0x5c, 0x93, 0x34, 0x09, 0xfb, 0x29, 0xfb, 0xbf, 0xf8, 0x68, 0x85, - 0xaf, 0x61, 0x5f, 0x0f, 0x0e, 0xdf, 0x91, 0x3d, 0xc3, 0xc2, 0xd4, 0x43, 0x96, 0xc3, 0x05, 0xd6, - 0xf3, 0xa8, 0x1a, 0x69, 0x11, 0xac, 0x59, 0xed, 0xb5, 0xa6, 0xb5, 0x26, 0xd3, 0x7d, 0xe4, 0x62, - 0x5d, 0xd5, 0x88, 0x4d, 0x0f, 0xad, 0x68, 0xc5, 0x17, 0xfa, 0xac, 0x78, 0x64, 0xb8, 0x98, 0x8b, - 0x2d, 0x7a, 0xd8, 0xd6, 0xb1, 0x6b, 0x19, 0xb6, 0x27, 0x6b, 0x6e, 0xdb, 0xf1, 0x88, 0xfc, 0x10, - 0xb7, 0x43, 0x0b, 0xcf, 0x68, 0x84, 0x5a, 0x84, 0xaa, 0x81, 0x91, 0xc1, 0x07, 0x9f, 0x3a, 0x85, - 0x2c, 0xc3, 0x26, 0x32, 0xfb, 0x1b, 0x0c, 0x49, 0x97, 0xc0, 0xc2, 0xdb, 0xbe, 0x87, 0xb7, 0xb9, - 0x26, 0x37, 0xb0, 0x8d, 0xa9, 0x41, 0x15, 0x7c, 0x70, 0x88, 0xa9, 0x07, 0xcf, 0x80, 0xe9, 0x40, - 0x1d, 0x43, 0x9f, 0x17, 0x96, 0x84, 0xe5, 0x19, 0xe5, 0x39, 0xf6, 0xdd, 0xd0, 0xa5, 0xc7, 0x60, - 0x31, 0x7b, 0x25, 0x75, 0x88, 0x4d, 0x31, 0xfc, 0x26, 0x38, 0xd6, 0x0c, 0x86, 0x54, 0xea, 0x21, - 0x0f, 0xb3, 0xf5, 0xb3, 0xeb, 0xab, 0xd5, 0x5e, 0x87, 0xd8, 0x5a, 0xab, 0x76, 0x60, 0xdd, 0xf1, - 0xd7, 0xd5, 0x26, 0x3e, 0x79, 0x52, 0x19, 0x53, 0x9e, 0x6f, 0x26, 0xc6, 0xa4, 0x45, 0x20, 0xa6, - 0x36, 0xdf, 0xf6, 0xe1, 0x42, 0xad, 0x25, 0xd4, 0x61, 0x54, 0x38, 0xcb, 0x35, 0xab, 0x81, 0x29, - 0xb6, 0x3d, 0x9d, 0x17, 0x96, 0xc6, 0x97, 0x67, 0xd7, 0x57, 0xaa, 0x39, 0xe2, 0xaa, 0xca, 0x40, - 0x14, 0xbe, 0x52, 0x3a, 0x0b, 0xbe, 0xd4, 0xbd, 0xc5, 0x1d, 0x0f, 0xb9, 0xde, 0x8e, 0x4b, 0x1c, - 0x42, 0x91, 0x19, 0x69, 0xf3, 0x81, 0x00, 0x96, 0x07, 0xcb, 0x72, 0xdd, 0xbe, 0x05, 0x66, 0x9c, - 0x70, 0x90, 0x7b, 0xec, 0xf5, 0x7c, 0xea, 0x71, 0xf0, 0x2d, 0x5d, 0x37, 0xfc, 0x80, 0x8f, 0xa1, - 0x63, 0x40, 0x69, 0x19, 0x7c, 0x31, 0x4b, 0x13, 0xe2, 0x74, 0x29, 0xfd, 0x3d, 0x21, 0xdb, 0xc0, - 0x94, 0x68, 0x74, 0xd2, 0x5d, 0x3a, 0x6f, 0x14, 0xd2, 0x59, 0xc1, 0x16, 0x69, 0x21, 0x33, 0x53, - 0xe5, 0x9f, 0x96, 0xc0, 0x24, 0xdb, 0xbb, 0x4f, 0x2c, 0xc2, 0x05, 0x30, 0xa3, 0x99, 0x06, 0xb6, - 0x3d, 0x7f, 0xae, 0xc4, 0xe6, 0xa6, 0x83, 0x81, 0x86, 0x0e, 0x4f, 0x83, 0x49, 0x8f, 0x38, 0xea, - 0x5b, 0xf3, 0xe3, 0x4b, 0xc2, 0xf2, 0x31, 0x65, 0xc2, 0x23, 0xce, 0x5b, 0x70, 0x05, 0x40, 0xcb, - 0xb0, 0x55, 0x87, 0x3c, 0xc2, 0xae, 0x6a, 0xd8, 0x6a, 0x20, 0x31, 0xb1, 0x24, 0x2c, 0x8f, 0x2b, - 0xc7, 0x2d, 0xc3, 0xde, 0xf1, 0x27, 0x1a, 0xf6, 0xae, 0x2f, 0xbb, 0x0a, 0xe6, 0x5a, 0xc8, 0x34, - 0x74, 0xe4, 0x11, 0x97, 0xf2, 0x25, 0x1a, 0x72, 0xe6, 0x27, 0x19, 0x1e, 0x8c, 0xe7, 0xd8, 0xa2, - 0x6d, 0xe4, 0xc0, 0x15, 0x70, 0x2a, 0x1a, 0x55, 0x29, 0xf6, 0x98, 0xf8, 0x14, 0x13, 0x3f, 0x11, - 0x4d, 0xdc, 0xc1, 0x9e, 0x2f, 0xbb, 0x08, 0x66, 0x90, 0x69, 0x92, 0x47, 0xa6, 0x41, 0xbd, 0xf9, - 0xe7, 0x96, 0xc6, 0x97, 0x67, 0x94, 0x78, 0x00, 0x8a, 0x60, 0x5a, 0xc7, 0x76, 0x9b, 0x4d, 0x4e, - 0xb3, 0xc9, 0xe8, 0x5b, 0xfa, 0xbe, 0x00, 0x5e, 0x66, 0x67, 0xb4, 0x17, 0x42, 0x26, 0x82, 0xc0, - 0x1d, 0x9c, 0xc2, 0x70, 0x03, 0x9c, 0x0c, 0x8f, 0x43, 0x45, 0xba, 0xee, 0x62, 0x4a, 0x03, 0xef, - 0xd5, 0xe0, 0xe7, 0x4f, 0x2a, 0xc7, 0xdb, 0xc8, 0x32, 0x2f, 0x4b, 0x7c, 0x42, 0x52, 0x4e, 0x84, - 0xb2, 0x5b, 0xc1, 0xc8, 0xe5, 0xe9, 0x0f, 0x3e, 0xaa, 0x8c, 0xfd, 0xed, 0xa3, 0xca, 0x98, 0x74, - 0x1b, 0x48, 0xfd, 0x14, 0xe1, 0x71, 0x72, 0x16, 0x9c, 0x0c, 0x0b, 0x5e, 0xb4, 0x5d, 0xa0, 0xd1, - 0x09, 0x2d, 0x21, 0xef, 0x6f, 0xd6, 0x6d, 0xda, 0x4e, 0x62, 0xf3, 0x7c, 0xa6, 0x75, 0xed, 0xd5, - 0xc7, 0xb4, 0x8e, 0xfd, 0xfb, 0x99, 0x96, 0x56, 0x24, 0x36, 0xad, 0xcb, 0x93, 0xdc, 0xb4, 0x0e, - 0xaf, 0x49, 0x0b, 0xe0, 0x0c, 0x03, 0xdc, 0xdd, 0x77, 0x89, 0xe7, 0x99, 0x98, 0x15, 0xb4, 0x30, - 0xed, 0x7e, 0x27, 0xf0, 0xc2, 0xd6, 0x31, 0xcb, 0xb7, 0xa9, 0x80, 0x59, 0x6a, 0x22, 0xba, 0xaf, - 0x5a, 0xd8, 0xc3, 0x2e, 0xdb, 0x61, 0x5c, 0x01, 0x6c, 0xe8, 0x4d, 0x7f, 0x04, 0xae, 0x83, 0xff, - 0x4b, 0x08, 0xa8, 0x2c, 0x8e, 0x90, 0xad, 0x61, 0x66, 0xfb, 0xb8, 0x72, 0x3a, 0x16, 0xdd, 0x0a, - 0xa7, 0xe0, 0xb7, 0xc1, 0xbc, 0x8d, 0xdf, 0xf5, 0x54, 0x17, 0x3b, 0x26, 0xb6, 0x0d, 0xba, 0xaf, - 0x6a, 0xc8, 0xd6, 0x7d, 0x63, 0x31, 0x4b, 0x99, 0xd9, 0x75, 0xb1, 0x1a, 0xdc, 0x8f, 0xd5, 0xf0, - 0x7e, 0xac, 0xee, 0x86, 0xf7, 0x63, 0x6d, 0xda, 0xaf, 0xce, 0x1f, 0xfe, 0xa9, 0x22, 0x28, 0x2f, - 0xf8, 0x28, 0x4a, 0x08, 0xb2, 0x1d, 0x62, 0x48, 0xe7, 0xc1, 0x0a, 0x33, 0x49, 0xc1, 0x4d, 0x83, - 0x7a, 0xd8, 0xc5, 0x7a, 0x9c, 0xf7, 0x8f, 0x90, 0xab, 0xd7, 0xb1, 0x4d, 0xac, 0xa8, 0xf0, 0x5c, - 0x03, 0xe7, 0x72, 0x49, 0x73, 0x8f, 0xbc, 0x00, 0xa6, 0x74, 0x36, 0xc2, 0x6a, 0xf9, 0x8c, 0xc2, - 0xbf, 0xa4, 0x32, 0xbf, 0x9d, 0x82, 0x9a, 0x82, 0x75, 0x56, 0x42, 0x1a, 0xf5, 0x68, 0x9b, 0xf7, - 0x05, 0xf0, 0x52, 0x0f, 0x01, 0x8e, 0x7c, 0x1f, 0x1c, 0x77, 0x92, 0x73, 0xe1, 0x6d, 0xb1, 0x9e, - 0xab, 0xb4, 0xa5, 0x60, 0xf9, 0x15, 0xd6, 0x81, 0x27, 0x35, 0xc0, 0xb1, 0x94, 0x18, 0x9c, 0x07, - 0x3c, 0x7e, 0xeb, 0xe9, 0x70, 0xae, 0xc3, 0x32, 0x00, 0x61, 0x49, 0x6c, 0xd4, 0xd9, 0x61, 0x4e, - 0x28, 0x89, 0x11, 0xe9, 0x16, 0x90, 0x99, 0x35, 0x5b, 0xa6, 0xb9, 0x83, 0x0c, 0x97, 0xee, 0x21, - 0x73, 0x9b, 0xd8, 0x7e, 0xc8, 0xd5, 0xd2, 0x15, 0xbc, 0x51, 0xcf, 0x71, 0xb5, 0xff, 0x4c, 0x00, - 0xab, 0xf9, 0xe1, 0xb8, 0xbf, 0x0e, 0xc0, 0x29, 0x07, 0x19, 0xae, 0xda, 0x42, 0xa6, 0xdf, 0xd7, - 0xb0, 0x34, 0xe0, 0x2e, 0xbb, 0x9e, 0xcf, 0x65, 0xc8, 0x70, 0xe3, 0x8d, 0xa2, 0x34, 0xb3, 0xe3, - 0x00, 0x38, 0xee, 0xa4, 0x44, 0xa4, 0x7f, 0x09, 0xe0, 0xe5, 0x81, 0xab, 0xe0, 0xf5, 0x5e, 0xb9, - 0x59, 0x5b, 0xf8, 0xfc, 0x49, 0xe5, 0xc5, 0xa0, 0x14, 0x74, 0x4a, 0x74, 0x97, 0x3b, 0x1f, 0xa7, - 0x47, 0x49, 0x49, 0xe0, 0x74, 0x4a, 0x74, 0xd7, 0x16, 0xb8, 0x09, 0x9e, 0x8f, 0xa4, 0x1e, 0xe2, - 0x36, 0xcf, 0xb1, 0xc5, 0x6a, 0xdc, 0xd5, 0x55, 0x83, 0xae, 0xae, 0xba, 0x73, 0xf8, 0xc0, 0x34, - 0xb4, 0x9b, 0xb8, 0xad, 0xcc, 0x86, 0x2b, 0x6e, 0xe2, 0xb6, 0x34, 0x07, 0x60, 0x10, 0xba, 0xc8, - 0x45, 0x71, 0xe2, 0xdc, 0x07, 0xa7, 0x53, 0xa3, 0xfc, 0x58, 0x1a, 0x60, 0xca, 0x61, 0x23, 0xfc, - 0x66, 0x3e, 0x97, 0xf3, 0x2c, 0xfc, 0x25, 0x3c, 0x6e, 0x39, 0x80, 0x74, 0x83, 0x27, 0x72, 0x2a, - 0x02, 0x6e, 0x3b, 0x1e, 0xd6, 0x1b, 0x76, 0x54, 0x1e, 0xf3, 0xb4, 0x8e, 0x07, 0x3c, 0xc7, 0x07, - 0x01, 0x45, 0xfd, 0xda, 0x4b, 0xc9, 0xfb, 0xb7, 0xe3, 0xa4, 0x70, 0x98, 0xfa, 0x0b, 0x89, 0x8b, - 0x38, 0x7d, 0x74, 0x98, 0x4a, 0x57, 0x40, 0x39, 0xb5, 0x65, 0x21, 0x7d, 0x3f, 0x16, 0xc0, 0x52, - 0x8f, 0xd5, 0xd1, 0xaf, 0xcc, 0xcb, 0x54, 0xc8, 0x7d, 0x99, 0x76, 0x45, 0x45, 0xa9, 0x60, 0x54, - 0xc0, 0x39, 0x30, 0xc9, 0x5a, 0x13, 0x16, 0x4f, 0xe3, 0x4a, 0xf0, 0xe1, 0x37, 0x9f, 0x95, 0x9e, - 0x86, 0x73, 0xff, 0x62, 0x00, 0x62, 0xd7, 0xf1, 0x94, 0xbd, 0x96, 0x2b, 0x4c, 0x06, 0x39, 0x45, - 0x49, 0x00, 0x4b, 0x07, 0xbc, 0xa8, 0xa4, 0xbb, 0xf2, 0x48, 0xf6, 0x0d, 0x44, 0x77, 0x09, 0xff, - 0x0a, 0xef, 0xc3, 0x11, 0x9d, 0x2a, 0x21, 0xb0, 0x56, 0x60, 0x4b, 0xee, 0x8e, 0xf3, 0x00, 0x46, - 0x27, 0x11, 0x46, 0x44, 0x18, 0x63, 0x51, 0x05, 0x08, 0xaa, 0x9f, 0xce, 0x3a, 0x95, 0x73, 0xd9, - 0xbd, 0xcf, 0x36, 0xb1, 0x2c, 0x83, 0x52, 0x83, 0xd8, 0x4a, 0xc2, 0xa2, 0xff, 0x59, 0x3b, 0x26, - 0x7d, 0x07, 0x9c, 0xcf, 0xa7, 0x08, 0xb7, 0xf3, 0x6b, 0x60, 0xc2, 0x0d, 0x79, 0xd9, 0x4c, 0xed, - 0xcb, 0x7e, 0xaa, 0xff, 0xf1, 0x49, 0x65, 0x21, 0x60, 0x8c, 0x54, 0x7f, 0x58, 0x35, 0x88, 0x6c, - 0x21, 0x6f, 0xbf, 0x7a, 0x0b, 0x37, 0x91, 0xd6, 0xae, 0x63, 0xed, 0xf7, 0xbf, 0x7e, 0x15, 0x70, - 0x42, 0x59, 0xc7, 0xda, 0xcf, 0xff, 0xfa, 0xcb, 0x15, 0x41, 0x61, 0x18, 0xd2, 0x06, 0x4f, 0x90, - 0xdb, 0xa6, 0x8e, 0xa9, 0x77, 0xd7, 0xd6, 0x88, 0xfd, 0x8e, 0xe1, 0x5a, 0x58, 0xdf, 0xa3, 0x5a, - 0x8e, 0x04, 0xfb, 0x41, 0xd8, 0xee, 0x65, 0xaf, 0xe7, 0x0a, 0x1b, 0x00, 0xb6, 0xa8, 0xa6, 0x52, - 0x6c, 0xeb, 0x6a, 0x44, 0xd0, 0x79, 0x59, 0xbb, 0x98, 0x2b, 0x5e, 0xf7, 0xa8, 0x76, 0x07, 0xdb, - 0x7a, 0xdc, 0xbd, 0x04, 0x05, 0xee, 0x64, 0xab, 0x63, 0x7c, 0xfd, 0xe3, 0x0a, 0x98, 0x64, 0x0a, - 0xc1, 0xa7, 0x02, 0x98, 0xcb, 0xe2, 0xb9, 0xf0, 0x6a, 0xf1, 0x0c, 0x49, 0x93, 0x6b, 0x71, 0x6b, - 0x04, 0x84, 0xc0, 0x25, 0xd2, 0xb5, 0xef, 0x7e, 0xf6, 0x97, 0x1f, 0x95, 0x36, 0xe1, 0xc6, 0xe0, - 0xb7, 0x94, 0x28, 0xa6, 0x39, 0x91, 0x96, 0x1f, 0x87, 0xa7, 0xf1, 0x1e, 0xfc, 0x4c, 0xe0, 0x97, - 0x47, 0x3a, 0x51, 0xe0, 0x66, 0x71, 0x0d, 0x53, 0x4c, 0x5c, 0xbc, 0x3a, 0x3c, 0x00, 0xb7, 0xf0, - 0x35, 0x66, 0xe1, 0x05, 0xb8, 0x56, 0xc0, 0xc2, 0x80, 0xa3, 0xc3, 0xf7, 0x4b, 0x60, 0xbe, 0x07, - 0xf1, 0xa6, 0xf0, 0xd6, 0x90, 0x9a, 0x65, 0x72, 0x7c, 0xf1, 0xcd, 0x23, 0x42, 0xe3, 0x46, 0xbf, - 0xc1, 0x8c, 0xae, 0xc1, 0xab, 0x45, 0x8d, 0x56, 0xa9, 0x0f, 0xa8, 0x46, 0xf4, 0x19, 0xfe, 0x47, - 0x00, 0x2f, 0x66, 0xf3, 0x78, 0x0a, 0x6f, 0x0e, 0xad, 0x74, 0xf7, 0x83, 0x81, 0x78, 0xeb, 0x68, - 0xc0, 0xb8, 0x03, 0x6e, 0x30, 0x07, 0x6c, 0xc1, 0xcd, 0x21, 0x1c, 0x40, 0x9c, 0x84, 0xfd, 0xff, - 0x0c, 0x09, 0x55, 0x26, 0x35, 0x85, 0xd7, 0xf3, 0x6b, 0xdd, 0x8f, 0x64, 0x8b, 0x37, 0x46, 0xc6, - 0xe1, 0x86, 0x6f, 0x31, 0xc3, 0xaf, 0xc0, 0xd7, 0x72, 0x3c, 0x8e, 0x46, 0x2f, 0x0c, 0xa9, 0xa6, - 0x33, 0xc3, 0xe4, 0x64, 0x3b, 0x34, 0x94, 0xc9, 0x19, 0xe4, 0x7b, 0x28, 0x93, 0xb3, 0xb8, 0xf3, - 0x70, 0x26, 0xa7, 0x2e, 0x4a, 0xf8, 0x5b, 0x81, 0xb7, 0xc4, 0x29, 0xda, 0x0c, 0x5f, 0xcf, 0xaf, - 0x62, 0x16, 0x1b, 0x17, 0x37, 0x87, 0x5e, 0xcf, 0x4d, 0xbb, 0xc4, 0x4c, 0x5b, 0x87, 0xab, 0x83, - 0x4d, 0xf3, 0x38, 0x40, 0xf0, 0x58, 0x0a, 0x7f, 0x52, 0x02, 0xaf, 0xe4, 0xe0, 0xc1, 0xf0, 0x76, - 0x7e, 0x15, 0x73, 0xf1, 0x6f, 0x71, 0xe7, 0xe8, 0x00, 0xb9, 0x13, 0x6e, 0x32, 0x27, 0x5c, 0x83, - 0xdb, 0x83, 0x9d, 0xe0, 0x46, 0x88, 0x71, 0x4c, 0xbb, 0x0c, 0x53, 0x0d, 0x78, 0x3d, 0xfc, 0x7b, - 0x17, 0x6f, 0x4f, 0xd3, 0x51, 0x0a, 0x0b, 0xdc, 0xaa, 0x3d, 0x1e, 0x07, 0xc4, 0xda, 0x28, 0x10, - 0xdc, 0xea, 0x1a, 0xb3, 0xfa, 0xab, 0xf0, 0xf2, 0x60, 0xab, 0xc3, 0x67, 0x01, 0xb5, 0xf3, 0x02, - 0xfb, 0x71, 0x89, 0xbf, 0x1c, 0xe7, 0xe0, 0xe1, 0x70, 0x37, 0xbf, 0xd2, 0xf9, 0x5f, 0x09, 0xc4, - 0xbb, 0x47, 0x8c, 0xca, 0xbd, 0x73, 0x85, 0x79, 0xe7, 0x22, 0xbc, 0x50, 0xb8, 0xbe, 0x1b, 0x3a, - 0xfc, 0x95, 0x00, 0x66, 0x13, 0x54, 0x17, 0x7e, 0xa5, 0xc0, 0x71, 0x25, 0x29, 0xb3, 0x78, 0xa9, - 0xf8, 0x42, 0xae, 0xff, 0x2a, 0xd3, 0x7f, 0x05, 0x2e, 0xe7, 0x38, 0xdd, 0x40, 0xc9, 0x1f, 0x86, - 0x09, 0xdd, 0x9f, 0xf4, 0x16, 0x49, 0xe8, 0x5c, 0x3c, 0xbc, 0x48, 0x42, 0xe7, 0xe3, 0xe3, 0x45, - 0xba, 0x13, 0xe2, 0x83, 0xa8, 0x86, 0xad, 0xc6, 0x3c, 0x30, 0xd9, 0x77, 0xfe, 0xa6, 0x04, 0xce, - 0xe6, 0x26, 0x68, 0xf0, 0xee, 0xb0, 0xcd, 0x64, 0x5f, 0x8e, 0x29, 0xee, 0x1d, 0x35, 0x2c, 0x77, - 0xd3, 0x3d, 0xe6, 0xa6, 0x5d, 0xa8, 0x14, 0xee, 0x5c, 0x55, 0x07, 0xbb, 0xb1, 0xc7, 0xe4, 0xc7, - 0x9d, 0xac, 0xf0, 0x3d, 0xf8, 0x8b, 0x12, 0xf8, 0xff, 0x3c, 0x64, 0x0f, 0xee, 0x8c, 0xd0, 0x98, - 0x64, 0x12, 0x58, 0xf1, 0xed, 0x23, 0x44, 0xe4, 0x9e, 0xba, 0xcf, 0x3c, 0x75, 0x0f, 0x7e, 0xa3, - 0x88, 0xa7, 0x22, 0x28, 0xd5, 0x67, 0xa0, 0x89, 0xa8, 0xca, 0xf2, 0xd7, 0xbf, 0x05, 0xfe, 0xea, - 0x9e, 0x45, 0x30, 0x61, 0x81, 0xc7, 0x8e, 0x3e, 0x04, 0x57, 0xbc, 0x3e, 0x2a, 0x4c, 0xf1, 0x0b, - 0x93, 0x30, 0x1c, 0xf5, 0x30, 0x06, 0x52, 0x5b, 0x54, 0x4b, 0xa6, 0xd8, 0x3f, 0x3a, 0x09, 0x40, - 0xa2, 0xd6, 0x6c, 0x8f, 0xf2, 0xc8, 0x13, 0x5a, 0x5d, 0x1f, 0x0d, 0x64, 0x04, 0xc6, 0x93, 0x59, - 0x53, 0x6a, 0x5f, 0xff, 0xe4, 0x69, 0x59, 0xf8, 0xf4, 0x69, 0x59, 0xf8, 0xf3, 0xd3, 0xb2, 0xf0, - 0xe1, 0xb3, 0xf2, 0xd8, 0xa7, 0xcf, 0xca, 0x63, 0x7f, 0x78, 0x56, 0x1e, 0xbb, 0xb7, 0xd1, 0x34, - 0xbc, 0xfd, 0xc3, 0x07, 0x55, 0x8d, 0x58, 0xfc, 0xff, 0xe2, 0x89, 0xcd, 0x5e, 0x8d, 0x36, 0x6b, - 0x5d, 0x94, 0xdf, 0xed, 0xe8, 0xcd, 0xda, 0x0e, 0xa6, 0x0f, 0xa6, 0xd8, 0x7f, 0x3f, 0x2e, 0xfc, - 0x37, 0x00, 0x00, 0xff, 0xff, 0xf5, 0x73, 0x8b, 0xa7, 0xb7, 0x20, 0x00, 0x00, + // 2015 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xcd, 0x6f, 0xdc, 0xc6, + 0x15, 0x17, 0x57, 0x1f, 0x91, 0x46, 0xf1, 0x47, 0xc6, 0x6a, 0x22, 0x53, 0xca, 0xae, 0x42, 0xf7, + 0x43, 0x96, 0x5d, 0x52, 0x92, 0x61, 0xc4, 0xb1, 0xab, 0xc8, 0x5a, 0xc9, 0x76, 0x16, 0x76, 0x62, + 0x85, 0x96, 0xd5, 0xc2, 0x2d, 0x4a, 0x8f, 0xc9, 0xc9, 0x8a, 0x30, 0x97, 0x43, 0x71, 0xb8, 0xeb, + 0x2c, 0x8c, 0x1c, 0xd2, 0x43, 0x9b, 0x53, 0x11, 0xf4, 0x03, 0xe8, 0x31, 0x97, 0x1e, 0x7b, 0xe9, + 0xa1, 0xc8, 0x9f, 0x90, 0x5b, 0x53, 0xe4, 0x52, 0xf4, 0xe0, 0x16, 0x72, 0x0f, 0x45, 0x0f, 0x45, + 0x61, 0x14, 0xe8, 0xa9, 0x40, 0xc1, 0xe1, 0xf0, 0x6b, 0x97, 0xbb, 0x4b, 0xee, 0x2a, 0xb7, 0xe5, + 0xcc, 0xbc, 0xdf, 0xbc, 0xf7, 0xe6, 0xbd, 0x37, 0xef, 0x37, 0x0b, 0x14, 0xd3, 0xf6, 0xb0, 0xab, + 0x1f, 0x20, 0xd3, 0xd6, 0x28, 0xd6, 0x9b, 0xae, 0xe9, 0xb5, 0x15, 0x5d, 0x6f, 0x29, 0x8e, 0x4b, + 0x5a, 0xa6, 0x81, 0x5d, 0xa5, 0xb5, 0xa6, 0x1c, 0x36, 0xb1, 0xdb, 0x96, 0x1d, 0x97, 0x78, 0x04, + 0x9e, 0xcb, 0x10, 0x90, 0x75, 0xbd, 0x25, 0x87, 0x02, 0x72, 0x6b, 0x4d, 0x5c, 0xac, 0x13, 0x52, + 0xb7, 0xb0, 0x82, 0x1c, 0x53, 0x41, 0xb6, 0x4d, 0x3c, 0xe4, 0x99, 0xc4, 0xa6, 0x01, 0x84, 0x38, + 0x57, 0x27, 0x75, 0xc2, 0x7e, 0x2a, 0xfe, 0x2f, 0x3e, 0x5a, 0xe1, 0x32, 0xec, 0xeb, 0x51, 0xf3, + 0x03, 0xc5, 0x33, 0x1b, 0x98, 0x7a, 0xa8, 0xe1, 0xf0, 0x05, 0xeb, 0x79, 0x54, 0x8d, 0xb4, 0x08, + 0x64, 0x56, 0x7b, 0xc9, 0xb4, 0xd6, 0x14, 0x7a, 0x80, 0x5c, 0x6c, 0x68, 0x3a, 0xb1, 0x69, 0xb3, + 0x11, 0x49, 0x7c, 0xab, 0x8f, 0xc4, 0x13, 0xd3, 0xc5, 0x7c, 0xd9, 0xa2, 0x87, 0x6d, 0x03, 0xbb, + 0x0d, 0xd3, 0xf6, 0x14, 0xdd, 0x6d, 0x3b, 0x1e, 0x51, 0x1e, 0xe3, 0x76, 0x68, 0xe1, 0x59, 0x9d, + 0xd0, 0x06, 0xa1, 0x5a, 0x60, 0x64, 0xf0, 0x11, 0x4c, 0x49, 0x57, 0xc0, 0xc2, 0xfb, 0xbe, 0x3b, + 0xb7, 0xf9, 0xb6, 0xb7, 0xb0, 0x8d, 0xa9, 0x49, 0x55, 0x7c, 0xd8, 0xc4, 0xd4, 0x83, 0x67, 0xc1, + 0x74, 0xb0, 0xb7, 0x69, 0xcc, 0x0b, 0x4b, 0xc2, 0xf2, 0x8c, 0xfa, 0x12, 0xfb, 0xae, 0x19, 0xd2, + 0x53, 0xb0, 0x98, 0x2d, 0x49, 0x1d, 0x62, 0x53, 0x0c, 0x7f, 0x08, 0x4e, 0xd4, 0x83, 0x21, 0x8d, + 0x7a, 0xc8, 0xc3, 0x4c, 0x7e, 0x76, 0x7d, 0x55, 0xee, 0x75, 0x62, 0xad, 0x35, 0xb9, 0x03, 0xeb, + 0x9e, 0x2f, 0x57, 0x9d, 0xf8, 0xe2, 0x59, 0x65, 0x4c, 0x7d, 0xb9, 0x9e, 0x18, 0x93, 0x16, 0x81, + 0x98, 0xda, 0x7c, 0xdb, 0x87, 0x0b, 0xb5, 0x96, 0x50, 0x87, 0x51, 0xe1, 0x2c, 0xd7, 0xac, 0x0a, + 0xa6, 0xd8, 0xf6, 0x74, 0x5e, 0x58, 0x1a, 0x5f, 0x9e, 0x5d, 0x5f, 0x91, 0x73, 0x04, 0x91, 0xcc, + 0x40, 0x54, 0x2e, 0x29, 0x9d, 0x07, 0xdf, 0xe9, 0xde, 0xe2, 0x9e, 0x87, 0x5c, 0x6f, 0xd7, 0x25, + 0x0e, 0xa1, 0xc8, 0x8a, 0xb4, 0xf9, 0x44, 0x00, 0xcb, 0x83, 0xd7, 0x72, 0xdd, 0x7e, 0x04, 0x66, + 0x9c, 0x70, 0x90, 0x7b, 0xec, 0xed, 0x7c, 0xea, 0x71, 0xf0, 0x2d, 0xc3, 0x30, 0xfd, 0xe8, 0x8e, + 0xa1, 0x63, 0x40, 0x69, 0x19, 0x7c, 0x3b, 0x4b, 0x13, 0xe2, 0x74, 0x29, 0xfd, 0x53, 0x21, 0xdb, + 0xc0, 0xd4, 0xd2, 0xe8, 0xa4, 0xbb, 0x74, 0xde, 0x28, 0xa4, 0xb3, 0x8a, 0x1b, 0xa4, 0x85, 0xac, + 0x4c, 0x95, 0x7f, 0x53, 0x02, 0x93, 0x6c, 0xef, 0x3e, 0xb1, 0x08, 0x17, 0xc0, 0x8c, 0x6e, 0x99, + 0xd8, 0xf6, 0xfc, 0xb9, 0x12, 0x9b, 0x9b, 0x0e, 0x06, 0x6a, 0x06, 0x3c, 0x03, 0x26, 0x3d, 0xe2, + 0x68, 0xef, 0xcd, 0x8f, 0x2f, 0x09, 0xcb, 0x27, 0xd4, 0x09, 0x8f, 0x38, 0xef, 0xc1, 0x15, 0x00, + 0x1b, 0xa6, 0xad, 0x39, 0xe4, 0x09, 0x76, 0x35, 0xd3, 0xd6, 0x82, 0x15, 0x13, 0x4b, 0xc2, 0xf2, + 0xb8, 0x7a, 0xb2, 0x61, 0xda, 0xbb, 0xfe, 0x44, 0xcd, 0xde, 0xf3, 0xd7, 0xae, 0x82, 0xb9, 0x16, + 0xb2, 0x4c, 0x03, 0x79, 0xc4, 0xa5, 0x5c, 0x44, 0x47, 0xce, 0xfc, 0x24, 0xc3, 0x83, 0xf1, 0x1c, + 0x13, 0xda, 0x46, 0x0e, 0x5c, 0x01, 0xaf, 0x44, 0xa3, 0x1a, 0xc5, 0x1e, 0x5b, 0x3e, 0xc5, 0x96, + 0x9f, 0x8a, 0x26, 0xee, 0x61, 0xcf, 0x5f, 0xbb, 0x08, 0x66, 0x90, 0x65, 0x91, 0x27, 0x96, 0x49, + 0xbd, 0xf9, 0x97, 0x96, 0xc6, 0x97, 0x67, 0xd4, 0x78, 0x00, 0x8a, 0x60, 0xda, 0xc0, 0x76, 0x9b, + 0x4d, 0x4e, 0xb3, 0xc9, 0xe8, 0x5b, 0xfa, 0x99, 0x00, 0xde, 0x60, 0x67, 0xb4, 0x1f, 0x42, 0x26, + 0x82, 0xc0, 0x1d, 0x9c, 0xc2, 0x70, 0x03, 0x9c, 0x0e, 0x8f, 0x43, 0x43, 0x86, 0xe1, 0x62, 0x4a, + 0x03, 0xef, 0x55, 0xe1, 0x8b, 0x67, 0x95, 0x93, 0x6d, 0xd4, 0xb0, 0xae, 0x4a, 0x7c, 0x42, 0x52, + 0x4f, 0x85, 0x6b, 0xb7, 0x82, 0x91, 0xab, 0xd3, 0x9f, 0x7c, 0x56, 0x19, 0xfb, 0xc7, 0x67, 0x95, + 0x31, 0xe9, 0x2e, 0x90, 0xfa, 0x29, 0xc2, 0xe3, 0xe4, 0x3c, 0x38, 0x1d, 0x56, 0xb7, 0x68, 0xbb, + 0x40, 0xa3, 0x53, 0x7a, 0x62, 0xbd, 0xbf, 0x59, 0xb7, 0x69, 0xbb, 0x89, 0xcd, 0xf3, 0x99, 0xd6, + 0xb5, 0x57, 0x1f, 0xd3, 0x3a, 0xf6, 0xef, 0x67, 0x5a, 0x5a, 0x91, 0xd8, 0xb4, 0x2e, 0x4f, 0x72, + 0xd3, 0x3a, 0xbc, 0x26, 0x2d, 0x80, 0xb3, 0x0c, 0x70, 0xef, 0xc0, 0x25, 0x9e, 0x67, 0x61, 0x56, + 0xd0, 0xc2, 0xb4, 0xfb, 0x93, 0xc0, 0x0b, 0x5b, 0xc7, 0x2c, 0xdf, 0xa6, 0x02, 0x66, 0xa9, 0x85, + 0xe8, 0x81, 0xd6, 0xc0, 0x1e, 0x76, 0xd9, 0x0e, 0xe3, 0x2a, 0x60, 0x43, 0xef, 0xfa, 0x23, 0x70, + 0x1d, 0x7c, 0x23, 0xb1, 0x40, 0x63, 0x71, 0x84, 0x6c, 0x1d, 0x33, 0xdb, 0xc7, 0xd5, 0x33, 0xf1, + 0xd2, 0xad, 0x70, 0x0a, 0xfe, 0x18, 0xcc, 0xdb, 0xf8, 0x43, 0x4f, 0x73, 0xb1, 0x63, 0x61, 0xdb, + 0xa4, 0x07, 0x9a, 0x8e, 0x6c, 0xc3, 0x37, 0x16, 0xb3, 0x94, 0x99, 0x5d, 0x17, 0xe5, 0xe0, 0x32, + 0x94, 0xc3, 0xcb, 0x50, 0xde, 0x0b, 0x2f, 0xc3, 0xea, 0xb4, 0x5f, 0x9d, 0x3f, 0xfd, 0x6b, 0x45, + 0x50, 0x5f, 0xf5, 0x51, 0xd4, 0x10, 0x64, 0x3b, 0xc4, 0x90, 0x2e, 0x82, 0x15, 0x66, 0x92, 0x8a, + 0xeb, 0x26, 0xf5, 0xb0, 0x8b, 0x8d, 0x38, 0xef, 0x9f, 0x20, 0xd7, 0xd8, 0xc1, 0x36, 0x69, 0x44, + 0x85, 0xe7, 0x06, 0xb8, 0x90, 0x6b, 0x35, 0xf7, 0xc8, 0xab, 0x60, 0xca, 0x60, 0x23, 0xac, 0x96, + 0xcf, 0xa8, 0xfc, 0x4b, 0x2a, 0xf3, 0xdb, 0x29, 0xa8, 0x29, 0xd8, 0x60, 0x25, 0xa4, 0xb6, 0x13, + 0x6d, 0xf3, 0xb1, 0x00, 0x5e, 0xef, 0xb1, 0x80, 0x23, 0x3f, 0x04, 0x27, 0x9d, 0xe4, 0x5c, 0x78, + 0x5b, 0xac, 0xe7, 0x2a, 0x6d, 0x29, 0x58, 0x7e, 0x85, 0x75, 0xe0, 0x49, 0x35, 0x70, 0x22, 0xb5, + 0x0c, 0xce, 0x03, 0x1e, 0xbf, 0x3b, 0xe9, 0x70, 0xde, 0x81, 0x65, 0x00, 0xc2, 0x92, 0x58, 0xdb, + 0x61, 0x87, 0x39, 0xa1, 0x26, 0x46, 0xa4, 0x3b, 0x40, 0x61, 0xd6, 0x6c, 0x59, 0xd6, 0x2e, 0x32, + 0x5d, 0xba, 0x8f, 0xac, 0x6d, 0x62, 0xfb, 0x21, 0x57, 0x4d, 0x57, 0xf0, 0xda, 0x4e, 0x8e, 0xab, + 0xfd, 0xb7, 0x02, 0x58, 0xcd, 0x0f, 0xc7, 0xfd, 0x75, 0x08, 0x5e, 0x71, 0x90, 0xe9, 0x6a, 0x2d, + 0x64, 0xf9, 0x4d, 0x0c, 0x4b, 0x03, 0xee, 0xb2, 0x9b, 0xf9, 0x5c, 0x86, 0x4c, 0x37, 0xde, 0x28, + 0x4a, 0x33, 0x3b, 0x0e, 0x80, 0x93, 0x4e, 0x6a, 0x89, 0xf4, 0x1f, 0x01, 0xbc, 0x31, 0x50, 0x0a, + 0xde, 0xec, 0x95, 0x9b, 0xd5, 0x85, 0x17, 0xcf, 0x2a, 0xaf, 0x05, 0xa5, 0xa0, 0x73, 0x45, 0x77, + 0xb9, 0xf3, 0x71, 0x7a, 0x94, 0x94, 0x04, 0x4e, 0xe7, 0x8a, 0xee, 0xda, 0x02, 0x37, 0xc1, 0xcb, + 0xd1, 0xaa, 0xc7, 0xb8, 0xcd, 0x73, 0x6c, 0x51, 0x8e, 0x5b, 0x38, 0x39, 0x68, 0xe1, 0xe4, 0xdd, + 0xe6, 0x23, 0xcb, 0xd4, 0x6f, 0xe3, 0xb6, 0x3a, 0x1b, 0x4a, 0xdc, 0xc6, 0x6d, 0x69, 0x0e, 0xc0, + 0x20, 0x74, 0x91, 0x8b, 0xe2, 0xc4, 0x79, 0x08, 0xce, 0xa4, 0x46, 0xf9, 0xb1, 0xd4, 0xc0, 0x94, + 0xc3, 0x46, 0xf8, 0xcd, 0x7c, 0x21, 0xe7, 0x59, 0xf8, 0x22, 0x3c, 0x6e, 0x39, 0x80, 0x74, 0x8b, + 0x27, 0x72, 0x2a, 0x02, 0xee, 0x3a, 0x1e, 0x36, 0x6a, 0x76, 0x54, 0x1e, 0xf3, 0xb4, 0x8e, 0x87, + 0x3c, 0xc7, 0x07, 0x01, 0x45, 0xfd, 0xda, 0xeb, 0xc9, 0xfb, 0xb7, 0xe3, 0xa4, 0x70, 0x98, 0xfa, + 0x0b, 0x89, 0x8b, 0x38, 0x7d, 0x74, 0x98, 0x4a, 0xd7, 0x40, 0x39, 0xb5, 0x65, 0x21, 0x7d, 0x3f, + 0x17, 0xc0, 0x52, 0x0f, 0xe9, 0xe8, 0x57, 0xe6, 0x65, 0x2a, 0xe4, 0xbe, 0x4c, 0xbb, 0xa2, 0xa2, + 0x54, 0x30, 0x2a, 0xe0, 0x1c, 0x98, 0x64, 0xad, 0x09, 0x8b, 0xa7, 0x71, 0x35, 0xf8, 0xf0, 0x9b, + 0xcf, 0x4a, 0x4f, 0xc3, 0xb9, 0x7f, 0x31, 0x00, 0xb1, 0xeb, 0x78, 0xca, 0xde, 0xc8, 0x15, 0x26, + 0x83, 0x9c, 0xa2, 0x26, 0x80, 0xa5, 0x43, 0x5e, 0x54, 0xd2, 0x5d, 0x79, 0xb4, 0xf6, 0x1d, 0x44, + 0xf7, 0x08, 0xff, 0x0a, 0xef, 0xc3, 0x11, 0x9d, 0x2a, 0x21, 0xb0, 0x56, 0x60, 0x4b, 0xee, 0x8e, + 0x8b, 0x00, 0x46, 0x27, 0x11, 0x46, 0x44, 0x18, 0x63, 0x51, 0x05, 0x08, 0xaa, 0x9f, 0xc1, 0x3a, + 0x95, 0x0b, 0xd9, 0xbd, 0xcf, 0x36, 0x69, 0x34, 0x4c, 0x4a, 0x4d, 0x62, 0xab, 0x09, 0x8b, 0xbe, + 0xb6, 0x76, 0x4c, 0xaa, 0x83, 0x8b, 0xf9, 0x14, 0xe1, 0x76, 0xbe, 0x09, 0x26, 0xdc, 0x90, 0x97, + 0xcd, 0x54, 0xcf, 0xf9, 0xa9, 0xfe, 0x97, 0x67, 0x95, 0x85, 0x80, 0x1e, 0x52, 0xe3, 0xb1, 0x6c, + 0x12, 0xa5, 0x81, 0xbc, 0x03, 0xf9, 0x0e, 0xae, 0x23, 0xbd, 0xbd, 0x83, 0x75, 0x95, 0x09, 0x48, + 0x1b, 0x3c, 0x1b, 0xee, 0x5a, 0x06, 0xa6, 0xde, 0x7d, 0x5b, 0x27, 0xf6, 0x07, 0xa6, 0xdb, 0xc0, + 0xc6, 0x3e, 0xd5, 0x73, 0x64, 0xd3, 0xcf, 0xc3, 0xde, 0x2e, 0x5b, 0x9e, 0x6b, 0x67, 0x02, 0xd8, + 0xa2, 0xba, 0x46, 0xb1, 0x6d, 0x68, 0x11, 0xf5, 0xe6, 0x35, 0xec, 0x72, 0xae, 0xe0, 0xdc, 0xa7, + 0xfa, 0x3d, 0x6c, 0x1b, 0x71, 0xab, 0x12, 0x54, 0xb3, 0xd3, 0xad, 0x8e, 0xf1, 0xf5, 0xcf, 0x2b, + 0x60, 0x92, 0x29, 0x04, 0x8f, 0x04, 0x30, 0x97, 0x45, 0x6a, 0xe1, 0xf5, 0xe2, 0xe9, 0x90, 0x66, + 0xd2, 0xe2, 0xd6, 0x08, 0x08, 0x81, 0x4b, 0xa4, 0x1b, 0x3f, 0xf9, 0xea, 0xef, 0xbf, 0x2c, 0x6d, + 0xc2, 0x8d, 0xc1, 0xaf, 0x24, 0x51, 0x00, 0x73, 0xd6, 0xac, 0x3c, 0x0d, 0x4f, 0xe3, 0x23, 0xf8, + 0x95, 0xc0, 0x6f, 0x8a, 0x74, 0x56, 0xc0, 0xcd, 0xe2, 0x1a, 0xa6, 0x68, 0xb7, 0x78, 0x7d, 0x78, + 0x00, 0x6e, 0xe1, 0x5b, 0xcc, 0xc2, 0x4b, 0x70, 0xad, 0x80, 0x85, 0x01, 0x21, 0x87, 0x1f, 0x97, + 0xc0, 0x7c, 0x0f, 0x96, 0x4d, 0xe1, 0x9d, 0x21, 0x35, 0xcb, 0x24, 0xf4, 0xe2, 0xbb, 0xc7, 0x84, + 0xc6, 0x8d, 0x7e, 0x87, 0x19, 0x5d, 0x85, 0xd7, 0x8b, 0x1a, 0xad, 0x51, 0x1f, 0x50, 0x8b, 0xb8, + 0x32, 0xfc, 0x9f, 0x00, 0x5e, 0xcb, 0x26, 0xed, 0x14, 0xde, 0x1e, 0x5a, 0xe9, 0xee, 0xd7, 0x01, + 0xf1, 0xce, 0xf1, 0x80, 0x71, 0x07, 0xdc, 0x62, 0x0e, 0xd8, 0x82, 0x9b, 0x43, 0x38, 0x80, 0x38, + 0x09, 0xfb, 0xff, 0x1d, 0xb2, 0xa7, 0x4c, 0x1e, 0x0a, 0x6f, 0xe6, 0xd7, 0xba, 0x1f, 0xa3, 0x16, + 0x6f, 0x8d, 0x8c, 0xc3, 0x0d, 0xdf, 0x62, 0x86, 0x5f, 0x83, 0x6f, 0xe5, 0x78, 0xf6, 0x8c, 0x9e, + 0x13, 0x52, 0x1d, 0x66, 0x86, 0xc9, 0xc9, 0xde, 0x67, 0x28, 0x93, 0x33, 0x98, 0xf6, 0x50, 0x26, + 0x67, 0x11, 0xe5, 0xe1, 0x4c, 0x4e, 0xdd, 0x8a, 0xf0, 0x8f, 0x02, 0xef, 0x7f, 0x53, 0x1c, 0x19, + 0xbe, 0x9d, 0x5f, 0xc5, 0x2c, 0xea, 0x2d, 0x6e, 0x0e, 0x2d, 0xcf, 0x4d, 0xbb, 0xc2, 0x4c, 0x5b, + 0x87, 0xab, 0x83, 0x4d, 0xf3, 0x38, 0x40, 0xf0, 0x32, 0x0a, 0x7f, 0x5d, 0x02, 0xe7, 0x72, 0x90, + 0x5e, 0x78, 0x37, 0xbf, 0x8a, 0xb9, 0xc8, 0xb6, 0xb8, 0x7b, 0x7c, 0x80, 0xdc, 0x09, 0xb7, 0x99, + 0x13, 0x6e, 0xc0, 0xed, 0xc1, 0x4e, 0x70, 0x23, 0xc4, 0x38, 0xa6, 0x5d, 0x86, 0xa9, 0x05, 0x24, + 0x1e, 0xfe, 0xb3, 0x8b, 0xa4, 0xa7, 0xb9, 0x27, 0x85, 0x05, 0x6e, 0xd5, 0x1e, 0x2f, 0x01, 0x62, + 0x75, 0x14, 0x08, 0x6e, 0x75, 0x95, 0x59, 0xfd, 0x3d, 0x78, 0x75, 0xb0, 0xd5, 0xe1, 0x1b, 0x80, + 0xd6, 0x79, 0x81, 0xfd, 0xaa, 0xc4, 0x9f, 0x89, 0x73, 0x90, 0x6e, 0xb8, 0x97, 0x5f, 0xe9, 0xfc, + 0x4f, 0x02, 0xe2, 0xfd, 0x63, 0x46, 0xe5, 0xde, 0xb9, 0xc6, 0xbc, 0x73, 0x19, 0x5e, 0x2a, 0x5c, + 0xdf, 0x4d, 0x03, 0xfe, 0x5e, 0x00, 0xb3, 0x09, 0x5e, 0x0b, 0xdf, 0x2c, 0x70, 0x5c, 0x49, 0x7e, + 0x2c, 0x5e, 0x29, 0x2e, 0xc8, 0xf5, 0x5f, 0x65, 0xfa, 0xaf, 0xc0, 0xe5, 0x1c, 0xa7, 0x1b, 0x28, + 0xf9, 0x8b, 0x30, 0xa1, 0xfb, 0x33, 0xdc, 0x22, 0x09, 0x9d, 0x8b, 0x74, 0x17, 0x49, 0xe8, 0x7c, + 0xe4, 0xbb, 0x48, 0x77, 0x42, 0x7c, 0x10, 0xcd, 0xb4, 0xb5, 0x98, 0xf4, 0x25, 0xfb, 0xce, 0x3f, + 0x94, 0xc0, 0xf9, 0xdc, 0x6c, 0x0c, 0xde, 0x1f, 0xb6, 0x99, 0xec, 0x4b, 0x28, 0xc5, 0xfd, 0xe3, + 0x86, 0xe5, 0x6e, 0x7a, 0xc0, 0xdc, 0xb4, 0x07, 0xd5, 0xc2, 0x9d, 0xab, 0xe6, 0x60, 0x37, 0xf6, + 0x98, 0xf2, 0xb4, 0x93, 0x02, 0x7e, 0x04, 0x7f, 0x57, 0x02, 0xdf, 0xcc, 0xc3, 0xec, 0xe0, 0xee, + 0x08, 0x8d, 0x49, 0x26, 0x5b, 0x15, 0xdf, 0x3f, 0x46, 0x44, 0xee, 0xa9, 0x87, 0xcc, 0x53, 0x0f, + 0xe0, 0x0f, 0x8a, 0x78, 0x2a, 0x82, 0xd2, 0x7c, 0x06, 0x9a, 0x88, 0xaa, 0x2c, 0x7f, 0xfd, 0x57, + 0xe0, 0x4f, 0xec, 0x59, 0x04, 0x13, 0x16, 0x78, 0xd9, 0xe8, 0x43, 0x70, 0xc5, 0x9b, 0xa3, 0xc2, + 0x14, 0xbf, 0x30, 0x09, 0xc3, 0xd1, 0x9a, 0x31, 0x90, 0xd6, 0xa2, 0x7a, 0x32, 0xc5, 0xfe, 0xd5, + 0x49, 0x00, 0x12, 0xb5, 0x66, 0x7b, 0x94, 0x17, 0x9d, 0xd0, 0xea, 0x9d, 0xd1, 0x40, 0x46, 0x60, + 0x3c, 0x99, 0x35, 0xa5, 0xfa, 0xfd, 0x2f, 0x8e, 0xca, 0xc2, 0x97, 0x47, 0x65, 0xe1, 0x6f, 0x47, + 0x65, 0xe1, 0xd3, 0xe7, 0xe5, 0xb1, 0x2f, 0x9f, 0x97, 0xc7, 0xfe, 0xfc, 0xbc, 0x3c, 0xf6, 0x60, + 0xa3, 0x6e, 0x7a, 0x07, 0xcd, 0x47, 0xb2, 0x4e, 0x1a, 0xfc, 0x1f, 0xef, 0xc4, 0x66, 0xdf, 0x8d, + 0x36, 0x6b, 0x5d, 0x56, 0x3e, 0xec, 0xe8, 0xcd, 0xda, 0x0e, 0xa6, 0x8f, 0xa6, 0xd8, 0x5f, 0x1d, + 0x97, 0xfe, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xb7, 0x4e, 0xa1, 0x75, 0x91, 0x20, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/ccv/provider/types/tx.pb.go b/x/ccv/provider/types/tx.pb.go index debc79ba02..be71e8fa18 100644 --- a/x/ccv/provider/types/tx.pb.go +++ b/x/ccv/provider/types/tx.pb.go @@ -1295,113 +1295,113 @@ func init() { } var fileDescriptor_43221a4391e9fbf4 = []byte{ - // 1689 bytes of a gzipped FileDescriptorProto + // 1687 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x58, 0xcf, 0x6f, 0xe4, 0x48, - 0x15, 0x8e, 0xf3, 0x6b, 0xba, 0xab, 0xf3, 0xd3, 0x93, 0x90, 0x8e, 0x37, 0xdb, 0x9d, 0x34, 0xcb, - 0x6e, 0x34, 0x6c, 0xec, 0x9d, 0xc0, 0xce, 0x42, 0xb4, 0x08, 0x92, 0xf4, 0xc2, 0x64, 0x20, 0x93, + 0x15, 0x8e, 0xf3, 0x6b, 0xba, 0xab, 0xf3, 0xd3, 0x93, 0x21, 0x1d, 0x6f, 0xb6, 0x3b, 0x69, 0x96, + 0xdd, 0x68, 0xd8, 0xd8, 0x9b, 0xc0, 0xee, 0x42, 0xb4, 0x08, 0x92, 0xf4, 0xc0, 0x64, 0x21, 0x93, 0xe0, 0x09, 0x8b, 0x04, 0x12, 0x56, 0xb5, 0x5d, 0x71, 0x97, 0xc6, 0x76, 0x59, 0x55, 0xd5, 0x9d, - 0xed, 0x1b, 0xda, 0x13, 0x12, 0x02, 0x2d, 0x37, 0xc4, 0x69, 0x0f, 0x08, 0x81, 0x04, 0xd2, 0x1c, - 0xf6, 0xc4, 0x8d, 0xdb, 0x1c, 0x38, 0x2c, 0x2b, 0x0e, 0x88, 0xc3, 0x80, 0x66, 0x0e, 0xcb, 0x99, - 0xbf, 0x00, 0x55, 0xb9, 0xec, 0x76, 0x27, 0x9d, 0xde, 0xee, 0x0e, 0x1c, 0xb8, 0xb4, 0xda, 0xf5, - 0xbe, 0xf7, 0xd5, 0xf7, 0x3d, 0xbb, 0x5e, 0x95, 0x0d, 0x5e, 0xc7, 0x11, 0x47, 0xd4, 0x6d, 0x42, - 0x1c, 0x39, 0x0c, 0xb9, 0x2d, 0x8a, 0x79, 0xc7, 0x72, 0xdd, 0xb6, 0x15, 0x53, 0xd2, 0xc6, 0x1e, - 0xa2, 0x56, 0xfb, 0xae, 0xc5, 0xdf, 0x33, 0x63, 0x4a, 0x38, 0xd1, 0x3f, 0xdf, 0x07, 0x6d, 0xba, - 0x6e, 0xdb, 0x4c, 0xd1, 0x66, 0xfb, 0xae, 0xb1, 0x0c, 0x43, 0x1c, 0x11, 0x4b, 0xfe, 0x26, 0x79, - 0xc6, 0x86, 0x4f, 0x88, 0x1f, 0x20, 0x0b, 0xc6, 0xd8, 0x82, 0x51, 0x44, 0x38, 0xe4, 0x98, 0x44, - 0x4c, 0x45, 0xab, 0x2a, 0x2a, 0xaf, 0x1a, 0xad, 0x73, 0x8b, 0xe3, 0x10, 0x31, 0x0e, 0xc3, 0x58, - 0x01, 0x2a, 0x97, 0x01, 0x5e, 0x8b, 0x4a, 0x06, 0x15, 0x5f, 0xbf, 0x1c, 0x87, 0x51, 0x47, 0x85, - 0x56, 0x7c, 0xe2, 0x13, 0xf9, 0xd7, 0x12, 0xff, 0xd2, 0x04, 0x97, 0xb0, 0x90, 0x30, 0x27, 0x09, - 0x24, 0x17, 0x2a, 0xb4, 0x96, 0x5c, 0x59, 0x21, 0xf3, 0x85, 0xf5, 0x90, 0xf9, 0xa9, 0x4a, 0xdc, - 0x70, 0x2d, 0x97, 0x50, 0x64, 0xb9, 0x01, 0x46, 0x11, 0x17, 0xd1, 0xe4, 0x9f, 0x02, 0xec, 0x0e, - 0x53, 0xca, 0xac, 0x50, 0x49, 0x8e, 0x25, 0x48, 0x03, 0xec, 0x37, 0x79, 0x42, 0xc5, 0x2c, 0x8e, - 0x22, 0x0f, 0xd1, 0x10, 0x27, 0x13, 0x74, 0xaf, 0x52, 0x15, 0xb9, 0x38, 0xef, 0xc4, 0x88, 0x59, - 0x48, 0xf0, 0x45, 0x2e, 0x4a, 0x00, 0xb5, 0xbf, 0x6a, 0x60, 0xe5, 0x98, 0xf9, 0xfb, 0x8c, 0x61, - 0x3f, 0x3a, 0x24, 0x11, 0x6b, 0x85, 0x88, 0x7e, 0x1b, 0x75, 0xf4, 0x75, 0x50, 0x48, 0xb4, 0x61, - 0xaf, 0xac, 0x6d, 0x6a, 0xdb, 0x45, 0xfb, 0x96, 0xbc, 0x3e, 0xf2, 0xf4, 0xb7, 0xc0, 0x7c, 0xaa, - 0xcb, 0x81, 0x9e, 0x47, 0xcb, 0x93, 0x22, 0x7e, 0xa0, 0xff, 0xfb, 0x59, 0x75, 0xa1, 0x03, 0xc3, - 0x60, 0xaf, 0x26, 0x46, 0x11, 0x63, 0x35, 0x7b, 0x2e, 0x05, 0xee, 0x7b, 0x1e, 0xd5, 0xb7, 0xc0, - 0x9c, 0xab, 0xa6, 0x70, 0x1e, 0xa3, 0x4e, 0x79, 0x4a, 0xf2, 0x96, 0xdc, 0xdc, 0xb4, 0x6f, 0x80, - 0x59, 0xa1, 0x04, 0xd1, 0xf2, 0xb4, 0x24, 0x2d, 0x7f, 0xf2, 0xd1, 0xce, 0x8a, 0xaa, 0xf8, 0x7e, - 0xc2, 0xfa, 0x88, 0x53, 0x1c, 0xf9, 0xb6, 0xc2, 0xed, 0xdd, 0xfe, 0xc9, 0x87, 0xd5, 0x89, 0x7f, - 0x7d, 0x58, 0x9d, 0x78, 0xff, 0xd3, 0x27, 0x77, 0xd4, 0x60, 0xad, 0x02, 0x36, 0xfa, 0xb9, 0xb2, - 0x11, 0x8b, 0x49, 0xc4, 0x50, 0xed, 0x4f, 0x1a, 0x78, 0xf9, 0x98, 0xf9, 0x8f, 0x5a, 0x8d, 0x10, - 0xf3, 0x14, 0x70, 0x8c, 0x59, 0x03, 0x35, 0x61, 0x1b, 0x93, 0x16, 0xd5, 0xef, 0x81, 0x22, 0x93, - 0x51, 0x8e, 0x68, 0x52, 0x80, 0x01, 0x5a, 0xba, 0x50, 0xfd, 0x14, 0xcc, 0x85, 0x39, 0x1e, 0x59, - 0x9b, 0xd2, 0xee, 0xeb, 0x26, 0x6e, 0xb8, 0x66, 0xfe, 0xce, 0x99, 0xb9, 0x7b, 0xd5, 0xbe, 0x6b, - 0xe6, 0xe7, 0xb6, 0x7b, 0x18, 0xf6, 0x3e, 0x97, 0x37, 0xd8, 0x9d, 0xa9, 0xf6, 0x1a, 0xf8, 0xc2, - 0x40, 0x0b, 0x99, 0xd9, 0x27, 0x93, 0x7d, 0xcc, 0xd6, 0x49, 0xab, 0x11, 0xa0, 0x77, 0x09, 0xc7, - 0x91, 0x3f, 0xb6, 0x59, 0x07, 0xac, 0x79, 0xad, 0x38, 0xc0, 0x2e, 0xe4, 0xc8, 0x69, 0x13, 0x8e, - 0x9c, 0xf4, 0xf1, 0x52, 0xbe, 0x5f, 0xcb, 0xdb, 0x94, 0x0f, 0xa0, 0x59, 0x4f, 0x13, 0xde, 0x25, - 0x1c, 0xbd, 0xa3, 0xe0, 0xf6, 0xaa, 0xd7, 0x6f, 0x58, 0xff, 0x11, 0x58, 0xc3, 0xd1, 0x39, 0x85, - 0xae, 0x58, 0xbe, 0x4e, 0x23, 0x20, 0xee, 0x63, 0xa7, 0x89, 0xa0, 0x87, 0xa8, 0x7c, 0x78, 0x4a, - 0xbb, 0xaf, 0x7e, 0x56, 0x61, 0xef, 0x4b, 0xb4, 0xbd, 0xda, 0xa5, 0x39, 0x10, 0x2c, 0xc9, 0xf0, - 0x48, 0xb5, 0xcd, 0x57, 0x2c, 0xab, 0xed, 0xaf, 0x35, 0xb0, 0x78, 0xcc, 0xfc, 0xef, 0xc5, 0x1e, - 0xe4, 0xe8, 0x14, 0x52, 0x18, 0x32, 0x51, 0x4d, 0xd8, 0xe2, 0x4d, 0x22, 0x56, 0xf4, 0x67, 0x57, - 0x33, 0x83, 0xea, 0x47, 0x60, 0x36, 0x96, 0x0c, 0xaa, 0x78, 0x5f, 0x34, 0x87, 0xe8, 0x9f, 0x66, - 0x32, 0xe9, 0xc1, 0xf4, 0xd3, 0x67, 0xd5, 0x09, 0x5b, 0x11, 0xec, 0x2d, 0x48, 0x3f, 0x19, 0x75, - 0x6d, 0x1d, 0xac, 0x5d, 0x52, 0x99, 0x39, 0xf8, 0x59, 0x01, 0xdc, 0x3e, 0x66, 0x7e, 0xea, 0x72, - 0xdf, 0xf3, 0xb0, 0xa8, 0xd2, 0xa0, 0x06, 0xf0, 0x2d, 0xb0, 0x80, 0x23, 0xcc, 0x31, 0x0c, 0x9c, - 0x26, 0x12, 0xa5, 0x57, 0x82, 0x0d, 0x79, 0x33, 0x44, 0xd3, 0x33, 0x55, 0xab, 0x93, 0x37, 0x40, - 0x20, 0x94, 0xbe, 0x79, 0x95, 0x97, 0x0c, 0x8a, 0x86, 0xe0, 0xa3, 0x08, 0x31, 0xcc, 0x9c, 0x26, - 0x64, 0x4d, 0x79, 0x4f, 0xe7, 0xec, 0x92, 0x1a, 0xbb, 0x0f, 0x59, 0x53, 0xaf, 0x82, 0x52, 0x03, - 0x47, 0x90, 0x76, 0x12, 0xc4, 0xb4, 0x44, 0x80, 0x64, 0x48, 0x02, 0x0e, 0x01, 0x60, 0x31, 0xbc, - 0x88, 0x1c, 0xb1, 0x0d, 0x94, 0x67, 0x94, 0x90, 0xa4, 0xc5, 0x9b, 0x69, 0x8b, 0x37, 0xcf, 0xd2, - 0x3d, 0xe2, 0xa0, 0x20, 0x84, 0x7c, 0xf0, 0x8f, 0xaa, 0x66, 0x17, 0x65, 0x9e, 0x88, 0xe8, 0x0f, - 0xc1, 0x52, 0x2b, 0x6a, 0x90, 0xc8, 0xc3, 0x91, 0xef, 0xc4, 0x88, 0x62, 0xe2, 0x95, 0x67, 0x25, - 0xd5, 0xfa, 0x15, 0xaa, 0xba, 0xda, 0x4d, 0x12, 0xa6, 0x5f, 0x0a, 0xa6, 0xc5, 0x2c, 0xf9, 0x54, - 0xe6, 0xea, 0xdf, 0x05, 0xba, 0xeb, 0xb6, 0xa5, 0x24, 0xd2, 0xe2, 0x29, 0xe3, 0xad, 0xe1, 0x19, - 0x97, 0x5c, 0xb7, 0x7d, 0x96, 0x64, 0x2b, 0xca, 0x1f, 0x82, 0x35, 0x4e, 0x61, 0xc4, 0xce, 0x11, - 0xbd, 0xcc, 0x5b, 0x18, 0x9e, 0x77, 0x35, 0xe5, 0xe8, 0x25, 0xbf, 0x0f, 0x36, 0xb3, 0xce, 0x4c, - 0x91, 0x87, 0x19, 0xa7, 0xb8, 0xd1, 0x92, 0x8b, 0x2e, 0x5d, 0x36, 0xe5, 0xa2, 0x7c, 0x08, 0x2a, - 0x29, 0xce, 0xee, 0x81, 0x7d, 0x53, 0xa1, 0xf4, 0x13, 0xf0, 0x8a, 0x5c, 0xa6, 0x4c, 0x88, 0x73, - 0x7a, 0x98, 0xe4, 0xd4, 0x21, 0x66, 0x4c, 0xb0, 0x81, 0x4d, 0x6d, 0x7b, 0xca, 0xde, 0x4a, 0xb0, - 0xa7, 0x88, 0xd6, 0x73, 0xc8, 0xb3, 0x1c, 0x50, 0xdf, 0x01, 0x7a, 0x13, 0x33, 0x4e, 0x28, 0x76, - 0x61, 0xe0, 0xa0, 0x88, 0x53, 0x8c, 0x58, 0xb9, 0x24, 0xd3, 0x97, 0xbb, 0x91, 0x77, 0x92, 0x80, - 0xfe, 0x00, 0x6c, 0x5d, 0x3b, 0xa9, 0xe3, 0x36, 0x61, 0x14, 0xa1, 0xa0, 0x3c, 0x27, 0xad, 0x54, - 0xbd, 0x6b, 0xe6, 0x3c, 0x4c, 0x60, 0xfa, 0x6d, 0x30, 0xc3, 0x49, 0xec, 0x3c, 0x2c, 0xcf, 0x6f, - 0x6a, 0xdb, 0xf3, 0xf6, 0x34, 0x27, 0xf1, 0x43, 0xfd, 0x0d, 0xb0, 0xd2, 0x86, 0x01, 0xf6, 0x20, - 0x27, 0x94, 0x39, 0x31, 0xb9, 0x40, 0xd4, 0x71, 0x61, 0x5c, 0x5e, 0x90, 0x18, 0xbd, 0x1b, 0x3b, - 0x15, 0xa1, 0x43, 0x18, 0xeb, 0x77, 0xc0, 0x72, 0x36, 0xea, 0x30, 0xc4, 0x25, 0x7c, 0x51, 0xc2, - 0x17, 0xb3, 0xc0, 0x23, 0xc4, 0x05, 0x76, 0x03, 0x14, 0x61, 0x10, 0x90, 0x8b, 0x00, 0x33, 0x5e, - 0x5e, 0xda, 0x9c, 0xda, 0x2e, 0xda, 0xdd, 0x01, 0xdd, 0x00, 0x05, 0x0f, 0x45, 0x1d, 0x19, 0x5c, - 0x96, 0xc1, 0xec, 0xba, 0xb7, 0xeb, 0xe8, 0x43, 0x77, 0x9d, 0x2b, 0xad, 0xe2, 0x65, 0xf0, 0x52, - 0x9f, 0x76, 0x90, 0xb5, 0x8b, 0x3f, 0x6a, 0x40, 0xcf, 0xc5, 0x6d, 0x14, 0x92, 0x36, 0x0c, 0x06, - 0x75, 0x8b, 0x7d, 0x50, 0x64, 0xa2, 0x8c, 0x72, 0x7d, 0x4e, 0x8e, 0xb0, 0x3e, 0x0b, 0x22, 0x4d, - 0x2e, 0xcf, 0x1e, 0x6f, 0x53, 0xe3, 0x7b, 0xdb, 0x00, 0xc6, 0x55, 0xed, 0x99, 0xb5, 0x3f, 0x68, - 0x60, 0x55, 0x84, 0x9b, 0x30, 0xf2, 0x91, 0x8d, 0x2e, 0x20, 0xf5, 0xea, 0x28, 0x22, 0x21, 0xd3, - 0x6b, 0x60, 0xde, 0x93, 0xff, 0x1c, 0x4e, 0xc4, 0x91, 0xa7, 0xac, 0xc9, 0xe2, 0x97, 0x92, 0xc1, - 0x33, 0xb2, 0xef, 0x79, 0xfa, 0x36, 0x58, 0xea, 0x62, 0xa8, 0xa0, 0x16, 0x6e, 0x05, 0x6c, 0x21, - 0x85, 0xc9, 0x09, 0xff, 0x7b, 0x6e, 0xaa, 0x72, 0x5b, 0xbf, 0x2a, 0x37, 0x33, 0xf4, 0x54, 0x03, - 0x85, 0x63, 0xe6, 0x9f, 0xc4, 0xfc, 0x28, 0xfa, 0x3f, 0x3f, 0xd0, 0xe9, 0x60, 0x29, 0x75, 0x92, - 0xd9, 0xfb, 0x8d, 0x06, 0x8a, 0xc9, 0xe0, 0x49, 0x8b, 0xff, 0x4f, 0xfc, 0x75, 0xc5, 0x4f, 0xdd, - 0x44, 0xfc, 0x6d, 0xb0, 0x9c, 0xe9, 0xcc, 0xdf, 0x1c, 0x71, 0x46, 0x15, 0xeb, 0x5e, 0x95, 0xeb, - 0x90, 0x84, 0xaa, 0x01, 0xd9, 0x90, 0xa3, 0xab, 0xaa, 0xb5, 0x21, 0x55, 0xe7, 0x2b, 0x31, 0xd9, - 0x5b, 0x89, 0x07, 0x60, 0x9a, 0x42, 0x8e, 0x94, 0x9d, 0x7b, 0x62, 0xa9, 0xfd, 0xfd, 0x59, 0xf5, - 0xa5, 0xc4, 0x12, 0xf3, 0x1e, 0x9b, 0x98, 0x58, 0x21, 0xe4, 0x4d, 0xf3, 0x3b, 0xc8, 0x87, 0x6e, - 0xa7, 0x8e, 0xdc, 0x4f, 0x3e, 0xda, 0x01, 0xca, 0x71, 0x1d, 0xb9, 0xbf, 0xfd, 0xf4, 0xc9, 0x1d, - 0xcd, 0x96, 0x1c, 0x7b, 0x85, 0xd4, 0x6a, 0xed, 0x55, 0xf0, 0xca, 0x20, 0x27, 0x99, 0xe5, 0xbf, - 0x4c, 0xca, 0x63, 0x48, 0x76, 0x58, 0x25, 0x1e, 0x3e, 0x17, 0x67, 0x3e, 0xd1, 0xe6, 0x57, 0xc0, - 0x0c, 0xc7, 0x3c, 0x40, 0xea, 0xde, 0x25, 0x17, 0xfa, 0x26, 0x28, 0x79, 0x88, 0xb9, 0x14, 0xc7, - 0x72, 0x0b, 0x4a, 0xdc, 0xe4, 0x87, 0x7a, 0xcc, 0x4e, 0xf5, 0x9a, 0xcd, 0xda, 0xf7, 0xf4, 0x10, - 0xed, 0x7b, 0x66, 0xb4, 0xf6, 0x3d, 0x3b, 0x44, 0xfb, 0xbe, 0x35, 0xa8, 0x7d, 0x17, 0x06, 0xb5, - 0xef, 0xe2, 0xd0, 0x4d, 0xa1, 0xb6, 0x05, 0xaa, 0xd7, 0x94, 0x34, 0x2d, 0xfb, 0xee, 0x9f, 0x4b, - 0x60, 0xea, 0x98, 0xf9, 0xfa, 0x2f, 0x34, 0xb0, 0x7c, 0xf5, 0x45, 0xef, 0xab, 0x43, 0x9d, 0x32, - 0xfb, 0xbd, 0x4d, 0x19, 0xfb, 0x63, 0xa7, 0xa6, 0xda, 0xf4, 0xdf, 0x6b, 0xc0, 0x18, 0xf0, 0x16, - 0x76, 0x30, 0xec, 0x0c, 0xd7, 0x73, 0x18, 0x0f, 0x6e, 0xce, 0x31, 0x40, 0x6e, 0xcf, 0x7b, 0xd4, - 0x98, 0x72, 0xf3, 0x1c, 0xe3, 0xca, 0xed, 0xf7, 0x76, 0xa2, 0xff, 0x5c, 0x03, 0x4b, 0x57, 0x0e, - 0xf6, 0x5f, 0x19, 0x76, 0x82, 0xcb, 0x99, 0xc6, 0x37, 0xc6, 0xcd, 0xcc, 0x04, 0xfd, 0x54, 0x03, - 0x8b, 0x97, 0x8f, 0x0e, 0x6f, 0x8d, 0xca, 0xaa, 0x12, 0x8d, 0xaf, 0x8f, 0x99, 0x98, 0xa9, 0x79, - 0x5f, 0x03, 0x73, 0x3d, 0x6f, 0x6e, 0x5f, 0x1e, 0x96, 0x31, 0x9f, 0x65, 0xbc, 0x3d, 0x4e, 0x56, - 0x26, 0x22, 0x04, 0x33, 0xc9, 0x06, 0xbd, 0x33, 0x2c, 0x8d, 0x84, 0x1b, 0x6f, 0x8e, 0x04, 0xcf, - 0xa6, 0x8b, 0xc1, 0xac, 0xda, 0x30, 0xcd, 0x11, 0x08, 0x4e, 0x5a, 0xdc, 0xb8, 0x37, 0x1a, 0x3e, - 0x9b, 0xf1, 0x77, 0x1a, 0x58, 0xbf, 0x7e, 0x97, 0x1b, 0xba, 0x87, 0x5c, 0x4b, 0x61, 0x1c, 0xdd, - 0x98, 0x22, 0xd3, 0xfa, 0x2b, 0x0d, 0xac, 0xf4, 0xdd, 0x9e, 0xde, 0x1e, 0xf5, 0x59, 0xcb, 0x67, - 0x1b, 0xf5, 0x9b, 0x64, 0xa7, 0xe2, 0x8c, 0x99, 0x1f, 0x8b, 0xdd, 0xf7, 0xe0, 0xfb, 0x4f, 0x9f, - 0x57, 0xb4, 0x8f, 0x9f, 0x57, 0xb4, 0x7f, 0x3e, 0xaf, 0x68, 0x1f, 0xbc, 0xa8, 0x4c, 0x7c, 0xfc, - 0xa2, 0x32, 0xf1, 0xb7, 0x17, 0x95, 0x89, 0x1f, 0x7c, 0xcd, 0xc7, 0xbc, 0xd9, 0x6a, 0x98, 0x2e, - 0x09, 0xd5, 0x57, 0x4a, 0xab, 0x3b, 0xef, 0x4e, 0xf6, 0x91, 0xb1, 0xfd, 0xa6, 0xf5, 0x5e, 0xef, - 0x97, 0x46, 0xf9, 0x65, 0xa6, 0x31, 0x2b, 0x4f, 0xe3, 0x5f, 0xfa, 0x4f, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xcb, 0x72, 0xac, 0x84, 0xe5, 0x15, 0x00, 0x00, + 0xed, 0x1b, 0xda, 0x13, 0x12, 0x02, 0x2d, 0x37, 0xc4, 0x69, 0x0f, 0x08, 0x09, 0x09, 0xa4, 0x39, + 0xec, 0x89, 0x1b, 0xe2, 0x32, 0x07, 0x0e, 0xcb, 0x8a, 0x03, 0xe2, 0x30, 0xa0, 0x99, 0xc3, 0x72, + 0xe6, 0x2f, 0x40, 0x55, 0x2e, 0xbb, 0xdd, 0x49, 0xa7, 0xa7, 0xbb, 0x03, 0x07, 0x2e, 0xad, 0x76, + 0xbd, 0xef, 0x7d, 0xf5, 0x7d, 0xcf, 0xae, 0x57, 0x65, 0x83, 0xd7, 0x71, 0xc4, 0x11, 0x75, 0x9b, + 0x10, 0x47, 0x0e, 0x43, 0x6e, 0x8b, 0x62, 0xde, 0xb1, 0x5c, 0xb7, 0x6d, 0xc5, 0x94, 0xb4, 0xb1, + 0x87, 0xa8, 0xd5, 0xde, 0xb1, 0xf8, 0xfb, 0x66, 0x4c, 0x09, 0x27, 0xfa, 0xe7, 0xfb, 0xa0, 0x4d, + 0xd7, 0x6d, 0x9b, 0x29, 0xda, 0x6c, 0xef, 0x18, 0xcb, 0x30, 0xc4, 0x11, 0xb1, 0xe4, 0x6f, 0x92, + 0x67, 0xac, 0xfb, 0x84, 0xf8, 0x01, 0xb2, 0x60, 0x8c, 0x2d, 0x18, 0x45, 0x84, 0x43, 0x8e, 0x49, + 0xc4, 0x54, 0xb4, 0xaa, 0xa2, 0xf2, 0xaa, 0xd1, 0x3a, 0xb7, 0x38, 0x0e, 0x11, 0xe3, 0x30, 0x8c, + 0x15, 0xa0, 0x72, 0x19, 0xe0, 0xb5, 0xa8, 0x64, 0x50, 0xf1, 0xb5, 0xcb, 0x71, 0x18, 0x75, 0x54, + 0x68, 0xc5, 0x27, 0x3e, 0x91, 0x7f, 0x2d, 0xf1, 0x2f, 0x4d, 0x70, 0x09, 0x0b, 0x09, 0x73, 0x92, + 0x40, 0x72, 0xa1, 0x42, 0xab, 0xc9, 0x95, 0x15, 0x32, 0x5f, 0x58, 0x0f, 0x99, 0x9f, 0xaa, 0xc4, + 0x0d, 0xd7, 0x72, 0x09, 0x45, 0x96, 0x1b, 0x60, 0x14, 0x71, 0x11, 0x4d, 0xfe, 0x29, 0xc0, 0xee, + 0x30, 0xa5, 0xcc, 0x0a, 0x95, 0xe4, 0x58, 0x82, 0x34, 0xc0, 0x7e, 0x93, 0x27, 0x54, 0xcc, 0xe2, + 0x28, 0xf2, 0x10, 0x0d, 0x71, 0x32, 0x41, 0xf7, 0x2a, 0x55, 0x91, 0x8b, 0xf3, 0x4e, 0x8c, 0x98, + 0x85, 0x04, 0x5f, 0xe4, 0xa2, 0x04, 0x50, 0xfb, 0xab, 0x06, 0x56, 0x8e, 0x99, 0xbf, 0xcf, 0x18, + 0xf6, 0xa3, 0x43, 0x12, 0xb1, 0x56, 0x88, 0xe8, 0xb7, 0x51, 0x47, 0x5f, 0x03, 0x85, 0x44, 0x1b, + 0xf6, 0xca, 0xda, 0x86, 0xb6, 0x55, 0xb4, 0x6f, 0xc9, 0xeb, 0x23, 0x4f, 0x7f, 0x1b, 0xcc, 0xa7, + 0xba, 0x1c, 0xe8, 0x79, 0xb4, 0x3c, 0x29, 0xe2, 0x07, 0xfa, 0xbf, 0x9f, 0x56, 0x17, 0x3a, 0x30, + 0x0c, 0xf6, 0x6a, 0x62, 0x14, 0x31, 0x56, 0xb3, 0xe7, 0x52, 0xe0, 0xbe, 0xe7, 0x51, 0x7d, 0x13, + 0xcc, 0xb9, 0x6a, 0x0a, 0xe7, 0x11, 0xea, 0x94, 0xa7, 0x24, 0x6f, 0xc9, 0xcd, 0x4d, 0xfb, 0x06, + 0x98, 0x15, 0x4a, 0x10, 0x2d, 0x4f, 0x4b, 0xd2, 0xf2, 0xa7, 0x1f, 0x6f, 0xaf, 0xa8, 0x8a, 0xef, + 0x27, 0xac, 0x0f, 0x39, 0xc5, 0x91, 0x6f, 0x2b, 0xdc, 0xde, 0xed, 0x9f, 0x7c, 0x54, 0x9d, 0xf8, + 0xd7, 0x47, 0xd5, 0x89, 0x0f, 0x3e, 0x7b, 0x7c, 0x57, 0x0d, 0xd6, 0x2a, 0x60, 0xbd, 0x9f, 0x2b, + 0x1b, 0xb1, 0x98, 0x44, 0x0c, 0xd5, 0xfe, 0xa8, 0x81, 0x97, 0x8f, 0x99, 0xff, 0xb0, 0xd5, 0x08, + 0x31, 0x4f, 0x01, 0xc7, 0x98, 0x35, 0x50, 0x13, 0xb6, 0x31, 0x69, 0x51, 0xfd, 0x2d, 0x50, 0x64, + 0x32, 0xca, 0x11, 0x4d, 0x0a, 0x30, 0x40, 0x4b, 0x17, 0xaa, 0x9f, 0x82, 0xb9, 0x30, 0xc7, 0x23, + 0x6b, 0x53, 0xda, 0x7d, 0xdd, 0xc4, 0x0d, 0xd7, 0xcc, 0xdf, 0x39, 0x33, 0x77, 0xaf, 0xda, 0x3b, + 0x66, 0x7e, 0x6e, 0xbb, 0x87, 0x61, 0xef, 0x73, 0x79, 0x83, 0xdd, 0x99, 0x6a, 0xaf, 0x81, 0x2f, + 0x0c, 0xb4, 0x90, 0x99, 0x7d, 0x3c, 0xd9, 0xc7, 0x6c, 0x9d, 0xb4, 0x1a, 0x01, 0x7a, 0x8f, 0x70, + 0x1c, 0xf9, 0x63, 0x9b, 0x75, 0xc0, 0xaa, 0xd7, 0x8a, 0x03, 0xec, 0x42, 0x8e, 0x9c, 0x36, 0xe1, + 0xc8, 0x49, 0x1f, 0x2f, 0xe5, 0xfb, 0xb5, 0xbc, 0x4d, 0xf9, 0x00, 0x9a, 0xf5, 0x34, 0xe1, 0x3d, + 0xc2, 0xd1, 0x3d, 0x05, 0xb7, 0xef, 0x78, 0xfd, 0x86, 0xf5, 0x1f, 0x81, 0x55, 0x1c, 0x9d, 0x53, + 0xe8, 0x8a, 0xe5, 0xeb, 0x34, 0x02, 0xe2, 0x3e, 0x72, 0x9a, 0x08, 0x7a, 0x88, 0xca, 0x87, 0xa7, + 0xb4, 0xfb, 0xea, 0x8b, 0x0a, 0x7b, 0x5f, 0xa2, 0xed, 0x3b, 0x5d, 0x9a, 0x03, 0xc1, 0x92, 0x0c, + 0x8f, 0x54, 0xdb, 0x7c, 0xc5, 0xb2, 0xda, 0xfe, 0x5a, 0x03, 0x8b, 0xc7, 0xcc, 0xff, 0x5e, 0xec, + 0x41, 0x8e, 0x4e, 0x21, 0x85, 0x21, 0x13, 0xd5, 0x84, 0x2d, 0xde, 0x24, 0x62, 0x45, 0xbf, 0xb8, + 0x9a, 0x19, 0x54, 0x3f, 0x02, 0xb3, 0xb1, 0x64, 0x50, 0xc5, 0xfb, 0xa2, 0x39, 0x44, 0xff, 0x34, + 0x93, 0x49, 0x0f, 0xa6, 0x9f, 0x3c, 0xad, 0x4e, 0xd8, 0x8a, 0x60, 0x6f, 0x41, 0xfa, 0xc9, 0xa8, + 0x6b, 0x6b, 0x60, 0xf5, 0x92, 0xca, 0xcc, 0xc1, 0xcf, 0x0a, 0xe0, 0xf6, 0x31, 0xf3, 0x53, 0x97, + 0xfb, 0x9e, 0x87, 0x45, 0x95, 0x06, 0x35, 0x80, 0x6f, 0x81, 0x05, 0x1c, 0x61, 0x8e, 0x61, 0xe0, + 0x34, 0x91, 0x28, 0xbd, 0x12, 0x6c, 0xc8, 0x9b, 0x21, 0x9a, 0x9e, 0xa9, 0x5a, 0x9d, 0xbc, 0x01, + 0x02, 0xa1, 0xf4, 0xcd, 0xab, 0xbc, 0x64, 0x50, 0x34, 0x04, 0x1f, 0x45, 0x88, 0x61, 0xe6, 0x34, + 0x21, 0x6b, 0xca, 0x7b, 0x3a, 0x67, 0x97, 0xd4, 0xd8, 0x7d, 0xc8, 0x9a, 0x7a, 0x15, 0x94, 0x1a, + 0x38, 0x82, 0xb4, 0x93, 0x20, 0xa6, 0x25, 0x02, 0x24, 0x43, 0x12, 0x70, 0x08, 0x00, 0x8b, 0xe1, + 0x45, 0xe4, 0x88, 0x6d, 0xa0, 0x3c, 0xa3, 0x84, 0x24, 0x2d, 0xde, 0x4c, 0x5b, 0xbc, 0x79, 0x96, + 0xee, 0x11, 0x07, 0x05, 0x21, 0xe4, 0xc3, 0x7f, 0x54, 0x35, 0xbb, 0x28, 0xf3, 0x44, 0x44, 0x7f, + 0x00, 0x96, 0x5a, 0x51, 0x83, 0x44, 0x1e, 0x8e, 0x7c, 0x27, 0x46, 0x14, 0x13, 0xaf, 0x3c, 0x2b, + 0xa9, 0xd6, 0xae, 0x50, 0xd5, 0xd5, 0x6e, 0x92, 0x30, 0xfd, 0x52, 0x30, 0x2d, 0x66, 0xc9, 0xa7, + 0x32, 0x57, 0xff, 0x2e, 0xd0, 0x5d, 0xb7, 0x2d, 0x25, 0x91, 0x16, 0x4f, 0x19, 0x6f, 0x0d, 0xcf, + 0xb8, 0xe4, 0xba, 0xed, 0xb3, 0x24, 0x5b, 0x51, 0xfe, 0x10, 0xac, 0x72, 0x0a, 0x23, 0x76, 0x8e, + 0xe8, 0x65, 0xde, 0xc2, 0xf0, 0xbc, 0x77, 0x52, 0x8e, 0x5e, 0xf2, 0xfb, 0x60, 0x23, 0xeb, 0xcc, + 0x14, 0x79, 0x98, 0x71, 0x8a, 0x1b, 0x2d, 0xb9, 0xe8, 0xd2, 0x65, 0x53, 0x2e, 0xca, 0x87, 0xa0, + 0x92, 0xe2, 0xec, 0x1e, 0xd8, 0x37, 0x15, 0x4a, 0x3f, 0x01, 0xaf, 0xc8, 0x65, 0xca, 0x84, 0x38, + 0xa7, 0x87, 0x49, 0x4e, 0x1d, 0x62, 0xc6, 0x04, 0x1b, 0xd8, 0xd0, 0xb6, 0xa6, 0xec, 0xcd, 0x04, + 0x7b, 0x8a, 0x68, 0x3d, 0x87, 0x3c, 0xcb, 0x01, 0xf5, 0x6d, 0xa0, 0x37, 0x31, 0xe3, 0x84, 0x62, + 0x17, 0x06, 0x0e, 0x8a, 0x38, 0xc5, 0x88, 0x95, 0x4b, 0x32, 0x7d, 0xb9, 0x1b, 0xb9, 0x97, 0x04, + 0xf4, 0x77, 0xc1, 0xe6, 0xb5, 0x93, 0x3a, 0x6e, 0x13, 0x46, 0x11, 0x0a, 0xca, 0x73, 0xd2, 0x4a, + 0xd5, 0xbb, 0x66, 0xce, 0xc3, 0x04, 0xa6, 0xdf, 0x06, 0x33, 0x9c, 0xc4, 0xce, 0x83, 0xf2, 0xfc, + 0x86, 0xb6, 0x35, 0x6f, 0x4f, 0x73, 0x12, 0x3f, 0xd0, 0xdf, 0x00, 0x2b, 0x6d, 0x18, 0x60, 0x0f, + 0x72, 0x42, 0x99, 0x13, 0x93, 0x0b, 0x44, 0x1d, 0x17, 0xc6, 0xe5, 0x05, 0x89, 0xd1, 0xbb, 0xb1, + 0x53, 0x11, 0x3a, 0x84, 0xb1, 0x7e, 0x17, 0x2c, 0x67, 0xa3, 0x0e, 0x43, 0x5c, 0xc2, 0x17, 0x25, + 0x7c, 0x31, 0x0b, 0x3c, 0x44, 0x5c, 0x60, 0xd7, 0x41, 0x11, 0x06, 0x01, 0xb9, 0x08, 0x30, 0xe3, + 0xe5, 0xa5, 0x8d, 0xa9, 0xad, 0xa2, 0xdd, 0x1d, 0xd0, 0x0d, 0x50, 0xf0, 0x50, 0xd4, 0x91, 0xc1, + 0x65, 0x19, 0xcc, 0xae, 0x7b, 0xbb, 0x8e, 0x3e, 0x74, 0xd7, 0xb9, 0xd2, 0x2a, 0x5e, 0x06, 0x2f, + 0xf5, 0x69, 0x07, 0x59, 0xbb, 0xf8, 0x83, 0x06, 0xf4, 0x5c, 0xdc, 0x46, 0x21, 0x69, 0xc3, 0x60, + 0x50, 0xb7, 0xd8, 0x07, 0x45, 0x26, 0xca, 0x28, 0xd7, 0xe7, 0xe4, 0x08, 0xeb, 0xb3, 0x20, 0xd2, + 0xe4, 0xf2, 0xec, 0xf1, 0x36, 0x35, 0xbe, 0xb7, 0x75, 0x60, 0x5c, 0xd5, 0x9e, 0x59, 0xfb, 0xbd, + 0x06, 0xee, 0x88, 0x70, 0x13, 0x46, 0x3e, 0xb2, 0xd1, 0x05, 0xa4, 0x5e, 0x1d, 0x45, 0x24, 0x64, + 0x7a, 0x0d, 0xcc, 0x7b, 0xf2, 0x9f, 0xc3, 0x89, 0x38, 0xf2, 0x94, 0x35, 0x59, 0xfc, 0x52, 0x32, + 0x78, 0x46, 0xf6, 0x3d, 0x4f, 0xdf, 0x02, 0x4b, 0x5d, 0x0c, 0x15, 0xd4, 0xc2, 0xad, 0x80, 0x2d, + 0xa4, 0x30, 0x39, 0xe1, 0x7f, 0xcf, 0x4d, 0x55, 0x6e, 0xeb, 0x57, 0xe5, 0x66, 0x86, 0x9e, 0x68, + 0xa0, 0x70, 0xcc, 0xfc, 0x93, 0x98, 0x1f, 0x45, 0xff, 0xe7, 0x07, 0x3a, 0x1d, 0x2c, 0xa5, 0x4e, + 0x32, 0x7b, 0xbf, 0xd1, 0x40, 0x31, 0x19, 0x3c, 0x69, 0xf1, 0xff, 0x89, 0xbf, 0xae, 0xf8, 0xa9, + 0x9b, 0x88, 0xbf, 0x0d, 0x96, 0x33, 0x9d, 0x99, 0xfa, 0x3f, 0x69, 0xf2, 0x8c, 0x2a, 0xd6, 0xbd, + 0x2a, 0xd7, 0x21, 0x09, 0x55, 0x03, 0xb2, 0x21, 0x47, 0x57, 0x55, 0x6b, 0x43, 0xaa, 0xce, 0x57, + 0x62, 0xb2, 0xb7, 0x12, 0xf7, 0xc0, 0x34, 0x85, 0x1c, 0x29, 0x3b, 0x3b, 0x62, 0xa9, 0xfd, 0xfd, + 0x69, 0xf5, 0xa5, 0xc4, 0x12, 0xf3, 0x1e, 0x99, 0x98, 0x58, 0x21, 0xe4, 0x4d, 0xf3, 0x3b, 0xc8, + 0x87, 0x6e, 0xa7, 0x8e, 0xdc, 0x4f, 0x3f, 0xde, 0x06, 0xca, 0x71, 0x1d, 0xb9, 0xb6, 0x4c, 0xdf, + 0x2b, 0xa4, 0x2e, 0x6b, 0xaf, 0x82, 0x57, 0x06, 0x99, 0xc8, 0xdc, 0xfe, 0x65, 0x52, 0x9e, 0x40, + 0xb2, 0x73, 0x2a, 0xf1, 0xf0, 0xb9, 0x38, 0xee, 0x89, 0x0e, 0xbf, 0x02, 0x66, 0x38, 0xe6, 0x01, + 0x52, 0xb7, 0x2d, 0xb9, 0xd0, 0x37, 0x40, 0xc9, 0x43, 0xcc, 0xa5, 0x38, 0x96, 0xbb, 0x4f, 0x62, + 0x24, 0x3f, 0xd4, 0xe3, 0x73, 0xaa, 0xd7, 0x67, 0xd6, 0xb9, 0xa7, 0x87, 0xe8, 0xdc, 0x33, 0xa3, + 0x75, 0xee, 0xd9, 0x21, 0x3a, 0xf7, 0xad, 0x41, 0x9d, 0xbb, 0x30, 0xa8, 0x73, 0x17, 0x87, 0xee, + 0x07, 0xb5, 0x4d, 0x50, 0xbd, 0xa6, 0xa4, 0x69, 0xd9, 0x77, 0xff, 0x5c, 0x02, 0x53, 0xc7, 0xcc, + 0xd7, 0x7f, 0xa1, 0x81, 0xe5, 0xab, 0xef, 0x78, 0x5f, 0x1d, 0xea, 0x80, 0xd9, 0xef, 0x45, 0xca, + 0xd8, 0x1f, 0x3b, 0x35, 0xd5, 0xa6, 0xff, 0x4e, 0x03, 0xc6, 0x80, 0x17, 0xb0, 0x83, 0x61, 0x67, + 0xb8, 0x9e, 0xc3, 0x78, 0xf7, 0xe6, 0x1c, 0x03, 0xe4, 0xf6, 0xbc, 0x42, 0x8d, 0x29, 0x37, 0xcf, + 0x31, 0xae, 0xdc, 0x7e, 0x2f, 0x26, 0xfa, 0xcf, 0x35, 0xb0, 0x74, 0xe5, 0x4c, 0xff, 0x95, 0x61, + 0x27, 0xb8, 0x9c, 0x69, 0x7c, 0x63, 0xdc, 0xcc, 0x4c, 0xd0, 0x4f, 0x35, 0xb0, 0x78, 0xf9, 0xd4, + 0xf0, 0xf6, 0xa8, 0xac, 0x2a, 0xd1, 0xf8, 0xfa, 0x98, 0x89, 0x99, 0x9a, 0x0f, 0x34, 0x30, 0xd7, + 0xf3, 0xd2, 0xf6, 0xe5, 0x61, 0x19, 0xf3, 0x59, 0xc6, 0x3b, 0xe3, 0x64, 0x65, 0x22, 0x42, 0x30, + 0x93, 0xec, 0xcd, 0xdb, 0xc3, 0xd2, 0x48, 0xb8, 0xf1, 0xe6, 0x48, 0xf0, 0x6c, 0xba, 0x18, 0xcc, + 0xaa, 0xbd, 0xd2, 0x1c, 0x81, 0xe0, 0xa4, 0xc5, 0x8d, 0xb7, 0x46, 0xc3, 0x67, 0x33, 0xfe, 0x56, + 0x03, 0x6b, 0xd7, 0x6f, 0x70, 0x43, 0xf7, 0x90, 0x6b, 0x29, 0x8c, 0xa3, 0x1b, 0x53, 0x64, 0x5a, + 0x7f, 0xa5, 0x81, 0x95, 0xbe, 0xdb, 0xd3, 0x3b, 0xa3, 0x3e, 0x6b, 0xf9, 0x6c, 0xa3, 0x7e, 0x93, + 0xec, 0x54, 0x9c, 0x31, 0xf3, 0xe3, 0xcf, 0x1e, 0xdf, 0xd5, 0x0e, 0xbe, 0xff, 0xe4, 0x59, 0x45, + 0xfb, 0xe4, 0x59, 0x45, 0xfb, 0xe7, 0xb3, 0x8a, 0xf6, 0xe1, 0xf3, 0xca, 0xc4, 0x27, 0xcf, 0x2b, + 0x13, 0x7f, 0x7b, 0x5e, 0x99, 0xf8, 0xc1, 0xd7, 0x7c, 0xcc, 0x9b, 0xad, 0x86, 0xe9, 0x92, 0x50, + 0x7d, 0xa0, 0xb4, 0xba, 0xf3, 0x6e, 0x67, 0xdf, 0x17, 0xdb, 0x6f, 0x5a, 0xef, 0xf7, 0x7e, 0x64, + 0x94, 0x1f, 0x65, 0x1a, 0xb3, 0xf2, 0x20, 0xfe, 0xa5, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x39, + 0xec, 0x0a, 0x75, 0xe0, 0x15, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/ccv/types/params.go b/x/ccv/types/params.go index 72a95ae7dd..475389d7df 100644 --- a/x/ccv/types/params.go +++ b/x/ccv/types/params.go @@ -27,6 +27,9 @@ const ( // decimal number. For example "0.75" would represent 75%. DefaultConsumerRedistributeFrac = "0.75" + // By default, the bottom 5% of the validator set can opt out of validating consumer chains + DefaultSoftOptOutThreshold = "0.05" + // Default number of historical info entries to persist in store. // We use the same default as the staking module, but use a signed integer // so that negative values can be caught during parameter validation in a readable way, @@ -38,9 +41,6 @@ const ( // the staking module default. DefaultConsumerUnbondingPeriod = stakingtypes.DefaultUnbondingTime - 7*24*time.Hour - // By default, the bottom 5% of the validator set can opt out of validating consumer chains - DefaultSoftOptOutThreshold = "0.05" - // Default retry delay period is 1 hour. DefaultRetryDelayPeriod = time.Hour ) @@ -149,9 +149,6 @@ func (p ConsumerParams) Validate() error { if err := ValidateDuration(p.UnbondingPeriod); err != nil { return err } - if err := ValidateSoftOptOutThreshold(p.SoftOptOutThreshold); err != nil { - return err - } if err := ValidateDenoms(p.RewardDenoms); err != nil { return err } @@ -184,8 +181,6 @@ func (p *ConsumerParams) ParamSetPairs() paramtypes.ParamSetPairs { p.HistoricalEntries, ValidatePositiveInt64), paramtypes.NewParamSetPair(KeyConsumerUnbondingPeriod, p.UnbondingPeriod, ValidateDuration), - paramtypes.NewParamSetPair(KeySoftOptOutThreshold, - p.SoftOptOutThreshold, ValidateSoftOptOutThreshold), paramtypes.NewParamSetPair(KeyRewardDenoms, p.RewardDenoms, ValidateDenoms), paramtypes.NewParamSetPair(KeyProviderRewardDenoms, diff --git a/x/ccv/types/shared_consumer.pb.go b/x/ccv/types/shared_consumer.pb.go index 425129c56c..92d0d82e6a 100644 --- a/x/ccv/types/shared_consumer.pb.go +++ b/x/ccv/types/shared_consumer.pb.go @@ -65,11 +65,8 @@ type ConsumerParams struct { // Unbonding period for the consumer, // which should be smaller than that of the provider in general. UnbondingPeriod time.Duration `protobuf:"bytes,9,opt,name=unbonding_period,json=unbondingPeriod,proto3,stdduration" json:"unbonding_period"` - // The threshold for the percentage of validators at the bottom of the set who - // can opt out of running the consumer chain without being punished. For - // example, a value of 0.05 means that the validators in the bottom 5% of the - // set can opt out - SoftOptOutThreshold string `protobuf:"bytes,10,opt,name=soft_opt_out_threshold,json=softOptOutThreshold,proto3" json:"soft_opt_out_threshold,omitempty"` + // !!! DEPRECATED !!! soft_opt_out_threshold is deprecated. see docs/docs/adrs/adr-015-partial-set-security.md + SoftOptOutThreshold string `protobuf:"bytes,10,opt,name=soft_opt_out_threshold,json=softOptOutThreshold,proto3" json:"soft_opt_out_threshold,omitempty"` // Deprecated: Do not use. // Reward denoms. These are the denominations which are allowed to be sent to // the provider as rewards. RewardDenoms []string `protobuf:"bytes,11,rep,name=reward_denoms,json=rewardDenoms,proto3" json:"reward_denoms,omitempty"` @@ -176,6 +173,7 @@ func (m *ConsumerParams) GetUnbondingPeriod() time.Duration { return 0 } +// Deprecated: Do not use. func (m *ConsumerParams) GetSoftOptOutThreshold() string { if m != nil { return m.SoftOptOutThreshold @@ -343,58 +341,59 @@ func init() { } var fileDescriptor_d0a8be0efc64dfbc = []byte{ - // 812 bytes of a gzipped FileDescriptorProto + // 817 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x41, 0x73, 0xdc, 0x34, - 0x14, 0x8e, 0xbb, 0x25, 0xdd, 0x68, 0x93, 0xa6, 0x88, 0x50, 0x4c, 0x3a, 0xb3, 0x71, 0x03, 0x87, - 0x1d, 0x98, 0xda, 0x24, 0x2d, 0x17, 0x6e, 0x24, 0xa1, 0x94, 0x1e, 0x92, 0xad, 0x13, 0xca, 0x0c, - 0x1c, 0x34, 0xb2, 0xf4, 0x76, 0xad, 0xc1, 0x96, 0x3c, 0x92, 0xec, 0x90, 0x5f, 0xc0, 0x95, 0x23, - 0x3f, 0xa9, 0xdc, 0x7a, 0xe4, 0x44, 0x99, 0xe4, 0x8f, 0x30, 0x96, 0xed, 0x8d, 0x97, 0x21, 0x50, - 0x6e, 0x7a, 0x7a, 0xdf, 0xf7, 0xd9, 0xdf, 0x93, 0xde, 0x13, 0xfa, 0x4c, 0x48, 0x0b, 0x9a, 0xa5, - 0x54, 0x48, 0x62, 0x80, 0x95, 0x5a, 0xd8, 0x8b, 0x88, 0xb1, 0x2a, 0xaa, 0xf6, 0x22, 0x93, 0x52, - 0x0d, 0x9c, 0x30, 0x25, 0x4d, 0x99, 0x83, 0x0e, 0x0b, 0xad, 0xac, 0xc2, 0xdb, 0xff, 0xc0, 0x08, - 0x19, 0xab, 0xc2, 0x6a, 0x6f, 0xfb, 0x81, 0x05, 0xc9, 0x41, 0xe7, 0x42, 0xda, 0x88, 0x26, 0x4c, - 0x44, 0xf6, 0xa2, 0x00, 0xd3, 0x10, 0xb7, 0x23, 0x91, 0xb0, 0x28, 0x13, 0xf3, 0xd4, 0xb2, 0x4c, - 0x80, 0xb4, 0x26, 0xea, 0xa1, 0xab, 0xbd, 0x5e, 0xd4, 0x12, 0xc6, 0x73, 0xa5, 0xe6, 0x19, 0x44, - 0x2e, 0x4a, 0xca, 0x59, 0xc4, 0x4b, 0x4d, 0xad, 0x50, 0xb2, 0xcd, 0x6f, 0xcd, 0xd5, 0x5c, 0xb9, - 0x65, 0x54, 0xaf, 0x9a, 0xdd, 0xdd, 0x37, 0xab, 0xe8, 0xee, 0x61, 0xfb, 0xcb, 0x53, 0xaa, 0x69, - 0x6e, 0xb0, 0x8f, 0xee, 0x80, 0xa4, 0x49, 0x06, 0xdc, 0xf7, 0x02, 0x6f, 0x32, 0x8c, 0xbb, 0x10, - 0x9f, 0xa0, 0x8f, 0x93, 0x4c, 0xb1, 0x1f, 0x0d, 0x29, 0x40, 0x13, 0x2e, 0x8c, 0xd5, 0x22, 0x29, - 0xeb, 0x6f, 0x10, 0xab, 0xa9, 0x34, 0xb9, 0x30, 0x46, 0x28, 0xe9, 0xdf, 0x0a, 0xbc, 0xc9, 0x20, - 0x7e, 0xd8, 0x60, 0xa7, 0xa0, 0x8f, 0x7a, 0xc8, 0xb3, 0x1e, 0x10, 0x3f, 0x47, 0x0f, 0x6f, 0x54, - 0x21, 0x2c, 0xa5, 0x52, 0x42, 0xe6, 0x0f, 0x02, 0x6f, 0xb2, 0x16, 0xef, 0xf0, 0x1b, 0x44, 0x0e, - 0x1b, 0x18, 0xfe, 0x02, 0x6d, 0x17, 0x5a, 0x55, 0x82, 0x83, 0x26, 0x33, 0x00, 0x52, 0x28, 0x95, - 0x11, 0xca, 0xb9, 0x26, 0xc6, 0x6a, 0xff, 0xb6, 0x13, 0xb9, 0xdf, 0x21, 0x9e, 0x02, 0x4c, 0x95, - 0xca, 0xbe, 0xe4, 0x5c, 0x9f, 0x5a, 0x8d, 0x5f, 0x20, 0xcc, 0x58, 0x45, 0xac, 0xc8, 0x41, 0x95, - 0xb6, 0x76, 0x27, 0x14, 0xf7, 0xdf, 0x09, 0xbc, 0xc9, 0x68, 0xff, 0xc3, 0xb0, 0x29, 0x6c, 0xd8, - 0x15, 0x36, 0x3c, 0x6a, 0x0b, 0x7b, 0x30, 0x7c, 0xf5, 0xc7, 0xce, 0xca, 0xaf, 0x6f, 0x76, 0xbc, - 0xf8, 0x1e, 0x63, 0xd5, 0x59, 0xc3, 0x9e, 0x3a, 0x32, 0xfe, 0x01, 0x7d, 0xe0, 0xdc, 0xcc, 0x40, - 0xff, 0x5d, 0x77, 0xf5, 0xed, 0x75, 0xdf, 0xef, 0x34, 0x96, 0xc5, 0x9f, 0xa1, 0xa0, 0xbb, 0x67, - 0x44, 0xc3, 0x52, 0x09, 0x67, 0x9a, 0xb2, 0x7a, 0xe1, 0xdf, 0x71, 0x8e, 0xc7, 0x1d, 0x2e, 0x5e, - 0x82, 0x3d, 0x6d, 0x51, 0xf8, 0x11, 0xc2, 0xa9, 0x30, 0x56, 0x69, 0xc1, 0x68, 0x46, 0x40, 0x5a, - 0x2d, 0xc0, 0xf8, 0x43, 0x77, 0x80, 0xef, 0x5e, 0x67, 0xbe, 0x6a, 0x12, 0xf8, 0x18, 0xdd, 0x2b, - 0x65, 0xa2, 0x24, 0x17, 0x72, 0xde, 0xd9, 0x59, 0x7b, 0x7b, 0x3b, 0x9b, 0x0b, 0x72, 0x6b, 0xe4, - 0x31, 0xba, 0x6f, 0xd4, 0xcc, 0x12, 0x55, 0x58, 0x52, 0x57, 0xc8, 0xa6, 0x1a, 0x4c, 0xaa, 0x32, - 0xee, 0x23, 0xf7, 0xfb, 0xef, 0xd5, 0xd9, 0x93, 0xc2, 0x9e, 0x94, 0xf6, 0xac, 0x4b, 0xe1, 0x8f, - 0xd0, 0x86, 0x86, 0x73, 0xaa, 0x39, 0xe1, 0x20, 0x55, 0x6e, 0xfc, 0x51, 0x30, 0x98, 0xac, 0xc5, - 0xeb, 0xcd, 0xe6, 0x91, 0xdb, 0xc3, 0x4f, 0xd0, 0xe2, 0xb0, 0xc9, 0x32, 0x7a, 0xdd, 0xa1, 0xb7, - 0xba, 0x6c, 0xdc, 0x67, 0xbd, 0x40, 0x58, 0x83, 0xd5, 0x17, 0x84, 0x43, 0x46, 0x2f, 0x3a, 0x87, - 0x1b, 0xff, 0xe3, 0x22, 0x38, 0xfa, 0x51, 0xcd, 0x6e, 0x2c, 0xee, 0xfe, 0xe6, 0xa1, 0xad, 0xae, - 0xc3, 0xbe, 0x06, 0x09, 0x46, 0x98, 0x53, 0x4b, 0x2d, 0xe0, 0x67, 0x68, 0xb5, 0x70, 0x1d, 0xe7, - 0xda, 0x6c, 0xb4, 0xff, 0x49, 0x78, 0xf3, 0xac, 0x08, 0x97, 0x7b, 0xf4, 0xe0, 0x76, 0xfd, 0xc1, - 0xb8, 0xe5, 0xe3, 0xe7, 0x68, 0xd8, 0xb9, 0x71, 0xbd, 0x37, 0xda, 0x9f, 0xfc, 0x9b, 0xd6, 0xb4, - 0xc5, 0x7e, 0x23, 0x67, 0xaa, 0x55, 0x5a, 0xf0, 0xf1, 0x03, 0xb4, 0x26, 0xe1, 0x9c, 0x38, 0xa6, - 0x6b, 0xbd, 0x61, 0x3c, 0x94, 0x70, 0x7e, 0x58, 0xc7, 0xbb, 0x3f, 0xdf, 0x42, 0xeb, 0x7d, 0x36, - 0x3e, 0x46, 0xeb, 0xcd, 0x78, 0x22, 0xa6, 0xf6, 0xd4, 0x3a, 0xf9, 0x34, 0x14, 0x09, 0x0b, 0xfb, - 0xc3, 0x2b, 0xec, 0x8d, 0xab, 0xda, 0x8d, 0xdb, 0x75, 0x65, 0x88, 0x47, 0xec, 0x3a, 0xc0, 0xdf, - 0xa1, 0xcd, 0xfa, 0xc2, 0x82, 0x34, 0xa5, 0x69, 0x25, 0x1b, 0x43, 0xe1, 0x7f, 0x4a, 0x76, 0xb4, - 0x46, 0xf5, 0x2e, 0x5b, 0x8a, 0xf1, 0x31, 0xda, 0x14, 0x52, 0x58, 0x41, 0x33, 0x52, 0xd1, 0x8c, - 0x18, 0xb0, 0xfe, 0x20, 0x18, 0x4c, 0x46, 0xfb, 0x41, 0x5f, 0xa7, 0x9e, 0xc2, 0xe1, 0x4b, 0x9a, - 0x09, 0x4e, 0xad, 0xd2, 0xdf, 0x16, 0x9c, 0x5a, 0x68, 0x2b, 0xb4, 0xd1, 0xd2, 0x5f, 0xd2, 0xec, - 0x14, 0xec, 0xc1, 0xf1, 0xab, 0xcb, 0xb1, 0xf7, 0xfa, 0x72, 0xec, 0xfd, 0x79, 0x39, 0xf6, 0x7e, - 0xb9, 0x1a, 0xaf, 0xbc, 0xbe, 0x1a, 0xaf, 0xfc, 0x7e, 0x35, 0x5e, 0xf9, 0xfe, 0xc9, 0x5c, 0xd8, - 0xb4, 0x4c, 0x42, 0xa6, 0xf2, 0x88, 0x29, 0x93, 0x2b, 0x13, 0x5d, 0x9f, 0xc5, 0xa3, 0xc5, 0xab, - 0x51, 0x7d, 0x1e, 0xfd, 0xe4, 0x9e, 0x0e, 0x37, 0xf4, 0x93, 0x55, 0x77, 0xa9, 0x1e, 0xff, 0x15, - 0x00, 0x00, 0xff, 0xff, 0x9a, 0xb1, 0xf7, 0x25, 0x62, 0x06, 0x00, 0x00, + 0x14, 0x8e, 0xb3, 0x25, 0xdd, 0x68, 0x93, 0xa6, 0x88, 0x50, 0x4c, 0x3a, 0xb3, 0x71, 0x03, 0x87, + 0x1d, 0x98, 0xda, 0x24, 0x94, 0x61, 0x86, 0x1b, 0x49, 0x28, 0xa5, 0x87, 0x64, 0xeb, 0x84, 0x32, + 0x03, 0x07, 0x8d, 0x2c, 0xbd, 0x5d, 0x6b, 0xb0, 0x25, 0x8f, 0x24, 0x3b, 0xe4, 0x17, 0x70, 0xe5, + 0xc8, 0x4f, 0x2a, 0xb7, 0x1e, 0x39, 0x01, 0x93, 0xfc, 0x11, 0xc6, 0xb2, 0x9d, 0x78, 0x19, 0x02, + 0xe9, 0x4d, 0x4f, 0xef, 0xfb, 0x3e, 0xfb, 0x7b, 0xd2, 0x7b, 0x42, 0x9f, 0x08, 0x69, 0x41, 0xb3, + 0x94, 0x0a, 0x49, 0x0c, 0xb0, 0x52, 0x0b, 0x7b, 0x1e, 0x31, 0x56, 0x45, 0xd5, 0x6e, 0x64, 0x52, + 0xaa, 0x81, 0x13, 0xa6, 0xa4, 0x29, 0x73, 0xd0, 0x61, 0xa1, 0x95, 0x55, 0x78, 0xeb, 0x5f, 0x18, + 0x21, 0x63, 0x55, 0x58, 0xed, 0x6e, 0x3d, 0xb4, 0x20, 0x39, 0xe8, 0x5c, 0x48, 0x1b, 0xd1, 0x84, + 0x89, 0xc8, 0x9e, 0x17, 0x60, 0x1a, 0xe2, 0x56, 0x24, 0x12, 0x16, 0x65, 0x62, 0x9e, 0x5a, 0x96, + 0x09, 0x90, 0xd6, 0x44, 0x3d, 0x74, 0xb5, 0xdb, 0x8b, 0x5a, 0xc2, 0x78, 0xae, 0xd4, 0x3c, 0x83, + 0xc8, 0x45, 0x49, 0x39, 0x8b, 0x78, 0xa9, 0xa9, 0x15, 0x4a, 0xb6, 0xf9, 0xcd, 0xb9, 0x9a, 0x2b, + 0xb7, 0x8c, 0xea, 0x55, 0xb3, 0xbb, 0x73, 0xb9, 0x82, 0xee, 0x1d, 0xb4, 0xbf, 0x3c, 0xa5, 0x9a, + 0xe6, 0x06, 0xfb, 0xe8, 0x2e, 0x48, 0x9a, 0x64, 0xc0, 0x7d, 0x2f, 0xf0, 0x26, 0xc3, 0xb8, 0x0b, + 0xf1, 0x31, 0xfa, 0x30, 0xc9, 0x14, 0xfb, 0xd1, 0x90, 0x02, 0x34, 0xe1, 0xc2, 0x58, 0x2d, 0x92, + 0xb2, 0xfe, 0x06, 0xb1, 0x9a, 0x4a, 0x93, 0x0b, 0x63, 0x84, 0x92, 0xfe, 0x72, 0xe0, 0x4d, 0x06, + 0xf1, 0xa3, 0x06, 0x3b, 0x05, 0x7d, 0xd8, 0x43, 0x9e, 0xf6, 0x80, 0xf8, 0x39, 0x7a, 0x74, 0xa3, + 0x0a, 0x61, 0x29, 0x95, 0x12, 0x32, 0x7f, 0x10, 0x78, 0x93, 0xd5, 0x78, 0x9b, 0xdf, 0x20, 0x72, + 0xd0, 0xc0, 0xf0, 0x17, 0x68, 0xab, 0xd0, 0xaa, 0x12, 0x1c, 0x34, 0x99, 0x01, 0x90, 0x42, 0xa9, + 0x8c, 0x50, 0xce, 0x35, 0x31, 0x56, 0xfb, 0x77, 0x9c, 0xc8, 0x83, 0x0e, 0xf1, 0x14, 0x60, 0xaa, + 0x54, 0xf6, 0x25, 0xe7, 0xfa, 0xc4, 0x6a, 0xfc, 0x02, 0x61, 0xc6, 0x2a, 0x62, 0x45, 0x0e, 0xaa, + 0xb4, 0xb5, 0x3b, 0xa1, 0xb8, 0xff, 0x56, 0xe0, 0x4d, 0x46, 0x7b, 0xef, 0x87, 0x4d, 0x61, 0xc3, + 0xae, 0xb0, 0xe1, 0x61, 0x5b, 0xd8, 0xfd, 0xe1, 0xab, 0x3f, 0xb6, 0x97, 0x7e, 0xfd, 0x73, 0xdb, + 0x8b, 0xef, 0x33, 0x56, 0x9d, 0x36, 0xec, 0xa9, 0x23, 0xe3, 0x1f, 0xd0, 0x7b, 0xce, 0xcd, 0x0c, + 0xf4, 0x3f, 0x75, 0x57, 0x6e, 0xaf, 0xfb, 0x6e, 0xa7, 0xb1, 0x28, 0xfe, 0x0c, 0x05, 0xdd, 0x3d, + 0x23, 0x1a, 0x16, 0x4a, 0x38, 0xd3, 0x94, 0xd5, 0x0b, 0xff, 0xae, 0x73, 0x3c, 0xee, 0x70, 0xf1, + 0x02, 0xec, 0x69, 0x8b, 0xc2, 0x8f, 0x11, 0x4e, 0x85, 0xb1, 0x4a, 0x0b, 0x46, 0x33, 0x02, 0xd2, + 0x6a, 0x01, 0xc6, 0x1f, 0xba, 0x03, 0x7c, 0xfb, 0x3a, 0xf3, 0x55, 0x93, 0xc0, 0x47, 0xe8, 0x7e, + 0x29, 0x13, 0x25, 0xb9, 0x90, 0xf3, 0xce, 0xce, 0xea, 0xed, 0xed, 0x6c, 0x5c, 0x91, 0x5b, 0x23, + 0x9f, 0xa3, 0x07, 0x46, 0xcd, 0x2c, 0x51, 0x85, 0x25, 0x75, 0x85, 0x6c, 0xaa, 0xc1, 0xa4, 0x2a, + 0xe3, 0x3e, 0xaa, 0x7f, 0x7f, 0x7f, 0xd9, 0xf7, 0xe2, 0x77, 0x6a, 0xc4, 0x71, 0x61, 0x8f, 0x4b, + 0x7b, 0xda, 0xa5, 0xf1, 0x07, 0x68, 0x5d, 0xc3, 0x19, 0xd5, 0x9c, 0x70, 0x90, 0x2a, 0x37, 0xfe, + 0x28, 0x18, 0x4c, 0x56, 0xe3, 0xb5, 0x66, 0xf3, 0xd0, 0xed, 0xe1, 0x27, 0xe8, 0xea, 0xc0, 0xc9, + 0x22, 0x7a, 0xcd, 0xa1, 0x37, 0xbb, 0x6c, 0xdc, 0x67, 0xbd, 0x40, 0x58, 0x83, 0xd5, 0xe7, 0x84, + 0x43, 0x46, 0xcf, 0x3b, 0x97, 0xeb, 0x6f, 0x70, 0x19, 0x1c, 0xfd, 0xb0, 0x66, 0x37, 0x36, 0x77, + 0x7e, 0xf3, 0xd0, 0x66, 0xd7, 0x65, 0x5f, 0x83, 0x04, 0x23, 0xcc, 0x89, 0xa5, 0x16, 0xf0, 0x33, + 0xb4, 0x52, 0xb8, 0xae, 0x73, 0xad, 0x36, 0xda, 0xfb, 0x28, 0xbc, 0x79, 0x5e, 0x84, 0x8b, 0x7d, + 0xba, 0x7f, 0xa7, 0xfe, 0x60, 0xdc, 0xf2, 0xf1, 0x73, 0x34, 0xec, 0xdc, 0xb8, 0xfe, 0x1b, 0xed, + 0x4d, 0xfe, 0x4b, 0x6b, 0xda, 0x62, 0xbf, 0x91, 0x33, 0xd5, 0x2a, 0x5d, 0xf1, 0xf1, 0x43, 0xb4, + 0x2a, 0xe1, 0x8c, 0x38, 0xa6, 0x6b, 0xbf, 0x61, 0x3c, 0x94, 0x70, 0x76, 0x50, 0xc7, 0x3b, 0x3f, + 0x2f, 0xa3, 0xb5, 0x3e, 0x1b, 0x1f, 0xa1, 0xb5, 0x66, 0x44, 0x11, 0x53, 0x7b, 0x6a, 0x9d, 0x7c, + 0x1c, 0x8a, 0x84, 0x85, 0xfd, 0x01, 0x16, 0xf6, 0x46, 0x56, 0xed, 0xc6, 0xed, 0xba, 0x32, 0xc4, + 0x23, 0x76, 0x1d, 0xe0, 0xef, 0xd0, 0x46, 0x7d, 0x69, 0x41, 0x9a, 0xd2, 0xb4, 0x92, 0x8d, 0xa1, + 0xf0, 0x7f, 0x25, 0x3b, 0x5a, 0xa3, 0x7a, 0x8f, 0x2d, 0xc4, 0xf8, 0x08, 0x6d, 0x08, 0x29, 0xac, + 0xa0, 0x19, 0xa9, 0x68, 0x46, 0x0c, 0x58, 0x7f, 0x10, 0x0c, 0x26, 0xa3, 0xbd, 0xa0, 0xaf, 0x53, + 0x4f, 0xe2, 0xf0, 0x25, 0xcd, 0x04, 0xa7, 0x56, 0xe9, 0x6f, 0x0b, 0x4e, 0x2d, 0xb4, 0x15, 0x5a, + 0x6f, 0xe9, 0x2f, 0x69, 0x76, 0x02, 0x76, 0xff, 0xe8, 0xd5, 0xc5, 0xd8, 0x7b, 0x7d, 0x31, 0xf6, + 0xfe, 0xba, 0x18, 0x7b, 0xbf, 0x5c, 0x8e, 0x97, 0x5e, 0x5f, 0x8e, 0x97, 0x7e, 0xbf, 0x1c, 0x2f, + 0x7d, 0xff, 0x64, 0x2e, 0x6c, 0x5a, 0x26, 0x21, 0x53, 0x79, 0xc4, 0x94, 0xc9, 0x95, 0x89, 0xae, + 0xcf, 0xe2, 0xf1, 0xd5, 0xcb, 0x51, 0x7d, 0x16, 0xfd, 0xe4, 0x9e, 0x0f, 0x37, 0xf8, 0x93, 0x15, + 0x77, 0xa9, 0x3e, 0xfd, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x00, 0xe4, 0xb0, 0x69, 0x66, 0x06, 0x00, + 0x00, } func (m *ConsumerParams) Marshal() (dAtA []byte, err error) { From 644227bb1f33880a7586417fde9992ff1d47b680 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Thu, 4 Jul 2024 09:13:31 +0200 Subject: [PATCH 23/35] Revert "refactor!: deprecate soft opt-out (#1964)" This reverts commit 8674ef6527ebfd2c7fbd600055b6767584ab1659. --- .../1964-deprecate-soft-opt-out.md | 2 - .../features/1964-deprecate-soft-opt-out.md | 2 - .../1964-deprecate-soft-opt-out.md | 2 - app/consumer-democracy/app.go | 1 + app/consumer/app.go | 1 + app/consumer/genesis.go | 3 - app/consumer/genesis_test.go | 9 +- app/sovereign/app.go | 1 + docs/docs/adrs/adr-009-soft-opt-out.md | 5 +- docs/docs/adrs/intro.md | 2 +- docs/docs/features/proposals.md | 8 + .../ccv/consumer/v1/consumer.proto | 5 +- .../ccv/v1/shared_consumer.proto | 7 +- tests/e2e/actions.go | 14 +- tests/e2e/step_delegation.go | 115 +++++++- tests/e2e/steps.go | 16 +- tests/e2e/steps_active_set_changes.go | 6 + tests/e2e/steps_compatibility.go | 6 + tests/e2e/steps_consumer_misbehaviour.go | 28 +- tests/e2e/steps_double_sign.go | 12 +- tests/e2e/steps_downtime.go | 161 +++++++---- tests/e2e/steps_light_client_attack.go | 24 +- tests/e2e/steps_partial_set_security.go | 57 +++- tests/e2e/steps_sovereign_changeover.go | 1 + tests/e2e/steps_start_chains.go | 6 + .../e2e/tracehandler_testdata/changeover.json | 8 +- .../consumer-double-sign.json | 8 +- .../consumer-misbehaviour.json | 26 +- .../e2e/tracehandler_testdata/democracy.json | 8 +- .../democracyRewardsSteps.json | 8 +- .../e2e/tracehandler_testdata/happyPath.json | 265 +++++++++++++++--- .../multipleConsumers.json | 16 +- .../e2e/tracehandler_testdata/shorthappy.json | 84 +++--- .../tracehandler_testdata/slashThrottle.json | 8 +- tests/integration/soft_opt_out.go | 251 +++++++++++++++++ tests/mbt/driver/setup.go | 1 + testutil/integration/debug_test.go | 8 + testutil/integration/interfaces.go | 2 +- x/ccv/consumer/keeper/params.go | 9 + x/ccv/consumer/keeper/params_test.go | 3 +- x/ccv/consumer/keeper/soft_opt_out.go | 118 ++++++++ x/ccv/consumer/keeper/soft_opt_out_test.go | 120 ++++++++ x/ccv/consumer/keeper/validators.go | 12 + x/ccv/consumer/module.go | 3 + x/ccv/consumer/types/consumer.pb.go | 61 ++-- x/ccv/consumer/types/genesis_test.go | 3 + x/ccv/consumer/types/keys.go | 9 +- x/ccv/consumer/types/keys_test.go | 5 +- x/ccv/consumer/types/params_test.go | 36 ++- x/ccv/consumer/types/validator.go | 7 +- x/ccv/provider/keeper/grpc_query_test.go | 6 +- x/ccv/provider/keeper/proposal.go | 1 + x/ccv/provider/keeper/proposal_test.go | 5 +- x/ccv/provider/proposal_handler_test.go | 2 +- x/ccv/provider/types/proposal.go | 2 +- x/ccv/types/params.go | 39 ++- x/ccv/types/shared_consumer.pb.go | 113 ++++---- x/ccv/types/utils.go | 2 +- 58 files changed, 1330 insertions(+), 413 deletions(-) delete mode 100644 .changelog/unreleased/api-breaking/1964-deprecate-soft-opt-out.md delete mode 100644 .changelog/unreleased/features/1964-deprecate-soft-opt-out.md delete mode 100644 .changelog/unreleased/state-breaking/1964-deprecate-soft-opt-out.md create mode 100644 tests/integration/soft_opt_out.go create mode 100644 x/ccv/consumer/keeper/soft_opt_out.go create mode 100644 x/ccv/consumer/keeper/soft_opt_out_test.go diff --git a/.changelog/unreleased/api-breaking/1964-deprecate-soft-opt-out.md b/.changelog/unreleased/api-breaking/1964-deprecate-soft-opt-out.md deleted file mode 100644 index 73de583293..0000000000 --- a/.changelog/unreleased/api-breaking/1964-deprecate-soft-opt-out.md +++ /dev/null @@ -1,2 +0,0 @@ -- Remove soft opt-out feature. - ([\#1964](https://github.com/cosmos/interchain-security/pull/1964)) \ No newline at end of file diff --git a/.changelog/unreleased/features/1964-deprecate-soft-opt-out.md b/.changelog/unreleased/features/1964-deprecate-soft-opt-out.md deleted file mode 100644 index 73de583293..0000000000 --- a/.changelog/unreleased/features/1964-deprecate-soft-opt-out.md +++ /dev/null @@ -1,2 +0,0 @@ -- Remove soft opt-out feature. - ([\#1964](https://github.com/cosmos/interchain-security/pull/1964)) \ No newline at end of file diff --git a/.changelog/unreleased/state-breaking/1964-deprecate-soft-opt-out.md b/.changelog/unreleased/state-breaking/1964-deprecate-soft-opt-out.md deleted file mode 100644 index 73de583293..0000000000 --- a/.changelog/unreleased/state-breaking/1964-deprecate-soft-opt-out.md +++ /dev/null @@ -1,2 +0,0 @@ -- Remove soft opt-out feature. - ([\#1964](https://github.com/cosmos/interchain-security/pull/1964)) \ No newline at end of file diff --git a/app/consumer-democracy/app.go b/app/consumer-democracy/app.go index a57f237a14..e90d35760e 100644 --- a/app/consumer-democracy/app.go +++ b/app/consumer-democracy/app.go @@ -551,6 +551,7 @@ func New( // CanWithdrawInvariant invariant. // NOTE: staking module is required if HistoricalEntries param > 0 // NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC) + // NOTE: the soft opt-out requires that the consumer module's beginblocker comes after the slashing module's beginblocker app.MM.SetOrderBeginBlockers( // upgrades should be run first upgradetypes.ModuleName, diff --git a/app/consumer/app.go b/app/consumer/app.go index e1d82bb600..9853145117 100644 --- a/app/consumer/app.go +++ b/app/consumer/app.go @@ -481,6 +481,7 @@ func New( // NOTE: Capability module must occur first so that it can initialize any capabilities // so that other modules that want to create or claim capabilities afterwards in InitChain // can do so safely. + // NOTE: the soft opt-out requires that the consumer module's beginblocker comes after the slashing module's beginblocker app.MM.SetOrderInitGenesis( capabilitytypes.ModuleName, authtypes.ModuleName, diff --git a/app/consumer/genesis.go b/app/consumer/genesis.go index 176d9d2d0e..f6c8e47905 100644 --- a/app/consumer/genesis.go +++ b/app/consumer/genesis.go @@ -81,9 +81,6 @@ func transformToNew(jsonRaw []byte, ctx client.Context) (json.RawMessage, error) oldConsumerGenesis.Params.RetryDelayPeriod = types.DefaultRetryDelayPeriod } - // `SoftOptOutThreshold` is deprecated in the current consumer implementation, so set to zero - oldConsumerGenesis.Params.SoftOptOutThreshold = "0" - // Versions before v3.3.x of provider genesis data fills up deprecated fields // ProviderClientState, ConsensusState and InitialValSet in type GenesisState newGenesis := types.ConsumerGenesisState{ diff --git a/app/consumer/genesis_test.go b/app/consumer/genesis_test.go index 16cdf94e25..5827651959 100644 --- a/app/consumer/genesis_test.go +++ b/app/consumer/genesis_test.go @@ -494,9 +494,7 @@ func TestConsumerGenesisTransformationFromV2ToCurrent(t *testing.T) { require.EqualValues(t, srcGenesis.Params.ConsumerRedistributionFraction, resultGenesis.Params.ConsumerRedistributionFraction) require.EqualValues(t, srcGenesis.Params.HistoricalEntries, resultGenesis.Params.HistoricalEntries) require.EqualValues(t, srcGenesis.Params.UnbondingPeriod, resultGenesis.Params.UnbondingPeriod) - - // `SoftOptOutThreshold` is deprecated, so it should be set to zero the current version - require.EqualValues(t, "0", resultGenesis.Params.SoftOptOutThreshold) + require.EqualValues(t, srcGenesis.Params.SoftOptOutThreshold, resultGenesis.Params.SoftOptOutThreshold) require.EqualValues(t, srcGenesis.Params.RewardDenoms, resultGenesis.Params.RewardDenoms) require.EqualValues(t, srcGenesis.Params.ProviderRewardDenoms, resultGenesis.Params.ProviderRewardDenoms) @@ -567,10 +565,7 @@ func TestConsumerGenesisTransformationV330ToCurrent(t *testing.T) { require.Equal(t, srcGenesis.Params.ConsumerRedistributionFraction, resultGenesis.Params.ConsumerRedistributionFraction) require.Equal(t, srcGenesis.Params.HistoricalEntries, resultGenesis.Params.HistoricalEntries) require.Equal(t, srcGenesis.Params.UnbondingPeriod, resultGenesis.Params.UnbondingPeriod) - - // `SoftOptOutThreshold` is deprecated, so it should be set to zero the current version - require.Equal(t, "0", resultGenesis.Params.SoftOptOutThreshold) - + require.Equal(t, srcGenesis.Params.SoftOptOutThreshold, resultGenesis.Params.SoftOptOutThreshold) require.Equal(t, srcGenesis.Params.RewardDenoms, resultGenesis.Params.RewardDenoms) require.Equal(t, srcGenesis.Params.ProviderRewardDenoms, resultGenesis.Params.ProviderRewardDenoms) diff --git a/app/sovereign/app.go b/app/sovereign/app.go index 3d1a981e83..4017ca9d4f 100644 --- a/app/sovereign/app.go +++ b/app/sovereign/app.go @@ -79,6 +79,7 @@ import ( govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + // add mint mint "github.com/cosmos/cosmos-sdk/x/mint" mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" diff --git a/docs/docs/adrs/adr-009-soft-opt-out.md b/docs/docs/adrs/adr-009-soft-opt-out.md index defe885a96..b8dbc27124 100644 --- a/docs/docs/adrs/adr-009-soft-opt-out.md +++ b/docs/docs/adrs/adr-009-soft-opt-out.md @@ -7,12 +7,11 @@ title: Soft Opt-Out ## Changelog * 6/13/23: Initial draft of ADR. Feature already implemented and in production. -* 6/19/24: Change status to deprecated ## Status -Deprecated -Deprecated by [Partial Set Security](adr-015-partial-set-security.md) +Accepted + ## Context Some small validators may not have the resources needed to validate all consumer chains. Therefore a need exists to allow the bottom `x%` of validators to opt-out of validating a consumer chain. Meaning downtime infractions for these validators are dropped without ever reaching the provider. diff --git a/docs/docs/adrs/intro.md b/docs/docs/adrs/intro.md index 110698c518..d94a628bf4 100644 --- a/docs/docs/adrs/intro.md +++ b/docs/docs/adrs/intro.md @@ -37,6 +37,7 @@ To suggest an ADR, please make use of the [ADR template](./templates/adr-templat - [ADR 004: Denom DOS fixes](./adr-004-denom-dos-fixes.md) - [ADR 005: Cryptographic verification of equivocation evidence](./adr-005-cryptographic-equivocation-verification.md) - [ADR 008: Throttle with retries](./adr-008-throttle-retries.md) +- [ADR 009: Soft Opt-Out](./adr-009-soft-opt-out.md) - [ADR 010: Standalone to Consumer Changeover](./adr-010-standalone-changeover.md) - [ADR 013: Slashing on the provider for consumer equivocation](./adr-013-equivocation-slashing.md) - [ADR 014: Epochs](./adr-014-epochs.md) @@ -56,4 +57,3 @@ To suggest an ADR, please make use of the [ADR template](./templates/adr-templat ### Deprecated - [ADR 003: Equivocation governance proposal](./adr-003-equivocation-gov-proposal.md) -- [ADR 009: Soft Opt-Out](./adr-009-soft-opt-out.md) diff --git a/docs/docs/features/proposals.md b/docs/docs/features/proposals.md index 44ea4f0298..5f5457fc0a 100644 --- a/docs/docs/features/proposals.md +++ b/docs/docs/features/proposals.md @@ -77,6 +77,14 @@ Minimal example: } ``` +:::warning +Before the introduction of Partial Set Security, consumer chains typically included a "soft opt-out mechanism" +which allows the bottom N% of the provider's validators to not validate the consumer chain, without being jailed for downtime on the provider. +After the introduction of Partial Set Security, the use of the soft opt-out mechanism is discouraged, and consumer chains are +encouraged to use the topN parameter to not force validators with little stake to validate the chain. +::: + + ## `ConsumerModificationProposal` Proposal type used to change the power shaping parameters of a running consumer chain, as well as to change a Top N running consumer chain to an Opt-In chain and vice versa. diff --git a/proto/interchain_security/ccv/consumer/v1/consumer.proto b/proto/interchain_security/ccv/consumer/v1/consumer.proto index 0d42d2d16e..749eedc7ac 100644 --- a/proto/interchain_security/ccv/consumer/v1/consumer.proto +++ b/proto/interchain_security/ccv/consumer/v1/consumer.proto @@ -27,10 +27,7 @@ message CrossChainValidator { (cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey", (gogoproto.moretags) = "yaml:\"consensus_pubkey\"" ]; - - // !!! DEPRECATED !!! opted_out is deprecated because after the introduction of Partial Set Security (PSS) - // we removed the soft opt-out feature. - bool opted_out = 4 [deprecated = true]; + bool opted_out = 4; } // A record storing the state of a slash packet sent to the provider chain diff --git a/proto/interchain_security/ccv/v1/shared_consumer.proto b/proto/interchain_security/ccv/v1/shared_consumer.proto index 6c8cccfe86..d1f0a5d5a3 100644 --- a/proto/interchain_security/ccv/v1/shared_consumer.proto +++ b/proto/interchain_security/ccv/v1/shared_consumer.proto @@ -62,8 +62,11 @@ message ConsumerParams { google.protobuf.Duration unbonding_period = 9 [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; - // !!! DEPRECATED !!! soft_opt_out_threshold is deprecated. see docs/docs/adrs/adr-015-partial-set-security.md - string soft_opt_out_threshold = 10 [deprecated = true]; + // The threshold for the percentage of validators at the bottom of the set who + // can opt out of running the consumer chain without being punished. For + // example, a value of 0.05 means that the validators in the bottom 5% of the + // set can opt out + string soft_opt_out_threshold = 10; // Reward denoms. These are the denominations which are allowed to be sent to // the provider as rewards. diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index 9628338019..2e8b500eb7 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -463,6 +463,7 @@ func (tr TestConfig) submitConsumerModificationProposal( } bz, err = cmd.CombinedOutput() + if err != nil { log.Fatal(err, "\n", string(bz)) } @@ -605,14 +606,10 @@ func (tr *TestConfig) startConsumerChain( verbose bool, ) { fmt.Println("Starting consumer chain ", action.ConsumerChain) - consumerGenesis := ".app_state.ccvconsumer = " + tr.getConsumerGenesis(action.ProviderChain, action.ConsumerChain, target) consumerGenesisChanges := tr.chainConfigs[action.ConsumerChain].GenesisChanges if consumerGenesisChanges != "" { - consumerGenesis = consumerGenesis + " | " + consumerGenesisChanges - } - if action.GenesisChanges != "" { - consumerGenesis = consumerGenesis + " | " + action.GenesisChanges + consumerGenesis = consumerGenesis + " | " + consumerGenesisChanges + " | " + action.GenesisChanges } tr.startChain(StartChainAction{ @@ -844,10 +841,7 @@ func (tr TestConfig) changeoverChain( consumerGenesis := ".app_state.ccvconsumer = " + string(bz) consumerGenesisChanges := tr.chainConfigs[action.SovereignChain].GenesisChanges if consumerGenesisChanges != "" { - consumerGenesis = consumerGenesis + " | " + consumerGenesisChanges - } - if action.GenesisChanges != "" { - consumerGenesis = consumerGenesis + " | " + action.GenesisChanges + consumerGenesis = consumerGenesis + " | " + consumerGenesisChanges + " | " + action.GenesisChanges } tr.startChangeover(ChangeoverChainAction{ @@ -2071,7 +2065,7 @@ func (tr TestConfig) invokeDoublesignSlash( if err != nil { log.Fatal(err, "\n", string(bz)) } - tr.waitBlocks("provi", 20, 4*time.Minute) + tr.waitBlocks("provi", 10, 2*time.Minute) } else { // tr.useCometMock validatorPrivateKeyAddress := tr.GetValidatorPrivateKeyAddress(action.Chain, action.Validator) diff --git a/tests/e2e/step_delegation.go b/tests/e2e/step_delegation.go index 531f0cbceb..102ee76fa2 100644 --- a/tests/e2e/step_delegation.go +++ b/tests/e2e/step_delegation.go @@ -220,6 +220,58 @@ func stepsCancelUnbond(consumerName string) []Step { } } +// stepsRedelegateForOptOut tests redelegation, and sets up voting powers s.t +// alice will have less than 5% of the total voting power. This is needed to +// test opt-out functionality. +func stepsRedelegateForOptOut(consumerName string) []Step { + return []Step{ + { + Action: RedelegateTokensAction{ + Chain: ChainID("provi"), + Src: ValidatorID("alice"), + Dst: ValidatorID("carol"), + TxSender: ValidatorID("alice"), + Amount: 450000000, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 60, + ValidatorID("bob"): 500, + ValidatorID("carol"): 950, + }, + }, + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + // Voting power changes not seen by consumer yet + ValidatorID("alice"): 510, + ValidatorID("bob"): 500, + ValidatorID("carol"): 500, + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID(consumerName), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + // Now power changes are seen by consumer + ValidatorID("alice"): 60, + ValidatorID("bob"): 500, + ValidatorID("carol"): 950, + }, + }, + }, + }, + } +} + // stepsRedelegate tests redelegation and resulting validator power changes. func stepsRedelegate(consumerName string) []Step { return []Step{ @@ -231,15 +283,68 @@ func stepsRedelegate(consumerName string) []Step { TxSender: ValidatorID("carol"), // redelegate s.t. alice has majority stake so non-faulty validators maintain more than // 2/3 voting power during downtime tests below, avoiding chain halt - Amount: 400000000, + Amount: 449000000, }, State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, // carol always uses a consumer assigned key - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, + }, + }, + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + // Voting power changes not seen by consumer yet + ValidatorID("alice"): 60, + ValidatorID("bob"): 500, + ValidatorID("carol"): 950, + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID(consumerName), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + // Now power changes are seen by consumer + ValidatorID("alice"): 509, + ValidatorID("bob"): 500, + ValidatorID("carol"): 501, + }, + }, + }, + }, + } +} + +// stepsRedelegate tests redelegation and resulting validator power changes. +func stepsRedelegateShort(consumerName string) []Step { + return []Step{ + { + Action: RedelegateTokensAction{ + Chain: ChainID("provi"), + Src: ValidatorID("alice"), + Dst: ValidatorID("carol"), + TxSender: ValidatorID("alice"), + // Leave alice with majority stake so non-faulty validators maintain more than + // 2/3 voting power during downtime tests below, avoiding chain halt + Amount: 1000000, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 509, + ValidatorID("bob"): 500, + // carol always uses a consumer assigned key + ValidatorID("carol"): 501, }, }, ChainID(consumerName): ChainState{ @@ -263,9 +368,9 @@ func stepsRedelegate(consumerName string) []Step { ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ // Now power changes are seen by consumer - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, }, diff --git a/tests/e2e/steps.go b/tests/e2e/steps.go index 5e16a61776..4a6f40333e 100644 --- a/tests/e2e/steps.go +++ b/tests/e2e/steps.go @@ -18,7 +18,7 @@ var compatibilitySteps = concatSteps( compstepsStartChains([]string{"consu"}, false), stepsDelegate("consu"), stepsUnbond("consu"), - stepsRedelegate("consu"), + stepsRedelegateShort("consu"), stepsDowntime("consu"), stepsDoubleSignOnProvider("consu"), // carol double signs on provider stepsStartRelayer(), @@ -32,6 +32,8 @@ var happyPathSteps = concatSteps( stepsAssignConsumerKeyOnStartedChain("consu", "bob"), stepsUnbond("consu"), stepsCancelUnbond("consu"), + stepsRedelegateForOptOut("consu"), + stepsDowntimeWithOptOut("consu"), stepsRedelegate("consu"), stepsDowntime("consu"), stepsDoubleSignOnProvider("consu"), // carol double signs on provider @@ -44,7 +46,7 @@ var shortHappyPathSteps = concatSteps( stepsStartChains([]string{"consu"}, false), stepsDelegate("consu"), stepsUnbond("consu"), - stepsRedelegate("consu"), + stepsRedelegateShort("consu"), stepsDowntime("consu"), stepsDoubleSignOnProvider("consu"), // carol double signs on provider stepsStartRelayer(), @@ -56,12 +58,12 @@ var lightClientAttackSteps = concatSteps( stepsStartChains([]string{"consu"}, false), stepsDelegate("consu"), stepsUnbond("consu"), - stepsRedelegate("consu"), + stepsRedelegateShort("consu"), stepsDowntime("consu"), stepsLightClientAttackOnProviderAndConsumer("consu"), // carol double signs on provider, bob double signs on consumer stepsStartRelayer(), - stepsConsumerRemovalPropNotPassing("consu", 2), // submit removal prop but vote no on it - chain should stay - stepsStopChain("consu", 3), // stop chain + stepsConsumerRemovalPropNotPassing("consu", 3), // submit removal prop but vote no on it - chain should stay + stepsStopChain("consu", 4), // stop chain ) var slashThrottleSteps = concatSteps( @@ -119,7 +121,7 @@ var changeoverSteps = concatSteps( var consumerMisbehaviourSteps = concatSteps( // start provider and consumer chain - stepsStartChainsForConsumerMisbehaviour("consu"), + stepsStartChainsWithSoftOptOut("consu"), // make a consumer validator to misbehave and get jailed stepsCauseConsumerMisbehaviour("consu"), ) @@ -135,6 +137,6 @@ var consumerDoubleDowntimeSteps = concatSteps( stepsStartChains([]string{"consu"}, false), stepsDelegate("consu"), stepsUnbond("consu"), - stepsRedelegate("consu"), + stepsRedelegateShort("consu"), stepsDoubleDowntime("consu"), ) diff --git a/tests/e2e/steps_active_set_changes.go b/tests/e2e/steps_active_set_changes.go index a29bd831d4..153e7a07b4 100644 --- a/tests/e2e/steps_active_set_changes.go +++ b/tests/e2e/steps_active_set_changes.go @@ -86,6 +86,12 @@ func stepsActiveSetChanges() []Step { {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, {Id: ValidatorID("carol"), Stake: 700000000, Allocation: 10000000000}, }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{}, }, diff --git a/tests/e2e/steps_compatibility.go b/tests/e2e/steps_compatibility.go index c5754aef43..c6bc3c88b1 100644 --- a/tests/e2e/steps_compatibility.go +++ b/tests/e2e/steps_compatibility.go @@ -143,6 +143,12 @@ func compstepsStartConsumerChain(consumerName string, proposalIndex, chainIndex {Id: ValidatorID("alice"), Stake: 500000000, Allocation: 10000000000}, {Id: ValidatorID("carol"), Stake: 500000000, Allocation: 10000000000}, }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{ ChainID("provi"): ChainState{ diff --git a/tests/e2e/steps_consumer_misbehaviour.go b/tests/e2e/steps_consumer_misbehaviour.go index ab0c474a41..bd6e3f1d3c 100644 --- a/tests/e2e/steps_consumer_misbehaviour.go +++ b/tests/e2e/steps_consumer_misbehaviour.go @@ -4,8 +4,10 @@ import ( clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ) -// starts a provider chain and an Opt-In consumer chain with one validator -func stepsStartChainsForConsumerMisbehaviour(consumerName string) []Step { +// starts a provider chain and a consumer chain with two validators, +// where the voting power is distributed in order that the smallest validator +// can soft opt-out of validating the consumer chain. +func stepsStartChainsWithSoftOptOut(consumerName string) []Step { s := []Step{ { // Create a provider chain with two validators, where one validator holds 96% of the voting power @@ -34,7 +36,7 @@ func stepsStartChainsForConsumerMisbehaviour(consumerName string) []Step { ConsumerChain: ChainID(consumerName), SpawnTime: 0, InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, - TopN: 0, + TopN: 100, }, State: State{ ChainID("provi"): ChainState{ @@ -77,13 +79,6 @@ func stepsStartChainsForConsumerMisbehaviour(consumerName string) []Step { }, }, }, - { - Action: OptInAction{ - Chain: ChainID(consumerName), - Validator: ValidatorID("alice"), - }, - State: State{}, - }, { Action: VoteGovProposalAction{ Chain: ChainID("provi"), @@ -111,12 +106,19 @@ func stepsStartChainsForConsumerMisbehaviour(consumerName string) []Step { }, { // start a consumer chain using a single big validator knowing that it holds more than 2/3 of the voting power + // and that the other validators hold less than 5% so they won't get jailed thanks to the sof opt-out mechanism. Action: StartConsumerChainAction{ ConsumerChain: ChainID(consumerName), ProviderChain: ChainID("provi"), Validators: []StartChainValidator{ {Id: ValidatorID("alice"), Stake: 500000000, Allocation: 10000000000}, }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{ ChainID("provi"): ChainState{ @@ -171,6 +173,7 @@ func stepsStartChainsForConsumerMisbehaviour(consumerName string) []Step { ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 500, + ValidatorID("bob"): 20, }, }, }, @@ -186,6 +189,7 @@ func stepsStartChainsForConsumerMisbehaviour(consumerName string) []Step { ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, + ValidatorID("bob"): 20, }, }, }, @@ -235,7 +239,7 @@ func stepsCauseConsumerMisbehaviour(consumerName string) []Step { ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, - ValidatorID("bob"): 0, + ValidatorID("bob"): 20, }, }, }, @@ -275,7 +279,7 @@ func stepsCauseConsumerMisbehaviour(consumerName string) []Step { // since its light client is frozen on the provider ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, - ValidatorID("bob"): 0, + ValidatorID("bob"): 20, }, }, }, diff --git a/tests/e2e/steps_double_sign.go b/tests/e2e/steps_double_sign.go index bdc4a68cb4..353de13761 100644 --- a/tests/e2e/steps_double_sign.go +++ b/tests/e2e/steps_double_sign.go @@ -13,16 +13,16 @@ func stepsDoubleSignOnProvider(consumerName string) []Step { // slash on provider ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, - ValidatorID("carol"): 0, // from 99 to 0 + ValidatorID("carol"): 0, // from 500 to 0 }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, - ValidatorID("carol"): 99, // not tombstoned on consumerName yet + ValidatorID("carol"): 495, // not tombstoned on consumerName yet }, }, }, @@ -38,14 +38,14 @@ func stepsDoubleSignOnProvider(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, ValidatorID("carol"): 0, // tombstoning visible on consumerName }, diff --git a/tests/e2e/steps_downtime.go b/tests/e2e/steps_downtime.go index 70fd81c130..a8506bf518 100644 --- a/tests/e2e/steps_downtime.go +++ b/tests/e2e/steps_downtime.go @@ -23,16 +23,16 @@ func stepsDowntime(consumerName string) []Step { // validator should be slashed on consumer, powers not affected on either chain yet ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, }, @@ -47,18 +47,18 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, // Downtime jailing and corresponding voting power change are processed by provider ValidatorID("bob"): 0, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, // Bob's stake may or may not be slashed at this point depending on comet vs cometmock // See https://github.com/cosmos/interchain-security/issues/1304 - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, }, @@ -75,10 +75,10 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, // VSC now seen on consumer ValidatorID("bob"): 0, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, }, @@ -91,18 +91,18 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, // bob's stake should not be slashed // since the slash was initiated from consumer ValidatorID("bob"): 500, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 0, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, }, @@ -117,11 +117,11 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, // bob's stake should not be slashed // since the slash was initiated from consumer ValidatorID("bob"): 500, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, }, @@ -136,7 +136,7 @@ func stepsDowntime(consumerName string) []Step { ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ // Non faulty validators still maintain just above 2/3 power here - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, // Carol's stake should be slashed and jailed // downtime slash was initiated from provider @@ -145,9 +145,9 @@ func stepsDowntime(consumerName string) []Step { }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, }, @@ -162,7 +162,7 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, @@ -177,14 +177,14 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, - ValidatorID("carol"): 99, + ValidatorID("carol"): 495, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, @@ -201,9 +201,9 @@ func stepsDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, - ValidatorID("carol"): 99, + ValidatorID("carol"): 495, }, }, }, @@ -211,7 +211,7 @@ func stepsDowntime(consumerName string) []Step { } } -// stepsDoubleDowntime time tests that a validator can get jailed twice +// stepsDowstepsDoubleDowntime time tests that a validator can get jailed twice // on a consumer. // These are the steps: // - a validator is down on a consumer @@ -233,16 +233,16 @@ func stepsDoubleDowntime(consumerName string) []Step { // validator should be slashed on consumer, powers not affected on either chain yet ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, }, @@ -257,18 +257,18 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, // Downtime jailing and corresponding voting power change are processed by provider ValidatorID("bob"): 0, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, // Bob's stake may or may not be slashed at this point depending on comet vs cometmock // See https://github.com/cosmos/interchain-security/issues/1304 - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, }, @@ -285,10 +285,10 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, // VSC now seen on consumer ValidatorID("bob"): 0, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, }, @@ -301,18 +301,18 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, // bob's stake should not be slashed // since the slash was initiated from consumer ValidatorID("bob"): 500, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 0, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, }, @@ -327,11 +327,11 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, // bob's stake should not be slashed // since the slash was initiated from consumer ValidatorID("bob"): 500, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, }, @@ -346,16 +346,16 @@ func stepsDoubleDowntime(consumerName string) []Step { // validator should be slashed on consumer, powers not affected on either chain yet ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, }, @@ -370,18 +370,18 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, // Downtime jailing and corresponding voting power change are processed by provider ValidatorID("bob"): 0, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, // Bob's stake may or may not be slashed at this point depending on comet vs cometmock // See https://github.com/cosmos/interchain-security/issues/1304 - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, }, }, }, @@ -398,10 +398,67 @@ func stepsDoubleDowntime(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, // VSC now seen on consumer ValidatorID("bob"): 0, - ValidatorID("carol"): 100, + ValidatorID("carol"): 501, + }, + }, + }, + }, + } +} + +// stepsDowntimeWithOptOut returns steps validating that alice can incur downtime +// and not be slashed/jailed, since her voting power is less than 5% of the total. +// +// Note: 60 / (60 + 500 + 950) ~= 0.04 +func stepsDowntimeWithOptOut(consumerName string) []Step { + return []Step{ + { + Action: DowntimeSlashAction{ + Chain: ChainID(consumerName), + Validator: ValidatorID("alice"), + }, + State: State{ + // powers not affected on either chain + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 60, + ValidatorID("bob"): 500, + ValidatorID("carol"): 950, + }, + }, + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 60, + ValidatorID("bob"): 500, + ValidatorID("carol"): 950, + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID(consumerName), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + // alice is not slashed or jailed due to soft opt out + ValidatorID("alice"): 60, + ValidatorID("bob"): 500, + ValidatorID("carol"): 950, + }, + }, + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 60, + ValidatorID("bob"): 500, + ValidatorID("carol"): 950, }, }, }, diff --git a/tests/e2e/steps_light_client_attack.go b/tests/e2e/steps_light_client_attack.go index afe1356c51..65481157b1 100644 --- a/tests/e2e/steps_light_client_attack.go +++ b/tests/e2e/steps_light_client_attack.go @@ -13,16 +13,16 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { // Slash on provider ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, - ValidatorID("carol"): 0, // from 100 to 0 + ValidatorID("carol"): 0, // from 500 to 0 }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, - ValidatorID("carol"): 99, // not tombstoned on consumerName yet + ValidatorID("carol"): 495, // not tombstoned on consumerName yet }, }, }, @@ -38,14 +38,14 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, ValidatorID("carol"): 0, // tombstoning visible on consumerName }, @@ -62,14 +62,14 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, @@ -86,14 +86,14 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, // not tombstoned ValidatorID("carol"): 0, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, // not tombstoned ValidatorID("carol"): 0, }, @@ -111,14 +111,14 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, ValidatorID("carol"): 0, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 910, + ValidatorID("alice"): 509, ValidatorID("bob"): 500, // not tombstoned ValidatorID("carol"): 0, }, diff --git a/tests/e2e/steps_partial_set_security.go b/tests/e2e/steps_partial_set_security.go index 77a76a0dd2..1002302620 100644 --- a/tests/e2e/steps_partial_set_security.go +++ b/tests/e2e/steps_partial_set_security.go @@ -118,6 +118,12 @@ func stepsOptInChain() []Step { {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{ ChainID("consu"): ChainState{ @@ -607,6 +613,12 @@ func stepsTopNChain() []Step { {Id: ValidatorID("bob"), Stake: 300000000, Allocation: 10000000000}, {Id: ValidatorID("carol"), Stake: 500000000, Allocation: 10000000000}, }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{ ChainID("consu"): ChainState{ @@ -1132,6 +1144,12 @@ func stepsValidatorSetCappedChain() []Step { {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{ ChainID("consu"): ChainState{ @@ -1362,6 +1380,12 @@ func stepsValidatorsPowerCappedChain() []Step { {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{ ChainID("consu"): ChainState{ @@ -1482,10 +1506,8 @@ func stepsValidatorsAllowlistedChain() []Step { InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, TopN: 0, // only "alice" and "bob" are allowlisted (see `getDefaultValidators` in `tests/e2e/config.go`) - Allowlist: []string{ - "cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq", - "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39", - }, + Allowlist: []string{"cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq", + "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39"}, }, State: State{ ChainID("provi"): ChainState{ @@ -1595,6 +1617,12 @@ func stepsValidatorsAllowlistedChain() []Step { {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{ ChainID("consu"): ChainState{ @@ -1798,6 +1826,12 @@ func stepsValidatorsDenylistedChain() []Step { {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{ ChainID("consu"): ChainState{ @@ -2000,6 +2034,12 @@ func stepsModifyChain() []Step { {Id: ValidatorID("bob"), Stake: 200000000, Allocation: 10000000000}, {Id: ValidatorID("carol"), Stake: 300000000, Allocation: 10000000000}, }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{ ChainID("consu"): ChainState{ @@ -2204,10 +2244,8 @@ func stepsModifyChain() []Step { Deposit: 10000001, ConsumerChain: ChainID("consu"), // only "alice" and "carol" are allowlisted (see `getDefaultValidators` in `tests/e2e/config.go`) - Allowlist: []string{ - "cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq", - "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6", - }, + Allowlist: []string{"cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq", + "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6"}, }, State: State{ ChainID("provi"): ChainState{ @@ -2394,8 +2432,7 @@ func stepsModifyChain() []Step { ExpectError: true, // because this chain is now Top 100%, no validator can opt out }, State: State{}, - }, - } + }} return s } diff --git a/tests/e2e/steps_sovereign_changeover.go b/tests/e2e/steps_sovereign_changeover.go index 3cdbc38dac..1ddd5a2143 100644 --- a/tests/e2e/steps_sovereign_changeover.go +++ b/tests/e2e/steps_sovereign_changeover.go @@ -102,6 +102,7 @@ func stepsChangeoverToConsumer(consumerName string) []Step { {Id: ValidatorID("bob"), Stake: 500000000, Allocation: 10000000000}, {Id: ValidatorID("carol"), Stake: 500000000, Allocation: 10000000000}, }, + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{ ChainID("provi"): ChainState{ diff --git a/tests/e2e/steps_start_chains.go b/tests/e2e/steps_start_chains.go index 67fbc585a4..2ff3226dec 100644 --- a/tests/e2e/steps_start_chains.go +++ b/tests/e2e/steps_start_chains.go @@ -159,6 +159,12 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint {Id: ValidatorID("alice"), Stake: 500000000, Allocation: 10000000000}, {Id: ValidatorID("carol"), Stake: 500000000, Allocation: 10000000000}, }, + // For consumers that're launching with the provider being on an earlier version + // of ICS before the soft opt-out threshold was introduced, we need to set the + // soft opt-out threshold to 0.05 in the consumer genesis to ensure that the + // consumer binary doesn't panic. Sdk requires that all params are set to valid + // values from the genesis file. + GenesisChanges: ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"", }, State: State{ ChainID("provi"): ChainState{ diff --git a/tests/e2e/tracehandler_testdata/changeover.json b/tests/e2e/tracehandler_testdata/changeover.json index 79601b4a2d..1b6ae37ae1 100644 --- a/tests/e2e/tracehandler_testdata/changeover.json +++ b/tests/e2e/tracehandler_testdata/changeover.json @@ -235,11 +235,7 @@ "revision_height": 111 }, "DistributionChannel": "channel-0", - "TopN": 100, - "ValidatorsPowerCap": 0, - "ValidatorSetCap": 0, - "Allowlist": null, - "Denylist": null + "TopN": 100 }, "State": { "provi": { @@ -349,7 +345,7 @@ "Stake": 500000000 } ], - "GenesisChanges": "" + "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" }, "State": { "provi": { diff --git a/tests/e2e/tracehandler_testdata/consumer-double-sign.json b/tests/e2e/tracehandler_testdata/consumer-double-sign.json index c47b259465..290f351875 100644 --- a/tests/e2e/tracehandler_testdata/consumer-double-sign.json +++ b/tests/e2e/tracehandler_testdata/consumer-double-sign.json @@ -59,11 +59,7 @@ "revision_height": 1 }, "DistributionChannel": "", - "TopN": 100, - "ValidatorsPowerCap": 0, - "ValidatorSetCap": 0, - "Allowlist": null, - "Denylist": null + "TopN": 100 }, "State": { "provi": { @@ -275,7 +271,7 @@ "Stake": 500000000 } ], - "GenesisChanges": "" + "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" }, "State": { "consu": { diff --git a/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json b/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json index 926b58b561..b0c64232e2 100644 --- a/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json +++ b/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json @@ -53,11 +53,7 @@ "revision_height": 1 }, "DistributionChannel": "", - "TopN": 0, - "ValidatorsPowerCap": 0, - "ValidatorSetCap": 0, - "Allowlist": null, - "Denylist": null + "TopN": 100 }, "State": { "provi": { @@ -127,14 +123,6 @@ } } }, - { - "ActionType": "main.OptInAction", - "Action": { - "Chain": "consu", - "Validator": "alice" - }, - "State": {} - }, { "ActionType": "main.VoteGovProposalAction", "Action": { @@ -196,7 +184,7 @@ "Stake": 500000000 } ], - "GenesisChanges": "" + "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" }, "State": { "consu": { @@ -274,7 +262,8 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 500 + "alice": 500, + "bob": 20 }, "StakedTokens": null, "Params": null, @@ -322,7 +311,8 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 511 + "alice": 511, + "bob": 20 }, "StakedTokens": null, "Params": null, @@ -364,7 +354,7 @@ "ProposedConsumerChains": null, "ValPowers": { "alice": 511, - "bob": 0 + "bob": 20 }, "StakedTokens": null, "Params": null, @@ -416,7 +406,7 @@ "ProposedConsumerChains": null, "ValPowers": { "alice": 511, - "bob": 0 + "bob": 20 }, "StakedTokens": null, "Params": null, diff --git a/tests/e2e/tracehandler_testdata/democracy.json b/tests/e2e/tracehandler_testdata/democracy.json index bb9a861af4..bcfcd0bcd4 100644 --- a/tests/e2e/tracehandler_testdata/democracy.json +++ b/tests/e2e/tracehandler_testdata/democracy.json @@ -59,11 +59,7 @@ "revision_height": 1 }, "DistributionChannel": "", - "TopN": 100, - "ValidatorsPowerCap": 0, - "ValidatorSetCap": 0, - "Allowlist": null, - "Denylist": null + "TopN": 100 }, "State": { "provi": { @@ -275,7 +271,7 @@ "Stake": 500000000 } ], - "GenesisChanges": "" + "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" }, "State": { "democ": { diff --git a/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json b/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json index 137199c483..83b1f326d9 100644 --- a/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json +++ b/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json @@ -59,11 +59,7 @@ "revision_height": 1 }, "DistributionChannel": "", - "TopN": 100, - "ValidatorsPowerCap": 0, - "ValidatorSetCap": 0, - "Allowlist": null, - "Denylist": null + "TopN": 100 }, "State": { "provi": { @@ -275,7 +271,7 @@ "Stake": 500000000 } ], - "GenesisChanges": "" + "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" }, "State": { "democ": { diff --git a/tests/e2e/tracehandler_testdata/happyPath.json b/tests/e2e/tracehandler_testdata/happyPath.json index 33e7815108..0109d72501 100644 --- a/tests/e2e/tracehandler_testdata/happyPath.json +++ b/tests/e2e/tracehandler_testdata/happyPath.json @@ -59,11 +59,7 @@ "revision_height": 1 }, "DistributionChannel": "", - "TopN": 100, - "ValidatorsPowerCap": 0, - "ValidatorSetCap": 0, - "Allowlist": null, - "Denylist": null + "TopN": 100 }, "State": { "provi": { @@ -275,7 +271,7 @@ "Stake": 500000000 } ], - "GenesisChanges": "" + "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" }, "State": { "consu": { @@ -847,6 +843,189 @@ } } }, + { + "ActionType": "main.RedelegateTokensAction", + "Action": { + "Chain": "provi", + "Src": "alice", + "Dst": "carol", + "TxSender": "alice", + "Amount": 450000000 + }, + "State": { + "consu": { + "ValBalances": null, + "ProposedConsumerChains": null, + "ValPowers": { + "alice": 510, + "bob": 500, + "carol": 500 + }, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "HasToValidate": null, + "Proposals": null + }, + "provi": { + "ValBalances": null, + "ProposedConsumerChains": null, + "ValPowers": { + "alice": 60, + "bob": 500, + "carol": 950 + }, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "HasToValidate": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.RelayPacketsAction", + "Action": { + "ChainA": "provi", + "ChainB": "consu", + "Port": "provider", + "Channel": 0 + }, + "State": { + "consu": { + "ValBalances": null, + "ProposedConsumerChains": null, + "ValPowers": { + "alice": 60, + "bob": 500, + "carol": 950 + }, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "HasToValidate": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.DowntimeSlashAction", + "Action": { + "Chain": "consu", + "Validator": "alice" + }, + "State": { + "consu": { + "ValBalances": null, + "ProposedConsumerChains": null, + "ValPowers": { + "alice": 60, + "bob": 500, + "carol": 950 + }, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "HasToValidate": null, + "Proposals": null + }, + "provi": { + "ValBalances": null, + "ProposedConsumerChains": null, + "ValPowers": { + "alice": 60, + "bob": 500, + "carol": 950 + }, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "HasToValidate": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.RelayPacketsAction", + "Action": { + "ChainA": "provi", + "ChainB": "consu", + "Port": "provider", + "Channel": 0 + }, + "State": { + "consu": { + "ValBalances": null, + "ProposedConsumerChains": null, + "ValPowers": { + "alice": 60, + "bob": 500, + "carol": 950 + }, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "HasToValidate": null, + "Proposals": null + }, + "provi": { + "ValBalances": null, + "ProposedConsumerChains": null, + "ValPowers": { + "alice": 60, + "bob": 500, + "carol": 950 + }, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "HasToValidate": null, + "Proposals": null + } + } + }, { "ActionType": "main.RedelegateTokensAction", "Action": { @@ -854,16 +1033,16 @@ "Src": "carol", "Dst": "alice", "TxSender": "carol", - "Amount": 400000000 + "Amount": 449000000 }, "State": { "consu": { "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 510, + "alice": 60, "bob": 500, - "carol": 500 + "carol": 950 }, "StakedTokens": null, "Params": null, @@ -881,9 +1060,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -912,9 +1091,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -941,9 +1120,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -961,9 +1140,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -992,8 +1171,8 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, - "carol": 100 + "alice": 509, + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -1011,9 +1190,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 0, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -1042,9 +1221,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 0, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -1071,9 +1250,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 0, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -1091,9 +1270,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -1122,9 +1301,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -1151,9 +1330,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -1171,7 +1350,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, "carol": 0 }, @@ -1202,7 +1381,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, "carol": 0 }, @@ -1231,7 +1410,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, "carol": 0 }, @@ -1251,9 +1430,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 99 + "carol": 495 }, "StakedTokens": null, "Params": null, @@ -1282,9 +1461,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 99 + "carol": 495 }, "StakedTokens": null, "Params": null, @@ -1311,9 +1490,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 99 + "carol": 495 }, "StakedTokens": null, "Params": null, @@ -1331,7 +1510,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, "carol": 0 }, @@ -1362,7 +1541,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, "carol": 0 }, @@ -1382,7 +1561,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, "carol": 0 }, diff --git a/tests/e2e/tracehandler_testdata/multipleConsumers.json b/tests/e2e/tracehandler_testdata/multipleConsumers.json index 34626ebbe8..b8bffb9cde 100644 --- a/tests/e2e/tracehandler_testdata/multipleConsumers.json +++ b/tests/e2e/tracehandler_testdata/multipleConsumers.json @@ -59,11 +59,7 @@ "revision_height": 1 }, "DistributionChannel": "", - "TopN": 100, - "ValidatorsPowerCap": 0, - "ValidatorSetCap": 0, - "Allowlist": null, - "Denylist": null + "TopN": 100 }, "State": { "provi": { @@ -275,7 +271,7 @@ "Stake": 500000000 } ], - "GenesisChanges": "" + "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" }, "State": { "consu": { @@ -356,11 +352,7 @@ "revision_height": 1 }, "DistributionChannel": "", - "TopN": 100, - "ValidatorsPowerCap": 0, - "ValidatorSetCap": 0, - "Allowlist": null, - "Denylist": null + "TopN": 100 }, "State": { "provi": { @@ -572,7 +564,7 @@ "Stake": 500000000 } ], - "GenesisChanges": "" + "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" }, "State": { "densu": { diff --git a/tests/e2e/tracehandler_testdata/shorthappy.json b/tests/e2e/tracehandler_testdata/shorthappy.json index 0d4973862e..e029c5951b 100644 --- a/tests/e2e/tracehandler_testdata/shorthappy.json +++ b/tests/e2e/tracehandler_testdata/shorthappy.json @@ -59,11 +59,7 @@ "revision_height": 1 }, "DistributionChannel": "", - "TopN": 100, - "ValidatorsPowerCap": 0, - "ValidatorSetCap": 0, - "Allowlist": null, - "Denylist": null + "TopN": 100 }, "State": { "provi": { @@ -275,7 +271,7 @@ "Stake": 500000000 } ], - "GenesisChanges": "" + "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" }, "State": { "consu": { @@ -571,10 +567,10 @@ "ActionType": "main.RedelegateTokensAction", "Action": { "Chain": "provi", - "Src": "carol", - "Dst": "alice", - "TxSender": "carol", - "Amount": 400000000 + "Src": "alice", + "Dst": "carol", + "TxSender": "alice", + "Amount": 1000000 }, "State": { "consu": { @@ -601,9 +597,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -632,9 +628,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -661,9 +657,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -681,9 +677,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -712,8 +708,8 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, - "carol": 100 + "alice": 509, + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -731,9 +727,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 0, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -762,9 +758,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 0, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -791,9 +787,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 0, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -811,9 +807,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -842,9 +838,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -871,9 +867,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 100 + "carol": 501 }, "StakedTokens": null, "Params": null, @@ -891,7 +887,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, "carol": 0 }, @@ -922,7 +918,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, "carol": 0 }, @@ -951,7 +947,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, "carol": 0 }, @@ -971,9 +967,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 99 + "carol": 495 }, "StakedTokens": null, "Params": null, @@ -1002,9 +998,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 99 + "carol": 495 }, "StakedTokens": null, "Params": null, @@ -1031,9 +1027,9 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, - "carol": 99 + "carol": 495 }, "StakedTokens": null, "Params": null, @@ -1051,7 +1047,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, "carol": 0 }, @@ -1082,7 +1078,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, "carol": 0 }, @@ -1102,7 +1098,7 @@ "ValBalances": null, "ProposedConsumerChains": null, "ValPowers": { - "alice": 910, + "alice": 509, "bob": 500, "carol": 0 }, diff --git a/tests/e2e/tracehandler_testdata/slashThrottle.json b/tests/e2e/tracehandler_testdata/slashThrottle.json index eb413af7e5..fb701a4dc1 100644 --- a/tests/e2e/tracehandler_testdata/slashThrottle.json +++ b/tests/e2e/tracehandler_testdata/slashThrottle.json @@ -59,11 +59,7 @@ "revision_height": 1 }, "DistributionChannel": "", - "TopN": 100, - "ValidatorsPowerCap": 0, - "ValidatorSetCap": 0, - "Allowlist": null, - "Denylist": null + "TopN": 100 }, "State": { "provi": { @@ -275,7 +271,7 @@ "Stake": 500000000 } ], - "GenesisChanges": "" + "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" }, "State": { "consu": { diff --git a/tests/integration/soft_opt_out.go b/tests/integration/soft_opt_out.go new file mode 100644 index 0000000000..bce2e1d77c --- /dev/null +++ b/tests/integration/soft_opt_out.go @@ -0,0 +1,251 @@ +package integration + +import ( + "bytes" + "sort" + + sdk "github.com/cosmos/cosmos-sdk/types" + slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + abci "github.com/cometbft/cometbft/abci/types" + + consumerKeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" + ccv "github.com/cosmos/interchain-security/v4/x/ccv/types" +) + +// TestSoftOptOut tests the soft opt-out feature +// - if a validator in the top 95% doesn't sign 50 blocks on the consumer, a SlashPacket is sent to the provider +// - if a validator in the bottom 5% doesn't sign 50 blocks on the consumer, a SlashPacket is NOT sent to the provider +// - if a validator in the bottom 5% doesn't sign 49 blocks on the consumer, +// then it moves to the top 95% and doesn't sign one more block, a SlashPacket is NOT sent to the provider +func (suite *CCVTestSuite) TestSoftOptOut() { + var votes []abci.VoteInfo + + testCases := []struct { + name string + downtimeFunc func(*consumerKeeper.Keeper, *slashingkeeper.Keeper, []byte, int) + targetValidator int + expJailed bool + expSlashPacket bool + }{ + { + "downtime top 95%", + func(ck *consumerKeeper.Keeper, sk *slashingkeeper.Keeper, valAddr []byte, valIdx int) { + for i, voteInfo := range votes { + if bytes.Equal(voteInfo.Validator.Address, valAddr) { + votes[i].SignedLastBlock = false + } + } + blocksToDowntime := sk.SignedBlocksWindow(suite.consumerCtx()) - sk.MinSignedPerWindow(suite.consumerCtx()) + 1 + slashingBeginBlocker(suite, votes, blocksToDowntime) + }, + 0, + true, + true, + }, + { + "downtime bottom 5%", + func(ck *consumerKeeper.Keeper, sk *slashingkeeper.Keeper, valAddr []byte, valIdx int) { + for i, voteInfo := range votes { + if bytes.Equal(voteInfo.Validator.Address, valAddr) { + votes[i].SignedLastBlock = false + } + } + blocksToDowntime := sk.SignedBlocksWindow(suite.consumerCtx()) - sk.MinSignedPerWindow(suite.consumerCtx()) + 1 + slashingBeginBlocker(suite, votes, blocksToDowntime) + }, + 3, + true, + false, + }, + { + "downtime bottom 5% first and then top 95%, but not enough", + func(ck *consumerKeeper.Keeper, sk *slashingkeeper.Keeper, valAddr []byte, valIdx int) { + for i, voteInfo := range votes { + if bytes.Equal(voteInfo.Validator.Address, valAddr) { + votes[i].SignedLastBlock = false + } + } + blocksToDowntime := sk.SignedBlocksWindow(suite.consumerCtx()) - sk.MinSignedPerWindow(suite.consumerCtx()) + slashingBeginBlocker(suite, votes, blocksToDowntime) + + // Increase the power of this validator (to bring it in the top 95%) + delAddr := suite.providerChain.SenderAccount.GetAddress() + bondAmt := sdk.NewInt(100).Mul(sdk.DefaultPowerReduction) + delegateByIdx(suite, delAddr, bondAmt, valIdx) + + suite.nextEpoch() + + // Relay 1 VSC packet from provider to consumer + relayAllCommittedPackets(suite, suite.providerChain, suite.path, ccv.ProviderPortID, suite.path.EndpointB.ChannelID, 1) + + // Update validator from store + val, found := ck.GetCCValidator(suite.consumerCtx(), valAddr) + suite.Require().True(found) + smallestNonOptOutPower := ck.GetSmallestNonOptOutPower(suite.consumerCtx()) + suite.Require().Equal(val.Power, smallestNonOptOutPower) + + // Let the validator continue not signing, but not enough to get jailed + for i, voteInfo := range votes { + if bytes.Equal(voteInfo.Validator.Address, valAddr) { + votes[i].Validator.Power = val.Power + } + } + slashingBeginBlocker(suite, votes, 10) + }, + 2, + false, + false, + }, + { + "donwtime bottom 5% first and then top 95% until jailed", + func(ck *consumerKeeper.Keeper, sk *slashingkeeper.Keeper, valAddr []byte, valIdx int) { + for i, voteInfo := range votes { + if bytes.Equal(voteInfo.Validator.Address, valAddr) { + votes[i].SignedLastBlock = false + } + } + blocksToDowntime := sk.SignedBlocksWindow(suite.consumerCtx()) - sk.MinSignedPerWindow(suite.consumerCtx()) + slashingBeginBlocker(suite, votes, blocksToDowntime) + + // Increase the power of this validator (to bring it in the top 95%) + delAddr := suite.providerChain.SenderAccount.GetAddress() + bondAmt := sdk.NewInt(100).Mul(sdk.DefaultPowerReduction) + delegateByIdx(suite, delAddr, bondAmt, valIdx) + + suite.nextEpoch() + + // Relay 1 VSC packet from provider to consumer + relayAllCommittedPackets(suite, suite.providerChain, suite.path, ccv.ProviderPortID, suite.path.EndpointB.ChannelID, 1) + + // Update validator from store + val, found := ck.GetCCValidator(suite.consumerCtx(), valAddr) + suite.Require().True(found) + smallestNonOptOutPower := ck.GetSmallestNonOptOutPower(suite.consumerCtx()) + suite.Require().Equal(val.Power, smallestNonOptOutPower) + + // Let the validator continue not signing until it gets jailed. + // Due to the starting height being just updated, the signed blocked window needs to pass. + for i, voteInfo := range votes { + if bytes.Equal(voteInfo.Validator.Address, valAddr) { + votes[i].Validator.Power = val.Power + } + } + slashingBeginBlocker(suite, votes, sk.SignedBlocksWindow(suite.consumerCtx())+1) + }, + 2, + true, + true, + }, + } + + for i, tc := range testCases { + // initial setup + suite.SetupCCVChannel(suite.path) + + consumerKeeper := suite.consumerApp.GetConsumerKeeper() + consumerSlashingKeeper := suite.consumerApp.GetTestSlashingKeeper() + + // Setup validator power s.t. the bottom 5% is non-empty + validatorPowers := []int64{1000, 500, 50, 10} + suite.setupValidatorPowers(validatorPowers) + + suite.nextEpoch() + + // Relay 1 VSC packet from provider to consumer + relayAllCommittedPackets(suite, suite.providerChain, suite.path, ccv.ProviderPortID, suite.path.EndpointB.ChannelID, 1) + + // Check that the third validator is the first in the top 95% + smallestNonOptOutPower := consumerKeeper.GetSmallestNonOptOutPower(suite.consumerCtx()) + suite.Require().Equal(validatorPowers[1], smallestNonOptOutPower, "test: "+tc.name) + + // Get the list of all CCV validators + vals := consumerKeeper.GetAllCCValidator(suite.consumerCtx()) + // Note that GetAllCCValidator is iterating over a map so the result need to be sorted + sort.Slice(vals, func(i, j int) bool { + if vals[i].Power != vals[j].Power { + return vals[i].Power > vals[j].Power + } + return bytes.Compare(vals[i].Address, vals[j].Address) > 0 + }) + + // Let everyone sign the first 100 blocks (default value for slahing.SignedBlocksWindow param). + // This populates the signingInfo of the slashing module so that + // the check for starting height passes. + votes = []abci.VoteInfo{} + for _, val := range vals { + votes = append(votes, abci.VoteInfo{ + Validator: abci.Validator{Address: val.Address, Power: val.Power}, + SignedLastBlock: true, + }) + } + slashingBeginBlocker(suite, votes, consumerSlashingKeeper.SignedBlocksWindow(suite.consumerCtx())) + + // Downtime infraction + sk := consumerSlashingKeeper.(slashingkeeper.Keeper) + tc.downtimeFunc(&consumerKeeper, &sk, vals[tc.targetValidator].Address, tc.targetValidator) + + // Check the signing info for target validator + consAddr := sdk.ConsAddress(vals[tc.targetValidator].Address) + info, _ := consumerSlashingKeeper.GetValidatorSigningInfo(suite.consumerCtx(), consAddr) + if tc.expJailed { + // expect increased jail time + suite.Require().True( + info.JailedUntil.Equal(suite.consumerCtx().BlockTime().Add(consumerSlashingKeeper.DowntimeJailDuration(suite.consumerCtx()))), + "test: "+tc.name+"; did not update validator jailed until signing info", + ) + // expect missed block counters reset + suite.Require().Zero(info.MissedBlocksCounter, "test: "+tc.name+"; did not reset validator missed block counter") + suite.Require().Zero(info.IndexOffset, "test: "+tc.name) + consumerSlashingKeeper.IterateValidatorMissedBlockBitArray(suite.consumerCtx(), consAddr, func(_ int64, missed bool) bool { + suite.Require().True(missed, "test: "+tc.name) + return false + }) + } else { + suite.Require().True( + // expect not increased jail time + info.JailedUntil.Before(suite.consumerCtx().BlockTime()), + "test: "+tc.name+"; validator jailed until signing info was updated", + ) + suite.Require().Positive(info.IndexOffset, "test: "+tc.name) + } + + pendingPackets := consumerKeeper.GetPendingPackets(suite.consumerCtx()) + if tc.expSlashPacket { + // Check that slash packet is queued + suite.Require().NotEmpty(pendingPackets, "test: "+tc.name+"; pending packets empty") + suite.Require().Len(pendingPackets, 1, "test: "+tc.name+"; pending packets len should be 1 is %d", len(pendingPackets)) + cp := pendingPackets[0] + suite.Require().Equal(ccv.SlashPacket, cp.Type, "test: "+tc.name) + sp := cp.GetSlashPacketData() + suite.Require().Equal(stakingtypes.Infraction_INFRACTION_DOWNTIME, sp.Infraction, "test: "+tc.name) + suite.Require().Equal(vals[tc.targetValidator].Address, sp.Validator.Address, "test: "+tc.name) + } else { + suite.Require().Empty(pendingPackets, "test: "+tc.name+"; pending packets non-empty") + } + + if i+1 < len(testCases) { + // reset suite + suite.SetupTest() + } + } +} + +// slashingBeginBlocker is a mock for the slashing BeginBlocker. +// It applies the votes for a sequence of blocks +func slashingBeginBlocker(s *CCVTestSuite, votes []abci.VoteInfo, blocks int64) { + consumerSlashingKeeper := s.consumerApp.GetTestSlashingKeeper() + currentHeight := s.consumerCtx().BlockHeight() + for s.consumerCtx().BlockHeight() < currentHeight+blocks { + for _, voteInfo := range votes { + consumerSlashingKeeper.HandleValidatorSignature( + s.consumerCtx(), + voteInfo.Validator.Address, + voteInfo.Validator.Power, + voteInfo.SignedLastBlock, + ) + } + s.consumerChain.NextBlock() + } +} diff --git a/tests/mbt/driver/setup.go b/tests/mbt/driver/setup.go index 9bf6459bf9..a49a1ac000 100644 --- a/tests/mbt/driver/setup.go +++ b/tests/mbt/driver/setup.go @@ -488,6 +488,7 @@ func createConsumerGenesis(modelParams ModelParams, providerChain *ibctesting.Te ccvtypes.DefaultConsumerRedistributeFrac, ccvtypes.DefaultHistoricalEntries, modelParams.UnbondingPeriodPerChain[ChainId(consumerClientState.ChainId)], + "0", // disable soft opt-out []string{}, []string{}, ccvtypes.DefaultRetryDelayPeriod, diff --git a/testutil/integration/debug_test.go b/testutil/integration/debug_test.go index 08728819bd..d97c41f7d0 100644 --- a/testutil/integration/debug_test.go +++ b/testutil/integration/debug_test.go @@ -149,6 +149,14 @@ func TestCISBeforeCCVEstablished(t *testing.T) { runCCVTestByName(t, "TestCISBeforeCCVEstablished") } +// +// Soft opt out tests +// + +func TestSoftOptOut(t *testing.T) { + runCCVTestByName(t, "TestSoftOptOut") +} + // // Stop consumer tests // diff --git a/testutil/integration/interfaces.go b/testutil/integration/interfaces.go index 2c4e3f9e3d..5324449c9f 100644 --- a/testutil/integration/interfaces.go +++ b/testutil/integration/interfaces.go @@ -3,6 +3,7 @@ package integration import ( "time" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ibctesting "github.com/cosmos/ibc-go/v7/testing" "cosmossdk.io/math" @@ -17,7 +18,6 @@ import ( paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" "github.com/cosmos/cosmos-sdk/x/staking/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" abci "github.com/cometbft/cometbft/abci/types" diff --git a/x/ccv/consumer/keeper/params.go b/x/ccv/consumer/keeper/params.go index 8d74205b8a..4d96ddf604 100644 --- a/x/ccv/consumer/keeper/params.go +++ b/x/ccv/consumer/keeper/params.go @@ -22,6 +22,7 @@ func (k Keeper) GetConsumerParams(ctx sdk.Context) ccvtypes.ConsumerParams { k.GetConsumerRedistributionFrac(ctx), k.GetHistoricalEntries(ctx), k.GetUnbondingPeriod(ctx), + k.GetSoftOptOutThreshold(ctx), k.GetRewardDenoms(ctx), k.GetProviderRewardDenoms(ctx), k.GetRetryDelayPeriod(ctx), @@ -119,6 +120,14 @@ func (k Keeper) GetUnbondingPeriod(ctx sdk.Context) time.Duration { return period } +// GetSoftOptOutThreshold returns the percentage of validators at the bottom of the set +// that can opt out of running the consumer chain +func (k Keeper) GetSoftOptOutThreshold(ctx sdk.Context) string { + var str string + k.paramStore.Get(ctx, ccvtypes.KeySoftOptOutThreshold, &str) + return str +} + func (k Keeper) GetRewardDenoms(ctx sdk.Context) []string { var denoms []string k.paramStore.Get(ctx, ccvtypes.KeyRewardDenoms, &denoms) diff --git a/x/ccv/consumer/keeper/params_test.go b/x/ccv/consumer/keeper/params_test.go index 536ae98236..e2975a0b31 100644 --- a/x/ccv/consumer/keeper/params_test.go +++ b/x/ccv/consumer/keeper/params_test.go @@ -28,6 +28,7 @@ func TestParams(t *testing.T) { ccv.DefaultConsumerRedistributeFrac, ccv.DefaultHistoricalEntries, ccv.DefaultConsumerUnbondingPeriod, + ccv.DefaultSoftOptOutThreshold, rewardDenoms, provideRewardDenoms, ccv.DefaultRetryDelayPeriod, @@ -38,7 +39,7 @@ func TestParams(t *testing.T) { newParams := ccv.NewParams(false, 1000, "channel-2", "cosmos19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddwhu7lm", - 7*24*time.Hour, 25*time.Hour, "0.5", 500, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour) + 7*24*time.Hour, 25*time.Hour, "0.5", 500, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour) consumerKeeper.SetParams(ctx, newParams) params = consumerKeeper.GetConsumerParams(ctx) require.Equal(t, newParams, params) diff --git a/x/ccv/consumer/keeper/soft_opt_out.go b/x/ccv/consumer/keeper/soft_opt_out.go new file mode 100644 index 0000000000..9221cca851 --- /dev/null +++ b/x/ccv/consumer/keeper/soft_opt_out.go @@ -0,0 +1,118 @@ +package keeper + +import ( + "encoding/binary" + "sort" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/interchain-security/v4/x/ccv/consumer/types" +) + +// BeginBlockSoftOptOut executes BeginBlock logic for the Soft Opt-Out sub-protocol +func (k Keeper) BeginBlockSoftOptOut(ctx sdk.Context) { + // Update smallest validator power that cannot opt out. + k.UpdateSmallestNonOptOutPower(ctx) + + // Update the SigningInfo structs of the Slashing module + k.UpdateSlashingSigningInfo(ctx) +} + +// SetSmallestNonOptOutPower sets the smallest validator power that cannot soft opt out. +func (k Keeper) SetSmallestNonOptOutPower(ctx sdk.Context, power uint64) { + store := ctx.KVStore(k.storeKey) + store.Set(types.SmallestNonOptOutPowerKey(), sdk.Uint64ToBigEndian(power)) +} + +// UpdateSmallestNonOptOutPower updates the smallest validator power that cannot soft opt out. +// This is the smallest validator power such that the sum of the power of all validators with a lower power +// is less than [SoftOptOutThreshold] of the total power of all validators. +func (k Keeper) UpdateSmallestNonOptOutPower(ctx sdk.Context) { + // get soft opt-out threshold + optOutThreshold := sdk.MustNewDecFromStr(k.GetSoftOptOutThreshold(ctx)) + if optOutThreshold.IsZero() { + // If the SoftOptOutThreshold is zero, then soft opt-out is disable. + // Setting the smallest non-opt-out power to zero, fixes the diff-testing + // when soft opt-out is disable. + k.SetSmallestNonOptOutPower(ctx, uint64(0)) + return + } + + // get all validators + valset := k.GetAllCCValidator(ctx) + + // Valset should only be empty for hacky tests. Log error in case this ever happens in prod. + if len(valset) == 0 { + k.Logger(ctx).Error("UpdateSoftOptOutThresholdPower called with empty validator set") + return + } + + // sort validators by power ascending + sort.SliceStable(valset, func(i, j int) bool { + return valset[i].Power < valset[j].Power + }) + + // get total power in set + totalPower := sdk.ZeroDec() + for _, val := range valset { + totalPower = totalPower.Add(sdk.NewDec(val.Power)) + } + + // get power of the smallest validator that cannot soft opt out + powerSum := sdk.ZeroDec() + for _, val := range valset { + powerSum = powerSum.Add(sdk.NewDecFromInt(sdk.NewInt(val.Power))) + // if powerSum / totalPower > SoftOptOutThreshold + if powerSum.Quo(totalPower).GT(optOutThreshold) { + // set smallest non opt out power + k.SetSmallestNonOptOutPower(ctx, uint64(val.Power)) + k.Logger(ctx).Info("smallest non opt out power updated", "power", val.Power) + return + } + } + panic("UpdateSoftOptOutThresholdPower should not reach this point. Incorrect logic!") +} + +// GetSmallestNonOptOutPower returns the smallest validator power that cannot soft opt out. +func (k Keeper) GetSmallestNonOptOutPower(ctx sdk.Context) int64 { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.SmallestNonOptOutPowerKey()) + if bz == nil { + return 0 + } + return int64(binary.BigEndian.Uint64(bz)) +} + +func (k Keeper) UpdateSlashingSigningInfo(ctx sdk.Context) { + smallestNonOptOutPower := k.GetSmallestNonOptOutPower(ctx) + + // Update SigningInfo for opted out validators + valset := k.GetAllCCValidator(ctx) + // Note that we don't need to sort the valset as GetAllCCValidator + // uses KVStorePrefixIterator that iterates over all the keys with + // a certain prefix in ascending order + for _, val := range valset { + consAddr := sdk.ConsAddress(val.Address) + signingInfo, found := k.slashingKeeper.GetValidatorSigningInfo(ctx, consAddr) + if !found { + continue + } + if val.Power < smallestNonOptOutPower { + // validator CAN opt-out from validating on consumer chains + if !val.OptedOut { + // previously the validator couldn't opt-out + val.OptedOut = true + } + } else { + // validator CANNOT opt-out from validating on consumer chains + if val.OptedOut { + // previously the validator could opt-out + signingInfo.StartHeight = ctx.BlockHeight() + val.OptedOut = false + } + } + + k.slashingKeeper.SetValidatorSigningInfo(ctx, consAddr, signingInfo) + k.SetCCValidator(ctx, val) + } +} diff --git a/x/ccv/consumer/keeper/soft_opt_out_test.go b/x/ccv/consumer/keeper/soft_opt_out_test.go new file mode 100644 index 0000000000..1a726d1767 --- /dev/null +++ b/x/ccv/consumer/keeper/soft_opt_out_test.go @@ -0,0 +1,120 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + tmtypes "github.com/cometbft/cometbft/types" + + "github.com/cosmos/interchain-security/v4/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" + ccvtypes "github.com/cosmos/interchain-security/v4/x/ccv/types" +) + +// Tests that UpdateSmallestNonOptOutPower updates the smallest validator power that cannot soft opt out. +// Soft opt out allows the bottom [SoftOptOutThreshold] portion of validators in the set to opt out. +// UpdateSmallestNonOptOutPower should update the smallest validator power that cannot opt out. +func TestUpdateSmallestNonOptOutPower(t *testing.T) { + cIds := crypto.GenMultipleCryptoIds(7, 682934679238) + + testCases := []struct { + name string + // soft opt out threshold set as param + optOutThresh string + // validators to set in store + validators []*tmtypes.Validator + // expected smallest power of validator which cannot opt out + expSmallestNonOptOutValPower int64 + }{ + { + name: "One", + optOutThresh: "0.05", + validators: []*tmtypes.Validator{ + tmtypes.NewValidator(cIds[0].TMCryptoPubKey(), 1), + tmtypes.NewValidator(cIds[1].TMCryptoPubKey(), 1), + tmtypes.NewValidator(cIds[2].TMCryptoPubKey(), 1), + tmtypes.NewValidator(cIds[3].TMCryptoPubKey(), 3), + tmtypes.NewValidator(cIds[4].TMCryptoPubKey(), 49), + tmtypes.NewValidator(cIds[5].TMCryptoPubKey(), 51), + }, + // 107 total power, validator with 3 power passes 0.05 threshold (6 / 107 = 0.056) and cannot opt out + expSmallestNonOptOutValPower: 3, + }, + { + name: "One in different order", + optOutThresh: "0.05", + validators: []*tmtypes.Validator{ + tmtypes.NewValidator(cIds[0].TMCryptoPubKey(), 3), + tmtypes.NewValidator(cIds[1].TMCryptoPubKey(), 51), + tmtypes.NewValidator(cIds[2].TMCryptoPubKey(), 1), + tmtypes.NewValidator(cIds[3].TMCryptoPubKey(), 49), + tmtypes.NewValidator(cIds[4].TMCryptoPubKey(), 1), + tmtypes.NewValidator(cIds[5].TMCryptoPubKey(), 1), + }, + // Same result as first test case, just confirms order of validators doesn't matter + expSmallestNonOptOutValPower: 3, + }, + { + name: "Two", + optOutThresh: "0.05", + validators: []*tmtypes.Validator{ + tmtypes.NewValidator(cIds[0].TMCryptoPubKey(), 1), + tmtypes.NewValidator(cIds[1].TMCryptoPubKey(), 1), + tmtypes.NewValidator(cIds[2].TMCryptoPubKey(), 1), + tmtypes.NewValidator(cIds[3].TMCryptoPubKey(), 3), + tmtypes.NewValidator(cIds[4].TMCryptoPubKey(), 500), + }, + // 506 total power, validator with 500 passes 0.05 threshold and cannot opt out + expSmallestNonOptOutValPower: 500, + }, + { + name: "Three", + optOutThresh: "0.199999", + validators: []*tmtypes.Validator{ + tmtypes.NewValidator(cIds[0].TMCryptoPubKey(), 54), + tmtypes.NewValidator(cIds[1].TMCryptoPubKey(), 53), + tmtypes.NewValidator(cIds[2].TMCryptoPubKey(), 52), + tmtypes.NewValidator(cIds[3].TMCryptoPubKey(), 51), + tmtypes.NewValidator(cIds[4].TMCryptoPubKey(), 50), + tmtypes.NewValidator(cIds[5].TMCryptoPubKey(), 1), + tmtypes.NewValidator(cIds[6].TMCryptoPubKey(), 1), + }, + // 262 total power, (50 + 1 + 1) / 262 ~= 0.19, validator with 51 passes 0.199999 threshold and cannot opt out + expSmallestNonOptOutValPower: 51, + }, + { + name: "soft opt-out disabled", + optOutThresh: "0", + validators: []*tmtypes.Validator{ + tmtypes.NewValidator(cIds[0].TMCryptoPubKey(), 54), + tmtypes.NewValidator(cIds[1].TMCryptoPubKey(), 53), + tmtypes.NewValidator(cIds[2].TMCryptoPubKey(), 52), + tmtypes.NewValidator(cIds[3].TMCryptoPubKey(), 51), + tmtypes.NewValidator(cIds[4].TMCryptoPubKey(), 50), + tmtypes.NewValidator(cIds[5].TMCryptoPubKey(), 1), + tmtypes.NewValidator(cIds[6].TMCryptoPubKey(), 1), + }, + expSmallestNonOptOutValPower: 0, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + consumerKeeper, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + moduleParams := ccvtypes.DefaultParams() + moduleParams.SoftOptOutThreshold = tc.optOutThresh + consumerKeeper.SetParams(ctx, moduleParams) + defer ctrl.Finish() + + // set validators in store + SetCCValidators(t, consumerKeeper, ctx, tc.validators) + + // update smallest power of validator which cannot opt out + consumerKeeper.UpdateSmallestNonOptOutPower(ctx) + + // expect smallest power of validator which cannot opt out to be updated + require.Equal(t, tc.expSmallestNonOptOutValPower, consumerKeeper.GetSmallestNonOptOutPower(ctx)) + }) + } +} diff --git a/x/ccv/consumer/keeper/validators.go b/x/ccv/consumer/keeper/validators.go index 27aefe4a44..504a8cd075 100644 --- a/x/ccv/consumer/keeper/validators.go +++ b/x/ccv/consumer/keeper/validators.go @@ -136,6 +136,18 @@ func (k Keeper) SlashWithInfractionReason(ctx sdk.Context, addr sdk.ConsAddress, // Otherwise infraction happened after the changeover was completed. + // if this is a downtime infraction and the validator is allowed to + // soft opt out, do not queue a slash packet + if infraction == stakingtypes.Infraction_INFRACTION_DOWNTIME { + if power < k.GetSmallestNonOptOutPower(ctx) { + // soft opt out + k.Logger(ctx).Debug("soft opt out", + "validator", addr, + "power", power, + ) + return math.NewInt(0) + } + } // get VSC ID for infraction height vscID := k.GetHeightValsetUpdateID(ctx, uint64(infractionHeight)) diff --git a/x/ccv/consumer/module.go b/x/ccv/consumer/module.go index 1896728085..4b5d9c053b 100644 --- a/x/ccv/consumer/module.go +++ b/x/ccv/consumer/module.go @@ -138,6 +138,9 @@ func (AppModule) ConsensusVersion() uint64 { // Set the VSC ID for the subsequent block to the same value as the current block // Panic if the provider's channel was established and then closed func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { + // Execute BeginBlock logic for the Soft Opt-Out sub-protocol + am.keeper.BeginBlockSoftOptOut(ctx) + channelID, found := am.keeper.GetProviderChannel(ctx) if found && am.keeper.IsChannelClosed(ctx, channelID) { // The CCV channel was established, but it was then closed; diff --git a/x/ccv/consumer/types/consumer.pb.go b/x/ccv/consumer/types/consumer.pb.go index 621801a57e..ab52b3a8a7 100644 --- a/x/ccv/consumer/types/consumer.pb.go +++ b/x/ccv/consumer/types/consumer.pb.go @@ -39,10 +39,8 @@ type CrossChainValidator struct { Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` Power int64 `protobuf:"varint,2,opt,name=power,proto3" json:"power,omitempty"` // pubkey is the consensus public key of the validator, as a Protobuf Any. - Pubkey *types.Any `protobuf:"bytes,3,opt,name=pubkey,proto3" json:"pubkey,omitempty" yaml:"consensus_pubkey"` - // !!! DEPRECATED !!! opted_out is deprecated because after the introduction of Partial Set Security (PSS) - // we removed the soft opt-out feature. - OptedOut bool `protobuf:"varint,4,opt,name=opted_out,json=optedOut,proto3" json:"opted_out,omitempty"` // Deprecated: Do not use. + Pubkey *types.Any `protobuf:"bytes,3,opt,name=pubkey,proto3" json:"pubkey,omitempty" yaml:"consensus_pubkey"` + OptedOut bool `protobuf:"varint,4,opt,name=opted_out,json=optedOut,proto3" json:"opted_out,omitempty"` } func (m *CrossChainValidator) Reset() { *m = CrossChainValidator{} } @@ -99,7 +97,6 @@ func (m *CrossChainValidator) GetPubkey() *types.Any { return nil } -// Deprecated: Do not use. func (m *CrossChainValidator) GetOptedOut() bool { if m != nil { return m.OptedOut @@ -173,35 +170,35 @@ func init() { } var fileDescriptor_5b27a82b276e7f93 = []byte{ - // 435 bytes of a gzipped FileDescriptorProto + // 434 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x52, 0xcd, 0x6e, 0xd3, 0x40, - 0x10, 0xce, 0xb6, 0x50, 0xdc, 0x0d, 0x42, 0xc8, 0x44, 0xc2, 0xcd, 0xc1, 0x8e, 0xc2, 0xc5, 0x97, + 0x10, 0xce, 0x52, 0x28, 0xee, 0x06, 0x21, 0x64, 0x22, 0xe1, 0x06, 0xc9, 0x89, 0xcc, 0xc5, 0x97, 0xda, 0x6a, 0xca, 0x09, 0x89, 0x43, 0xd3, 0x23, 0x87, 0x22, 0x83, 0x40, 0xe2, 0x62, 0xad, 0xd7, - 0x8b, 0x63, 0x61, 0xef, 0xac, 0xf6, 0xc7, 0x65, 0x79, 0x8a, 0x3e, 0x0c, 0x0f, 0x51, 0x38, 0xf5, - 0xc8, 0xa9, 0xa0, 0xe4, 0x0d, 0x78, 0x02, 0xe4, 0x9f, 0x04, 0xf1, 0x73, 0x9b, 0xf9, 0x66, 0xbf, - 0x99, 0x6f, 0x66, 0x3f, 0xbc, 0x28, 0xb9, 0x66, 0x92, 0xae, 0x48, 0xc9, 0x53, 0xc5, 0xa8, 0x91, - 0xa5, 0xb6, 0x31, 0xa5, 0x4d, 0x4c, 0x81, 0x2b, 0x53, 0x33, 0x19, 0x37, 0x27, 0xbb, 0x38, 0x12, - 0x12, 0x34, 0xb8, 0x4f, 0xfe, 0xc3, 0x89, 0x28, 0x6d, 0xa2, 0xdd, 0xbb, 0xe6, 0x64, 0x7a, 0x54, - 0x00, 0x14, 0x15, 0x8b, 0x3b, 0x4a, 0x66, 0xde, 0xc7, 0x84, 0xdb, 0x9e, 0x3f, 0x9d, 0x14, 0x50, - 0x40, 0x17, 0xc6, 0x6d, 0x34, 0xa0, 0x47, 0x14, 0x54, 0x0d, 0x2a, 0xed, 0x0b, 0x7d, 0x32, 0x94, - 0x82, 0xbf, 0x7b, 0xe9, 0xb2, 0x66, 0x4a, 0x93, 0x5a, 0xf4, 0x0f, 0xe6, 0x5f, 0x10, 0x7e, 0x74, - 0x2e, 0x41, 0xa9, 0xf3, 0x56, 0xd4, 0x1b, 0x52, 0x95, 0x39, 0xd1, 0x20, 0x5d, 0x0f, 0xdf, 0x23, - 0x79, 0x2e, 0x99, 0x52, 0x1e, 0x9a, 0xa1, 0xf0, 0x7e, 0xb2, 0x4d, 0xdd, 0x09, 0xbe, 0x2b, 0xe0, - 0x92, 0x49, 0x6f, 0x6f, 0x86, 0xc2, 0xfd, 0xa4, 0x4f, 0x5c, 0x82, 0x0f, 0x84, 0xc9, 0x3e, 0x30, - 0xeb, 0xed, 0xcf, 0x50, 0x38, 0x5e, 0x4c, 0xa2, 0x7e, 0x72, 0xb4, 0x9d, 0x1c, 0x9d, 0x71, 0xbb, - 0x3c, 0xfd, 0x79, 0x1b, 0x3c, 0xb6, 0xa4, 0xae, 0x9e, 0xcd, 0xdb, 0x8d, 0x19, 0x57, 0x46, 0xa5, - 0x3d, 0x6f, 0xfe, 0xf5, 0xf3, 0xf1, 0x64, 0xd0, 0x4e, 0xa5, 0x15, 0x1a, 0xa2, 0x97, 0x26, 0x7b, - 0xc1, 0x6c, 0x32, 0x34, 0x76, 0x03, 0x7c, 0x08, 0x42, 0xb3, 0x3c, 0x05, 0xa3, 0xbd, 0x3b, 0x33, - 0x14, 0x3a, 0xcb, 0x3d, 0x0f, 0x25, 0x4e, 0x07, 0x5e, 0x18, 0x3d, 0xff, 0x84, 0xc7, 0xaf, 0x2a, - 0xa2, 0x56, 0x09, 0xa3, 0x20, 0x73, 0x37, 0xc4, 0x0f, 0x2f, 0x49, 0xa9, 0x4b, 0x5e, 0xa4, 0xc0, - 0x53, 0xc9, 0x44, 0x65, 0xbb, 0x5d, 0x9c, 0xe4, 0xc1, 0x80, 0x5f, 0xf0, 0xa4, 0x45, 0xdd, 0x33, - 0x7c, 0xa8, 0x18, 0xcf, 0xd3, 0xf6, 0x38, 0xdd, 0x5a, 0xe3, 0xc5, 0xf4, 0x1f, 0xfd, 0xaf, 0xb7, - 0x97, 0x5b, 0x3a, 0xd7, 0xb7, 0xc1, 0xe8, 0xea, 0x7b, 0x80, 0x12, 0xa7, 0xa5, 0xb5, 0x85, 0xe5, - 0xdb, 0xeb, 0xb5, 0x8f, 0x6e, 0xd6, 0x3e, 0xfa, 0xb1, 0xf6, 0xd1, 0xd5, 0xc6, 0x1f, 0xdd, 0x6c, - 0xfc, 0xd1, 0xb7, 0x8d, 0x3f, 0x7a, 0xf7, 0xbc, 0x28, 0xf5, 0xca, 0x64, 0x11, 0x85, 0x7a, 0xf8, - 0x9b, 0xf8, 0xb7, 0x0b, 0x8e, 0x77, 0xce, 0x69, 0x9e, 0xc6, 0x1f, 0xff, 0xb4, 0x8f, 0xb6, 0x82, - 0xa9, 0xec, 0xa0, 0x13, 0x70, 0xfa, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x8b, 0x7c, 0x38, 0x7e, 0x6f, - 0x02, 0x00, 0x00, + 0x8b, 0x63, 0x61, 0xef, 0xac, 0xf6, 0xc7, 0x65, 0x79, 0x8a, 0x3e, 0x0c, 0xaf, 0x80, 0x54, 0x71, + 0xea, 0x91, 0x53, 0x41, 0xc9, 0x1b, 0xf0, 0x04, 0xc8, 0x3f, 0x09, 0xe2, 0xe7, 0x36, 0xf3, 0xcd, + 0x7e, 0x33, 0xdf, 0xcc, 0x7e, 0x78, 0x51, 0x72, 0xcd, 0x24, 0x5d, 0x91, 0x92, 0xa7, 0x8a, 0x51, + 0x23, 0x4b, 0x6d, 0x63, 0x4a, 0x9b, 0x98, 0x02, 0x57, 0xa6, 0x66, 0x32, 0x6e, 0x8e, 0x77, 0x71, + 0x24, 0x24, 0x68, 0x70, 0x9f, 0xfc, 0x87, 0x13, 0x51, 0xda, 0x44, 0xbb, 0x77, 0xcd, 0xf1, 0xf4, + 0xb0, 0x00, 0x28, 0x2a, 0x16, 0x77, 0x94, 0xcc, 0xbc, 0x8f, 0x09, 0xb7, 0x3d, 0x7f, 0x3a, 0x29, + 0xa0, 0x80, 0x2e, 0x8c, 0xdb, 0x68, 0x40, 0x0f, 0x29, 0xa8, 0x1a, 0x54, 0xda, 0x17, 0xfa, 0x64, + 0x28, 0xcd, 0xfe, 0xee, 0xa5, 0xcb, 0x9a, 0x29, 0x4d, 0x6a, 0xd1, 0x3f, 0x08, 0xbe, 0x20, 0xfc, + 0xf0, 0x4c, 0x82, 0x52, 0x67, 0xad, 0xa8, 0x37, 0xa4, 0x2a, 0x73, 0xa2, 0x41, 0xba, 0x1e, 0xbe, + 0x4b, 0xf2, 0x5c, 0x32, 0xa5, 0x3c, 0x34, 0x47, 0xe1, 0xbd, 0x64, 0x9b, 0xba, 0x13, 0x7c, 0x47, + 0xc0, 0x05, 0x93, 0xde, 0xad, 0x39, 0x0a, 0xf7, 0x92, 0x3e, 0x71, 0x09, 0xde, 0x17, 0x26, 0xfb, + 0xc0, 0xac, 0xb7, 0x37, 0x47, 0xe1, 0x78, 0x31, 0x89, 0xfa, 0xc9, 0xd1, 0x76, 0x72, 0x74, 0xca, + 0xed, 0xf2, 0xe4, 0xe7, 0xcd, 0xec, 0x91, 0x25, 0x75, 0xf5, 0x2c, 0x68, 0x37, 0x66, 0x5c, 0x19, + 0x95, 0xf6, 0xbc, 0xe0, 0xeb, 0xe7, 0xa3, 0xc9, 0xa0, 0x9d, 0x4a, 0x2b, 0x34, 0x44, 0x2f, 0x4d, + 0xf6, 0x82, 0xd9, 0x64, 0x68, 0xec, 0x3e, 0xc6, 0x07, 0x20, 0x34, 0xcb, 0x53, 0x30, 0xda, 0xbb, + 0x3d, 0x47, 0xa1, 0x93, 0x38, 0x1d, 0x70, 0x6e, 0x74, 0xf0, 0x09, 0x8f, 0x5f, 0x55, 0x44, 0xad, + 0x12, 0x46, 0x41, 0xe6, 0x6e, 0x88, 0x1f, 0x5c, 0x90, 0x52, 0x97, 0xbc, 0x48, 0x81, 0xa7, 0x92, + 0x89, 0xca, 0x76, 0x7b, 0x38, 0xc9, 0xfd, 0x01, 0x3f, 0xe7, 0x49, 0x8b, 0xba, 0xa7, 0xf8, 0x40, + 0x31, 0x9e, 0xa7, 0xed, 0x61, 0xba, 0x95, 0xc6, 0x8b, 0xe9, 0x3f, 0xda, 0x5f, 0x6f, 0xaf, 0xb6, + 0x74, 0xae, 0x6e, 0x66, 0xa3, 0xcb, 0xef, 0x33, 0x94, 0x38, 0x2d, 0xad, 0x2d, 0x2c, 0xdf, 0x5e, + 0xad, 0x7d, 0x74, 0xbd, 0xf6, 0xd1, 0x8f, 0xb5, 0x8f, 0x2e, 0x37, 0xfe, 0xe8, 0x7a, 0xe3, 0x8f, + 0xbe, 0x6d, 0xfc, 0xd1, 0xbb, 0xe7, 0x45, 0xa9, 0x57, 0x26, 0x8b, 0x28, 0xd4, 0xc3, 0xbf, 0xc4, + 0xbf, 0x1d, 0x70, 0xb4, 0x73, 0x4d, 0xf3, 0x34, 0xfe, 0xf8, 0xa7, 0x75, 0xb4, 0x15, 0x4c, 0x65, + 0xfb, 0x9d, 0x80, 0x93, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x20, 0xf1, 0xa5, 0x1e, 0x6b, 0x02, + 0x00, 0x00, } func (m *CrossChainValidator) Marshal() (dAtA []byte, err error) { diff --git a/x/ccv/consumer/types/genesis_test.go b/x/ccv/consumer/types/genesis_test.go index c8c61776ec..dcd30b642c 100644 --- a/x/ccv/consumer/types/genesis_test.go +++ b/x/ccv/consumer/types/genesis_test.go @@ -230,6 +230,7 @@ func TestValidateInitialGenesisState(t *testing.T) { ccv.DefaultConsumerRedistributeFrac, ccv.DefaultHistoricalEntries, ccv.DefaultConsumerUnbondingPeriod, + ccv.DefaultSoftOptOutThreshold, []string{}, []string{}, ccv.DefaultRetryDelayPeriod, @@ -249,6 +250,7 @@ func TestValidateInitialGenesisState(t *testing.T) { ccv.DefaultConsumerRedistributeFrac, ccv.DefaultHistoricalEntries, ccv.DefaultConsumerUnbondingPeriod, + ccv.DefaultSoftOptOutThreshold, []string{}, []string{}, ccv.DefaultRetryDelayPeriod, @@ -454,6 +456,7 @@ func TestValidateRestartConsumerGenesisState(t *testing.T) { ccv.DefaultConsumerRedistributeFrac, ccv.DefaultHistoricalEntries, ccv.DefaultConsumerUnbondingPeriod, + ccv.DefaultSoftOptOutThreshold, []string{}, []string{}, ccv.DefaultRetryDelayPeriod, diff --git a/x/ccv/consumer/types/keys.go b/x/ccv/consumer/types/keys.go index 5fcd26a1ca..20163f5ed9 100644 --- a/x/ccv/consumer/types/keys.go +++ b/x/ccv/consumer/types/keys.go @@ -65,9 +65,8 @@ const ( // [DEPRECATED] LastStandaloneHeightByteKey - // NOTE: This key is deprecated, but left in place to avoid consumer state migrations - // [DEPRECATED] - DeprecatedSmallestNonOptOutPowerByteKey + // SmallestNonOptOutPowerByteKey is the byte that will store the smallest val power that cannot opt out + SmallestNonOptOutPowerByteKey // HistoricalInfoKey is the byte prefix that will store the historical info for a given height HistoricalInfoBytePrefix @@ -202,6 +201,10 @@ func InitGenesisHeightKey() []byte { return []byte{InitGenesisHeightByteKey} } +func SmallestNonOptOutPowerKey() []byte { + return []byte{SmallestNonOptOutPowerByteKey} +} + // StandaloneTransferChannelIDKey returns the key to the transfer channelID that existed from a standalone chain // changing over to a consumer func StandaloneTransferChannelIDKey() []byte { diff --git a/x/ccv/consumer/types/keys_test.go b/x/ccv/consumer/types/keys_test.go index 66880b2ae9..a8cebee284 100644 --- a/x/ccv/consumer/types/keys_test.go +++ b/x/ccv/consumer/types/keys_test.go @@ -31,7 +31,7 @@ func getAllKeyPrefixes() []byte { PreCCVByteKey, InitialValSetByteKey, LastStandaloneHeightByteKey, - DeprecatedSmallestNonOptOutPowerByteKey, + SmallestNonOptOutPowerByteKey, HistoricalInfoBytePrefix, PacketMaturityTimeBytePrefix, HeightValsetUpdateIDBytePrefix, @@ -68,7 +68,8 @@ func getAllFullyDefinedKeys() [][]byte { // PendingDataPacketsKey() does not use duplicated prefix with value of 0x06 PreCCVKey(), InitialValSetKey(), - // LastStandaloneHeightKey() is deprecated + // LastStandaloneHeightKey() is depreciated + SmallestNonOptOutPowerKey(), HistoricalInfoKey(0), PacketMaturityTimeKey(0, time.Time{}), HeightValsetUpdateIDKey(0), diff --git a/x/ccv/consumer/types/params_test.go b/x/ccv/consumer/types/params_test.go index 8e81e2301c..5b11b52d43 100644 --- a/x/ccv/consumer/types/params_test.go +++ b/x/ccv/consumer/types/params_test.go @@ -19,59 +19,67 @@ func TestValidateParams(t *testing.T) { {"default params", ccvtypes.DefaultParams(), true}, { "custom valid params", - ccvtypes.NewParams(true, 5, "", "", 1004, 1005, "0.5", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), true, + ccvtypes.NewParams(true, 5, "", "", 1004, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), true, }, { "custom invalid params, block per dist transmission", - ccvtypes.NewParams(true, -5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, -5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, dist transmission channel", - ccvtypes.NewParams(true, 5, "badchannel/", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "badchannel/", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, ccv timeout", - ccvtypes.NewParams(true, 5, "", "", -5, 1005, "0.5", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", -5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, transfer timeout", - ccvtypes.NewParams(true, 5, "", "", 1004, -7, "0.5", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 1004, -7, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, consumer redist fraction is negative", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "-0.5", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "-0.5", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, consumer redist fraction is over 1", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "1.2", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "1.2", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, bad consumer redist fraction ", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "notFrac", 1000, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "notFrac", 1000, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, negative num historical entries", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", -100, 24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", -100, 24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, }, { "custom invalid params, negative unbonding period", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, -24*21*time.Hour, []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, -24*21*time.Hour, "0.05", []string{"untrn"}, []string{"uatom"}, 2*time.Hour), false, + }, + { + "custom invalid params, invalid soft opt out threshold", + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "-0.05", []string{"u"}, []string{}, 2*time.Hour), false, + }, + { + "custom invalid params, invalid soft opt out threshold", + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.5", []string{"u"}, []string{}, 2*time.Hour), false, }, { "custom invalid params, invalid reward denom", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, []string{"u"}, []string{}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{"u"}, []string{}, 2*time.Hour), false, }, { "custom invalid params, invalid provider reward denom", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, []string{}, []string{"a"}, 2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{}, []string{"a"}, 2*time.Hour), false, }, { "custom invalid params, retry delay period is negative", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, []string{}, []string{}, -2*time.Hour), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{}, []string{}, -2*time.Hour), false, }, { "custom invalid params, retry delay period is zero", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, []string{}, []string{}, 0), false, + ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.05", []string{}, []string{}, 0), false, }, } diff --git a/x/ccv/consumer/types/validator.go b/x/ccv/consumer/types/validator.go index b134dde078..f1f9fa260b 100644 --- a/x/ccv/consumer/types/validator.go +++ b/x/ccv/consumer/types/validator.go @@ -15,9 +15,10 @@ func NewCCValidator(address []byte, power int64, pubKey cryptotypes.PubKey) (Cro } return CrossChainValidator{ - Address: address, - Power: power, - Pubkey: pkAny, + Address: address, + Power: power, + Pubkey: pkAny, + OptedOut: false, }, nil } diff --git a/x/ccv/provider/keeper/grpc_query_test.go b/x/ccv/provider/keeper/grpc_query_test.go index c5b22ecc5f..befc84a8ea 100644 --- a/x/ccv/provider/keeper/grpc_query_test.go +++ b/x/ccv/provider/keeper/grpc_query_test.go @@ -5,13 +5,13 @@ import ( "testing" "time" + "github.com/cometbft/cometbft/proto/tendermint/crypto" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" sdktypes "github.com/cosmos/cosmos-sdk/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - - "github.com/cometbft/cometbft/proto/tendermint/crypto" cryptotestutil "github.com/cosmos/interchain-security/v4/testutil/crypto" testkeeper "github.com/cosmos/interchain-security/v4/testutil/keeper" diff --git a/x/ccv/provider/keeper/proposal.go b/x/ccv/provider/keeper/proposal.go index dc769b152e..ba40bacd60 100644 --- a/x/ccv/provider/keeper/proposal.go +++ b/x/ccv/provider/keeper/proposal.go @@ -355,6 +355,7 @@ func (k Keeper) MakeConsumerGenesis( prop.ConsumerRedistributionFraction, prop.HistoricalEntries, prop.UnbondingPeriod, + "0.05", []string{}, []string{}, ccv.DefaultRetryDelayPeriod, diff --git a/x/ccv/provider/keeper/proposal_test.go b/x/ccv/provider/keeper/proposal_test.go index 18257a508a..09942f82f1 100644 --- a/x/ccv/provider/keeper/proposal_test.go +++ b/x/ccv/provider/keeper/proposal_test.go @@ -7,6 +7,8 @@ import ( "testing" "time" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" _go "github.com/cosmos/ics23/go" @@ -14,7 +16,6 @@ import ( "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" abci "github.com/cometbft/cometbft/abci/types" @@ -877,7 +878,7 @@ func TestMakeConsumerGenesis(t *testing.T) { "consumer_redistribution_fraction": "0.75", "historical_entries": 10000, "unbonding_period": 1728000000000000, - "soft_opt_out_threshold": "0", + "soft_opt_out_threshold": "0.05", "reward_denoms": [], "provider_reward_denoms": [], "retry_delay_period": 3600000000000 diff --git a/x/ccv/provider/proposal_handler_test.go b/x/ccv/provider/proposal_handler_test.go index d4e6195b8a..cd4395e38d 100644 --- a/x/ccv/provider/proposal_handler_test.go +++ b/x/ccv/provider/proposal_handler_test.go @@ -4,11 +4,11 @@ import ( "testing" "time" + sdk "github.com/cosmos/cosmos-sdk/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" - sdk "github.com/cosmos/cosmos-sdk/types" distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" diff --git a/x/ccv/provider/types/proposal.go b/x/ccv/provider/types/proposal.go index 780fda5c44..97b9bd158f 100644 --- a/x/ccv/provider/types/proposal.go +++ b/x/ccv/provider/types/proposal.go @@ -96,7 +96,7 @@ func (cccp *ConsumerAdditionProposal) ProposalType() string { } // ValidatePSSFeatures returns an error if the `topN` and `validatorsPowerCap` parameters are no in the correct ranges -func ValidatePSSFeatures(topN, validatorsPowerCap uint32) error { +func ValidatePSSFeatures(topN uint32, validatorsPowerCap uint32) error { // Top N corresponds to the top N% of validators that have to validate the consumer chain and can only be 0 (for an // Opt In chain) or in the range [50, 100] (for a Top N chain). if topN != 0 && (topN < 50 || topN > 100) { diff --git a/x/ccv/types/params.go b/x/ccv/types/params.go index 5759ce28f9..c80e353d66 100644 --- a/x/ccv/types/params.go +++ b/x/ccv/types/params.go @@ -37,6 +37,9 @@ const ( // the staking module default. DefaultConsumerUnbondingPeriod = stakingtypes.DefaultUnbondingTime - 7*24*time.Hour + // By default, the bottom 5% of the validator set can opt out of validating consumer chains + DefaultSoftOptOutThreshold = "0.05" + // Default retry delay period is 1 hour. DefaultRetryDelayPeriod = time.Hour ) @@ -51,6 +54,7 @@ var ( KeyConsumerRedistributionFrac = []byte("ConsumerRedistributionFraction") KeyHistoricalEntries = []byte("HistoricalEntries") KeyConsumerUnbondingPeriod = []byte("UnbondingPeriod") + KeySoftOptOutThreshold = []byte("SoftOptOutThreshold") KeyRewardDenoms = []byte("RewardDenoms") KeyProviderRewardDenoms = []byte("ProviderRewardDenoms") KeyRetryDelayPeriod = []byte("RetryDelayPeriod") @@ -66,7 +70,7 @@ func NewParams(enabled bool, blocksPerDistributionTransmission int64, distributionTransmissionChannel, providerFeePoolAddrStr string, ccvTimeoutPeriod, transferTimeoutPeriod time.Duration, consumerRedistributionFraction string, historicalEntries int64, - consumerUnbondingPeriod time.Duration, + consumerUnbondingPeriod time.Duration, softOptOutThreshold string, rewardDenoms, providerRewardDenoms []string, retryDelayPeriod time.Duration, ) ConsumerParams { return ConsumerParams{ @@ -79,11 +83,10 @@ func NewParams(enabled bool, blocksPerDistributionTransmission int64, ConsumerRedistributionFraction: consumerRedistributionFraction, HistoricalEntries: historicalEntries, UnbondingPeriod: consumerUnbondingPeriod, - // DEPRECATED but setting here to 0 (i.e., disabled) for older versions of interchain-security - SoftOptOutThreshold: "0", - RewardDenoms: rewardDenoms, - ProviderRewardDenoms: providerRewardDenoms, - RetryDelayPeriod: retryDelayPeriod, + SoftOptOutThreshold: softOptOutThreshold, + RewardDenoms: rewardDenoms, + ProviderRewardDenoms: providerRewardDenoms, + RetryDelayPeriod: retryDelayPeriod, } } @@ -101,6 +104,7 @@ func DefaultParams() ConsumerParams { DefaultConsumerRedistributeFrac, DefaultHistoricalEntries, DefaultConsumerUnbondingPeriod, + DefaultSoftOptOutThreshold, rewardDenoms, provideRewardDenoms, DefaultRetryDelayPeriod, @@ -136,6 +140,9 @@ func (p ConsumerParams) Validate() error { if err := ValidateDuration(p.UnbondingPeriod); err != nil { return err } + if err := ValidateSoftOptOutThreshold(p.SoftOptOutThreshold); err != nil { + return err + } if err := ValidateDenoms(p.RewardDenoms); err != nil { return err } @@ -168,6 +175,8 @@ func (p *ConsumerParams) ParamSetPairs() paramtypes.ParamSetPairs { p.HistoricalEntries, ValidatePositiveInt64), paramtypes.NewParamSetPair(KeyConsumerUnbondingPeriod, p.UnbondingPeriod, ValidateDuration), + paramtypes.NewParamSetPair(KeySoftOptOutThreshold, + p.SoftOptOutThreshold, ValidateSoftOptOutThreshold), paramtypes.NewParamSetPair(KeyRewardDenoms, p.RewardDenoms, ValidateDenoms), paramtypes.NewParamSetPair(KeyProviderRewardDenoms, @@ -186,6 +195,24 @@ func ValidateProviderFeePoolAddrStr(i interface{}) error { return nil } +func ValidateSoftOptOutThreshold(i interface{}) error { + str, ok := i.(string) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + dec, err := sdktypes.NewDecFromStr(str) + if err != nil { + return err + } + if dec.IsNegative() { + return fmt.Errorf("soft opt out threshold cannot be negative, got %s", str) + } + if !dec.Sub(sdktypes.MustNewDecFromStr("0.2")).IsNegative() { + return fmt.Errorf("soft opt out threshold cannot be greater than 0.2, got %s", str) + } + return nil +} + func ValidateDenoms(i interface{}) error { v, ok := i.([]string) if !ok { diff --git a/x/ccv/types/shared_consumer.pb.go b/x/ccv/types/shared_consumer.pb.go index 92d7105d41..95050192b8 100644 --- a/x/ccv/types/shared_consumer.pb.go +++ b/x/ccv/types/shared_consumer.pb.go @@ -65,8 +65,11 @@ type ConsumerParams struct { // Unbonding period for the consumer, // which should be smaller than that of the provider in general. UnbondingPeriod time.Duration `protobuf:"bytes,9,opt,name=unbonding_period,json=unbondingPeriod,proto3,stdduration" json:"unbonding_period"` - // !!! DEPRECATED !!! soft_opt_out_threshold is deprecated. see docs/docs/adrs/adr-015-partial-set-security.md - SoftOptOutThreshold string `protobuf:"bytes,10,opt,name=soft_opt_out_threshold,json=softOptOutThreshold,proto3" json:"soft_opt_out_threshold,omitempty"` // Deprecated: Do not use. + // The threshold for the percentage of validators at the bottom of the set who + // can opt out of running the consumer chain without being punished. For + // example, a value of 0.05 means that the validators in the bottom 5% of the + // set can opt out + SoftOptOutThreshold string `protobuf:"bytes,10,opt,name=soft_opt_out_threshold,json=softOptOutThreshold,proto3" json:"soft_opt_out_threshold,omitempty"` // Reward denoms. These are the denominations which are allowed to be sent to // the provider as rewards. RewardDenoms []string `protobuf:"bytes,11,rep,name=reward_denoms,json=rewardDenoms,proto3" json:"reward_denoms,omitempty"` @@ -173,7 +176,6 @@ func (m *ConsumerParams) GetUnbondingPeriod() time.Duration { return 0 } -// Deprecated: Do not use. func (m *ConsumerParams) GetSoftOptOutThreshold() string { if m != nil { return m.SoftOptOutThreshold @@ -341,59 +343,58 @@ func init() { } var fileDescriptor_d0a8be0efc64dfbc = []byte{ - // 817 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x41, 0x6f, 0xe4, 0x34, - 0x14, 0x6e, 0x3a, 0x4b, 0x77, 0xea, 0x69, 0xb7, 0x8b, 0x29, 0x4b, 0xe8, 0x4a, 0xd3, 0x6c, 0xe1, - 0x30, 0x02, 0x6d, 0x42, 0x4b, 0x25, 0x24, 0x6e, 0xb4, 0x65, 0x59, 0xf6, 0xd0, 0xce, 0xa6, 0x65, - 0x91, 0xe0, 0x60, 0x39, 0xf6, 0x9b, 0x89, 0x45, 0x62, 0x47, 0xb6, 0x93, 0xd2, 0x5f, 0xc0, 0x95, - 0x23, 0x3f, 0x69, 0xb9, 0xed, 0x91, 0x13, 0xa0, 0xf6, 0x8f, 0xa0, 0x38, 0x49, 0x9b, 0x41, 0x14, - 0xca, 0xcd, 0xcf, 0xef, 0xfb, 0xbe, 0xe4, 0x7b, 0xf6, 0x7b, 0x46, 0x9f, 0x08, 0x69, 0x41, 0xb3, - 0x94, 0x0a, 0x49, 0x0c, 0xb0, 0x52, 0x0b, 0x7b, 0x11, 0x31, 0x56, 0x45, 0xd5, 0x6e, 0x64, 0x52, - 0xaa, 0x81, 0x13, 0xa6, 0xa4, 0x29, 0x73, 0xd0, 0x61, 0xa1, 0x95, 0x55, 0x78, 0xeb, 0x1f, 0x18, - 0x21, 0x63, 0x55, 0x58, 0xed, 0x6e, 0x3d, 0xb6, 0x20, 0x39, 0xe8, 0x5c, 0x48, 0x1b, 0xd1, 0x84, - 0x89, 0xc8, 0x5e, 0x14, 0x60, 0x1a, 0xe2, 0x56, 0x24, 0x12, 0x16, 0x65, 0x62, 0x9e, 0x5a, 0x96, - 0x09, 0x90, 0xd6, 0x44, 0x3d, 0x74, 0xb5, 0xdb, 0x8b, 0x5a, 0xc2, 0x78, 0xae, 0xd4, 0x3c, 0x83, - 0xc8, 0x45, 0x49, 0x39, 0x8b, 0x78, 0xa9, 0xa9, 0x15, 0x4a, 0xb6, 0xf9, 0xcd, 0xb9, 0x9a, 0x2b, - 0xb7, 0x8c, 0xea, 0x55, 0xb3, 0xbb, 0x73, 0xb5, 0x82, 0x1e, 0x1c, 0xb6, 0xbf, 0x3c, 0xa5, 0x9a, - 0xe6, 0x06, 0xfb, 0xe8, 0x3e, 0x48, 0x9a, 0x64, 0xc0, 0x7d, 0x2f, 0xf0, 0x26, 0xc3, 0xb8, 0x0b, - 0xf1, 0x09, 0xfa, 0x30, 0xc9, 0x14, 0xfb, 0xc1, 0x90, 0x02, 0x34, 0xe1, 0xc2, 0x58, 0x2d, 0x92, - 0xb2, 0xfe, 0x06, 0xb1, 0x9a, 0x4a, 0x93, 0x0b, 0x63, 0x84, 0x92, 0xfe, 0x72, 0xe0, 0x4d, 0x06, - 0xf1, 0x93, 0x06, 0x3b, 0x05, 0x7d, 0xd4, 0x43, 0x9e, 0xf5, 0x80, 0xf8, 0x05, 0x7a, 0x72, 0xab, - 0x0a, 0x61, 0x29, 0x95, 0x12, 0x32, 0x7f, 0x10, 0x78, 0x93, 0xd5, 0x78, 0x9b, 0xdf, 0x22, 0x72, - 0xd8, 0xc0, 0xf0, 0xe7, 0x68, 0xab, 0xd0, 0xaa, 0x12, 0x1c, 0x34, 0x99, 0x01, 0x90, 0x42, 0xa9, - 0x8c, 0x50, 0xce, 0x35, 0x31, 0x56, 0xfb, 0xf7, 0x9c, 0xc8, 0xa3, 0x0e, 0xf1, 0x0c, 0x60, 0xaa, - 0x54, 0xf6, 0x05, 0xe7, 0xfa, 0xd4, 0x6a, 0xfc, 0x12, 0x61, 0xc6, 0x2a, 0x62, 0x45, 0x0e, 0xaa, - 0xb4, 0xb5, 0x3b, 0xa1, 0xb8, 0xff, 0x56, 0xe0, 0x4d, 0x46, 0x7b, 0xef, 0x87, 0x4d, 0x61, 0xc3, - 0xae, 0xb0, 0xe1, 0x51, 0x5b, 0xd8, 0x83, 0xe1, 0xeb, 0xdf, 0xb7, 0x97, 0x7e, 0xf9, 0x63, 0xdb, - 0x8b, 0x1f, 0x32, 0x56, 0x9d, 0x35, 0xec, 0xa9, 0x23, 0xe3, 0xef, 0xd1, 0x7b, 0xce, 0xcd, 0x0c, - 0xf4, 0xdf, 0x75, 0x57, 0xee, 0xae, 0xfb, 0x6e, 0xa7, 0xb1, 0x28, 0xfe, 0x1c, 0x05, 0xdd, 0x3d, - 0x23, 0x1a, 0x16, 0x4a, 0x38, 0xd3, 0x94, 0xd5, 0x0b, 0xff, 0xbe, 0x73, 0x3c, 0xee, 0x70, 0xf1, - 0x02, 0xec, 0x59, 0x8b, 0xc2, 0x4f, 0x11, 0x4e, 0x85, 0xb1, 0x4a, 0x0b, 0x46, 0x33, 0x02, 0xd2, - 0x6a, 0x01, 0xc6, 0x1f, 0xba, 0x03, 0x7c, 0xfb, 0x26, 0xf3, 0x65, 0x93, 0xc0, 0xc7, 0xe8, 0x61, - 0x29, 0x13, 0x25, 0xb9, 0x90, 0xf3, 0xce, 0xce, 0xea, 0xdd, 0xed, 0x6c, 0x5c, 0x93, 0x5b, 0x23, - 0x9f, 0xa1, 0x47, 0x46, 0xcd, 0x2c, 0x51, 0x85, 0x25, 0x75, 0x85, 0x6c, 0xaa, 0xc1, 0xa4, 0x2a, - 0xe3, 0x3e, 0xaa, 0x7f, 0xff, 0x60, 0xd9, 0xf7, 0xe2, 0x77, 0x6a, 0xc4, 0x49, 0x61, 0x4f, 0x4a, - 0x7b, 0xd6, 0xa5, 0xf1, 0x07, 0x68, 0x5d, 0xc3, 0x39, 0xd5, 0x9c, 0x70, 0x90, 0x2a, 0x37, 0xfe, - 0x28, 0x18, 0x4c, 0x56, 0xe3, 0xb5, 0x66, 0xf3, 0xc8, 0xed, 0xe1, 0x7d, 0x74, 0x7d, 0xe0, 0x64, - 0x11, 0xbd, 0xe6, 0xd0, 0x9b, 0x5d, 0x36, 0xee, 0xb3, 0x5e, 0x22, 0xac, 0xc1, 0xea, 0x0b, 0xc2, - 0x21, 0xa3, 0x17, 0x9d, 0xcb, 0xf5, 0xff, 0x71, 0x19, 0x1c, 0xfd, 0xa8, 0x66, 0x37, 0x36, 0x77, - 0x7e, 0xf5, 0xd0, 0x66, 0xd7, 0x65, 0x5f, 0x81, 0x04, 0x23, 0xcc, 0xa9, 0xa5, 0x16, 0xf0, 0x73, - 0xb4, 0x52, 0xb8, 0xae, 0x73, 0xad, 0x36, 0xda, 0xfb, 0x28, 0xbc, 0x7d, 0x5e, 0x84, 0x8b, 0x7d, - 0x7a, 0x70, 0xaf, 0xfe, 0x60, 0xdc, 0xf2, 0xf1, 0x0b, 0x34, 0xec, 0xdc, 0xb8, 0xfe, 0x1b, 0xed, - 0x4d, 0xfe, 0x4d, 0x6b, 0xda, 0x62, 0xbf, 0x96, 0x33, 0xd5, 0x2a, 0x5d, 0xf3, 0xf1, 0x63, 0xb4, - 0x2a, 0xe1, 0x9c, 0x38, 0xa6, 0x6b, 0xbf, 0x61, 0x3c, 0x94, 0x70, 0x7e, 0x58, 0xc7, 0x3b, 0x3f, - 0x2d, 0xa3, 0xb5, 0x3e, 0x1b, 0x1f, 0xa3, 0xb5, 0x66, 0x44, 0x11, 0x53, 0x7b, 0x6a, 0x9d, 0x7c, - 0x1c, 0x8a, 0x84, 0x85, 0xfd, 0x01, 0x16, 0xf6, 0x46, 0x56, 0xed, 0xc6, 0xed, 0xba, 0x32, 0xc4, - 0x23, 0x76, 0x13, 0xe0, 0x6f, 0xd1, 0x46, 0x7d, 0x69, 0x41, 0x9a, 0xd2, 0xb4, 0x92, 0x8d, 0xa1, - 0xf0, 0x3f, 0x25, 0x3b, 0x5a, 0xa3, 0xfa, 0x80, 0x2d, 0xc4, 0xf8, 0x18, 0x6d, 0x08, 0x29, 0xac, - 0xa0, 0x19, 0xa9, 0x68, 0x46, 0x0c, 0x58, 0x7f, 0x10, 0x0c, 0x26, 0xa3, 0xbd, 0xa0, 0xaf, 0x53, - 0x4f, 0xe2, 0xf0, 0x15, 0xcd, 0x04, 0xa7, 0x56, 0xe9, 0x6f, 0x0a, 0x4e, 0x2d, 0xb4, 0x15, 0x5a, - 0x6f, 0xe9, 0xaf, 0x68, 0x76, 0x0a, 0xf6, 0xe0, 0xf8, 0xf5, 0xe5, 0xd8, 0x7b, 0x73, 0x39, 0xf6, - 0xfe, 0xbc, 0x1c, 0x7b, 0x3f, 0x5f, 0x8d, 0x97, 0xde, 0x5c, 0x8d, 0x97, 0x7e, 0xbb, 0x1a, 0x2f, - 0x7d, 0xb7, 0x3f, 0x17, 0x36, 0x2d, 0x93, 0x90, 0xa9, 0x3c, 0x62, 0xca, 0xe4, 0xca, 0x44, 0x37, - 0x67, 0xf1, 0xf4, 0xfa, 0xe5, 0xa8, 0xf6, 0xa3, 0x1f, 0xdd, 0xf3, 0xe1, 0x06, 0x7f, 0xb2, 0xe2, - 0x2e, 0xd5, 0xa7, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0x9e, 0x67, 0x6a, 0xf6, 0x66, 0x06, 0x00, - 0x00, + // 812 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x41, 0x73, 0xdc, 0x34, + 0x14, 0x8e, 0xbb, 0x25, 0xdd, 0x68, 0x93, 0xa6, 0x88, 0x50, 0x4c, 0x3a, 0xb3, 0x71, 0x03, 0x87, + 0x1d, 0x98, 0xda, 0x24, 0xcd, 0x89, 0x1b, 0x49, 0x28, 0xa5, 0x87, 0x64, 0xeb, 0x84, 0x32, 0x03, + 0x07, 0x8d, 0x2c, 0xbd, 0x5d, 0x6b, 0xb0, 0x25, 0x8f, 0x24, 0x3b, 0xe4, 0x17, 0x70, 0xe5, 0xc8, + 0x4f, 0x2a, 0xb7, 0x1e, 0x39, 0x51, 0x26, 0xf9, 0x23, 0x8c, 0x65, 0x3b, 0xf1, 0x32, 0x04, 0xd2, + 0x9b, 0x9e, 0xde, 0xf7, 0x7d, 0xf6, 0xf7, 0xa4, 0xf7, 0x84, 0xbe, 0x10, 0xd2, 0x82, 0x66, 0x29, + 0x15, 0x92, 0x18, 0x60, 0xa5, 0x16, 0xf6, 0x3c, 0x62, 0xac, 0x8a, 0xaa, 0x9d, 0xc8, 0xa4, 0x54, + 0x03, 0x27, 0x4c, 0x49, 0x53, 0xe6, 0xa0, 0xc3, 0x42, 0x2b, 0xab, 0xf0, 0xe6, 0xbf, 0x30, 0x42, + 0xc6, 0xaa, 0xb0, 0xda, 0xd9, 0x7c, 0x64, 0x41, 0x72, 0xd0, 0xb9, 0x90, 0x36, 0xa2, 0x09, 0x13, + 0x91, 0x3d, 0x2f, 0xc0, 0x34, 0xc4, 0xcd, 0x48, 0x24, 0x2c, 0xca, 0xc4, 0x3c, 0xb5, 0x2c, 0x13, + 0x20, 0xad, 0x89, 0x7a, 0xe8, 0x6a, 0xa7, 0x17, 0xb5, 0x84, 0xf1, 0x5c, 0xa9, 0x79, 0x06, 0x91, + 0x8b, 0x92, 0x72, 0x16, 0xf1, 0x52, 0x53, 0x2b, 0x94, 0x6c, 0xf3, 0x1b, 0x73, 0x35, 0x57, 0x6e, + 0x19, 0xd5, 0xab, 0x66, 0x77, 0xfb, 0xed, 0x32, 0xba, 0x7f, 0xd0, 0xfe, 0xf2, 0x94, 0x6a, 0x9a, + 0x1b, 0xec, 0xa3, 0x7b, 0x20, 0x69, 0x92, 0x01, 0xf7, 0xbd, 0xc0, 0x9b, 0x0c, 0xe3, 0x2e, 0xc4, + 0xc7, 0xe8, 0xd3, 0x24, 0x53, 0xec, 0x27, 0x43, 0x0a, 0xd0, 0x84, 0x0b, 0x63, 0xb5, 0x48, 0xca, + 0xfa, 0x1b, 0xc4, 0x6a, 0x2a, 0x4d, 0x2e, 0x8c, 0x11, 0x4a, 0xfa, 0x77, 0x02, 0x6f, 0x32, 0x88, + 0x1f, 0x37, 0xd8, 0x29, 0xe8, 0xc3, 0x1e, 0xf2, 0xb4, 0x07, 0xc4, 0x2f, 0xd0, 0xe3, 0x1b, 0x55, + 0x08, 0x4b, 0xa9, 0x94, 0x90, 0xf9, 0x83, 0xc0, 0x9b, 0xac, 0xc4, 0x5b, 0xfc, 0x06, 0x91, 0x83, + 0x06, 0x86, 0xbf, 0x44, 0x9b, 0x85, 0x56, 0x95, 0xe0, 0xa0, 0xc9, 0x0c, 0x80, 0x14, 0x4a, 0x65, + 0x84, 0x72, 0xae, 0x89, 0xb1, 0xda, 0xbf, 0xeb, 0x44, 0x1e, 0x76, 0x88, 0x67, 0x00, 0x53, 0xa5, + 0xb2, 0xaf, 0x38, 0xd7, 0x27, 0x56, 0xe3, 0x97, 0x08, 0x33, 0x56, 0x11, 0x2b, 0x72, 0x50, 0xa5, + 0xad, 0xdd, 0x09, 0xc5, 0xfd, 0xf7, 0x02, 0x6f, 0x32, 0xda, 0xfd, 0x38, 0x6c, 0x0a, 0x1b, 0x76, + 0x85, 0x0d, 0x0f, 0xdb, 0xc2, 0xee, 0x0f, 0x5f, 0xff, 0xb9, 0xb5, 0xf4, 0xdb, 0xdb, 0x2d, 0x2f, + 0x7e, 0xc0, 0x58, 0x75, 0xda, 0xb0, 0xa7, 0x8e, 0x8c, 0x7f, 0x44, 0x1f, 0x39, 0x37, 0x33, 0xd0, + 0xff, 0xd4, 0x5d, 0xbe, 0xbd, 0xee, 0x87, 0x9d, 0xc6, 0xa2, 0xf8, 0x73, 0x14, 0x74, 0xf7, 0x8c, + 0x68, 0x58, 0x28, 0xe1, 0x4c, 0x53, 0x56, 0x2f, 0xfc, 0x7b, 0xce, 0xf1, 0xb8, 0xc3, 0xc5, 0x0b, + 0xb0, 0x67, 0x2d, 0x0a, 0x3f, 0x41, 0x38, 0x15, 0xc6, 0x2a, 0x2d, 0x18, 0xcd, 0x08, 0x48, 0xab, + 0x05, 0x18, 0x7f, 0xe8, 0x0e, 0xf0, 0xfd, 0xeb, 0xcc, 0xd7, 0x4d, 0x02, 0x1f, 0xa1, 0x07, 0xa5, + 0x4c, 0x94, 0xe4, 0x42, 0xce, 0x3b, 0x3b, 0x2b, 0xb7, 0xb7, 0xb3, 0x7e, 0x45, 0x6e, 0x8d, 0x3c, + 0x45, 0x0f, 0x8d, 0x9a, 0x59, 0xa2, 0x0a, 0x4b, 0xea, 0x0a, 0xd9, 0x54, 0x83, 0x49, 0x55, 0xc6, + 0x7d, 0xe4, 0x7e, 0xff, 0x83, 0x3a, 0x7b, 0x5c, 0xd8, 0xe3, 0xd2, 0x9e, 0x76, 0x29, 0xfc, 0x09, + 0x5a, 0xd3, 0x70, 0x46, 0x35, 0x27, 0x1c, 0xa4, 0xca, 0x8d, 0x3f, 0x0a, 0x06, 0x93, 0x95, 0x78, + 0xb5, 0xd9, 0x3c, 0x74, 0x7b, 0x78, 0x0f, 0x5d, 0x1d, 0x36, 0x59, 0x44, 0xaf, 0x3a, 0xf4, 0x46, + 0x97, 0x8d, 0xfb, 0xac, 0x97, 0x08, 0x6b, 0xb0, 0xfa, 0x9c, 0x70, 0xc8, 0xe8, 0x79, 0xe7, 0x70, + 0xed, 0x1d, 0x2e, 0x82, 0xa3, 0x1f, 0xd6, 0xec, 0xc6, 0xe2, 0xf6, 0xef, 0x1e, 0xda, 0xe8, 0x3a, + 0xec, 0x1b, 0x90, 0x60, 0x84, 0x39, 0xb1, 0xd4, 0x02, 0x7e, 0x8e, 0x96, 0x0b, 0xd7, 0x71, 0xae, + 0xcd, 0x46, 0xbb, 0x9f, 0x85, 0x37, 0xcf, 0x8a, 0x70, 0xb1, 0x47, 0xf7, 0xef, 0xd6, 0x1f, 0x8c, + 0x5b, 0x3e, 0x7e, 0x81, 0x86, 0x9d, 0x1b, 0xd7, 0x7b, 0xa3, 0xdd, 0xc9, 0x7f, 0x69, 0x4d, 0x5b, + 0xec, 0xb7, 0x72, 0xa6, 0x5a, 0xa5, 0x2b, 0x3e, 0x7e, 0x84, 0x56, 0x24, 0x9c, 0x11, 0xc7, 0x74, + 0xad, 0x37, 0x8c, 0x87, 0x12, 0xce, 0x0e, 0xea, 0x78, 0xfb, 0x97, 0x3b, 0x68, 0xb5, 0xcf, 0xc6, + 0x47, 0x68, 0xb5, 0x19, 0x4f, 0xc4, 0xd4, 0x9e, 0x5a, 0x27, 0x9f, 0x87, 0x22, 0x61, 0x61, 0x7f, + 0x78, 0x85, 0xbd, 0x71, 0x55, 0xbb, 0x71, 0xbb, 0xae, 0x0c, 0xf1, 0x88, 0x5d, 0x07, 0xf8, 0x7b, + 0xb4, 0x5e, 0x5f, 0x58, 0x90, 0xa6, 0x34, 0xad, 0x64, 0x63, 0x28, 0xfc, 0x5f, 0xc9, 0x8e, 0xd6, + 0xa8, 0xde, 0x67, 0x0b, 0x31, 0x3e, 0x42, 0xeb, 0x42, 0x0a, 0x2b, 0x68, 0x46, 0x2a, 0x9a, 0x11, + 0x03, 0xd6, 0x1f, 0x04, 0x83, 0xc9, 0x68, 0x37, 0xe8, 0xeb, 0xd4, 0x53, 0x38, 0x7c, 0x45, 0x33, + 0xc1, 0xa9, 0x55, 0xfa, 0xbb, 0x82, 0x53, 0x0b, 0x6d, 0x85, 0xd6, 0x5a, 0xfa, 0x2b, 0x9a, 0x9d, + 0x80, 0xdd, 0x3f, 0x7a, 0x7d, 0x31, 0xf6, 0xde, 0x5c, 0x8c, 0xbd, 0xbf, 0x2e, 0xc6, 0xde, 0xaf, + 0x97, 0xe3, 0xa5, 0x37, 0x97, 0xe3, 0xa5, 0x3f, 0x2e, 0xc7, 0x4b, 0x3f, 0xec, 0xcd, 0x85, 0x4d, + 0xcb, 0x24, 0x64, 0x2a, 0x8f, 0x98, 0x32, 0xb9, 0x32, 0xd1, 0xf5, 0x59, 0x3c, 0xb9, 0x7a, 0x35, + 0xaa, 0xbd, 0xe8, 0x67, 0xf7, 0x74, 0xb8, 0xa1, 0x9f, 0x2c, 0xbb, 0x4b, 0xf5, 0xf4, 0xef, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x04, 0x32, 0x2d, 0xba, 0x62, 0x06, 0x00, 0x00, } func (m *ConsumerParams) Marshal() (dAtA []byte, err error) { diff --git a/x/ccv/types/utils.go b/x/ccv/types/utils.go index 236fee21cf..cb4e86d6b2 100644 --- a/x/ccv/types/utils.go +++ b/x/ccv/types/utils.go @@ -12,6 +12,7 @@ import ( host "github.com/cosmos/ibc-go/v7/modules/core/24-host" errorsmod "cosmossdk.io/errors" + "github.com/cometbft/cometbft/libs/log" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -19,7 +20,6 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" abci "github.com/cometbft/cometbft/abci/types" - "github.com/cometbft/cometbft/libs/log" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" ) From ad78fb01782357917fb2d9f82ec9970bec35e8ed Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Thu, 4 Jul 2024 10:06:07 +0200 Subject: [PATCH 24/35] update changelog --- .../dependencies/{xxx-bump-comet.md => 2013-bump-comet.md} | 2 +- .../xxx-bump-ibc.md => dependencies/2013-bump-ibc.md} | 2 +- .../xxx-bump-sdk.md => dependencies/2013-bump-sdk.md} | 2 +- .../state-breaking/{xxx-bump-comet.md => 2013-bump-comet.md} | 2 +- .../xxx-bump-ibc.md => state-breaking/2013-bump-ibc.md} | 2 +- .../xxx-bump-sdk.md => state-breaking/2013-bump-sdk.md} | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename .changelog/unreleased/dependencies/{xxx-bump-comet.md => 2013-bump-comet.md} (65%) rename .changelog/unreleased/{state-breaking/xxx-bump-ibc.md => dependencies/2013-bump-ibc.md} (63%) rename .changelog/unreleased/{state-breaking/xxx-bump-sdk.md => dependencies/2013-bump-sdk.md} (65%) rename .changelog/unreleased/state-breaking/{xxx-bump-comet.md => 2013-bump-comet.md} (65%) rename .changelog/unreleased/{dependencies/xxx-bump-ibc.md => state-breaking/2013-bump-ibc.md} (63%) rename .changelog/unreleased/{dependencies/xxx-bump-sdk.md => state-breaking/2013-bump-sdk.md} (65%) diff --git a/.changelog/unreleased/dependencies/xxx-bump-comet.md b/.changelog/unreleased/dependencies/2013-bump-comet.md similarity index 65% rename from .changelog/unreleased/dependencies/xxx-bump-comet.md rename to .changelog/unreleased/dependencies/2013-bump-comet.md index 045e29ce3d..9af87a1038 100644 --- a/.changelog/unreleased/dependencies/xxx-bump-comet.md +++ b/.changelog/unreleased/dependencies/2013-bump-comet.md @@ -1,3 +1,3 @@ - Bump [CometBFT](https://github.com/cometbft/cometbft) to [v0.38.7](https://github.com/cometbft/cometbft/releases/tag/v0.38.7). - ([\#xxx](https://github.com/cosmos/interchain-security/pull/xxx)) \ No newline at end of file + ([\#2013](https://github.com/cosmos/interchain-security/pull/2013)) \ No newline at end of file diff --git a/.changelog/unreleased/state-breaking/xxx-bump-ibc.md b/.changelog/unreleased/dependencies/2013-bump-ibc.md similarity index 63% rename from .changelog/unreleased/state-breaking/xxx-bump-ibc.md rename to .changelog/unreleased/dependencies/2013-bump-ibc.md index 494a69911b..eeaec9b362 100644 --- a/.changelog/unreleased/state-breaking/xxx-bump-ibc.md +++ b/.changelog/unreleased/dependencies/2013-bump-ibc.md @@ -1,3 +1,3 @@ - Bump [ibc-go](https://github.com/cosmos/ibc-go) to [v8.2.1](https://github.com/cosmos/ibc-go/releases/tag/v8.2.1). - ([\#xx](https://github.com/cosmos/interchain-security/pull/1698)) \ No newline at end of file + ([\#2013](https://github.com/cosmos/interchain-security/pull/2013)) \ No newline at end of file diff --git a/.changelog/unreleased/state-breaking/xxx-bump-sdk.md b/.changelog/unreleased/dependencies/2013-bump-sdk.md similarity index 65% rename from .changelog/unreleased/state-breaking/xxx-bump-sdk.md rename to .changelog/unreleased/dependencies/2013-bump-sdk.md index 9c38164b12..47c4361f49 100644 --- a/.changelog/unreleased/state-breaking/xxx-bump-sdk.md +++ b/.changelog/unreleased/dependencies/2013-bump-sdk.md @@ -1,3 +1,3 @@ - Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to [v0.50.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.5) -([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) \ No newline at end of file +([\#2013](https://github.com/cosmos/interchain-security/pull/2013)) \ No newline at end of file diff --git a/.changelog/unreleased/state-breaking/xxx-bump-comet.md b/.changelog/unreleased/state-breaking/2013-bump-comet.md similarity index 65% rename from .changelog/unreleased/state-breaking/xxx-bump-comet.md rename to .changelog/unreleased/state-breaking/2013-bump-comet.md index 045e29ce3d..9af87a1038 100644 --- a/.changelog/unreleased/state-breaking/xxx-bump-comet.md +++ b/.changelog/unreleased/state-breaking/2013-bump-comet.md @@ -1,3 +1,3 @@ - Bump [CometBFT](https://github.com/cometbft/cometbft) to [v0.38.7](https://github.com/cometbft/cometbft/releases/tag/v0.38.7). - ([\#xxx](https://github.com/cosmos/interchain-security/pull/xxx)) \ No newline at end of file + ([\#2013](https://github.com/cosmos/interchain-security/pull/2013)) \ No newline at end of file diff --git a/.changelog/unreleased/dependencies/xxx-bump-ibc.md b/.changelog/unreleased/state-breaking/2013-bump-ibc.md similarity index 63% rename from .changelog/unreleased/dependencies/xxx-bump-ibc.md rename to .changelog/unreleased/state-breaking/2013-bump-ibc.md index 494a69911b..eeaec9b362 100644 --- a/.changelog/unreleased/dependencies/xxx-bump-ibc.md +++ b/.changelog/unreleased/state-breaking/2013-bump-ibc.md @@ -1,3 +1,3 @@ - Bump [ibc-go](https://github.com/cosmos/ibc-go) to [v8.2.1](https://github.com/cosmos/ibc-go/releases/tag/v8.2.1). - ([\#xx](https://github.com/cosmos/interchain-security/pull/1698)) \ No newline at end of file + ([\#2013](https://github.com/cosmos/interchain-security/pull/2013)) \ No newline at end of file diff --git a/.changelog/unreleased/dependencies/xxx-bump-sdk.md b/.changelog/unreleased/state-breaking/2013-bump-sdk.md similarity index 65% rename from .changelog/unreleased/dependencies/xxx-bump-sdk.md rename to .changelog/unreleased/state-breaking/2013-bump-sdk.md index 9c38164b12..47c4361f49 100644 --- a/.changelog/unreleased/dependencies/xxx-bump-sdk.md +++ b/.changelog/unreleased/state-breaking/2013-bump-sdk.md @@ -1,3 +1,3 @@ - Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to [v0.50.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.5) -([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) \ No newline at end of file +([\#2013](https://github.com/cosmos/interchain-security/pull/2013)) \ No newline at end of file From 023a47d29b21a88fded753e80d356fd368ea48df Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Thu, 4 Jul 2024 13:03:40 +0200 Subject: [PATCH 25/35] fix epilogue --- .changelog/epilogue.md | 198 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 196 insertions(+), 2 deletions(-) diff --git a/.changelog/epilogue.md b/.changelog/epilogue.md index 3a080d16b9..88987ef0a0 100644 --- a/.changelog/epilogue.md +++ b/.changelog/epilogue.md @@ -1,3 +1,197 @@ -## Previous Versions +## v3.1.0 -[CHANGELOG of previous versions](https://github.com/cosmos/interchain-security/blob/main/CHANGELOG.md) +Date July 11th, 2023 + +A minor upgrade to v3.0.0, which removes the panic in the consumer ccv module which would occur in an emergency scenario where the ccv channel is closed. This release also fixes how a distribution related event is emitted, and bumps cometbft. + +* (feat) [#1127](https://github.com/cosmos/interchain-security/pull/1127) Remove consumer panic when ccv channel is closed +* (fix) [#720](https://github.com/cosmos/interchain-security/issues/720) Fix the attribute `AttributeDistributionTotal` value in `FeeDistribution` event emit. +* (deps) [#1119](https://github.com/cosmos/interchain-security/pull/1119) bump cometbft from `v0.37.1` to `0.37.2`. + +## v3.0.0 + +Date: June 21st, 2023 + +Interchain Security v3 uses SDK 0.47 and IBC 7. + +* (fix) [#1093](https://github.com/cosmos/interchain-security/pull/1093) Make SlashPacketData backward compatible when sending data over the wire +* (deps) [#1019](https://github.com/cosmos/interchain-security/pull/1019) Bump multiple dependencies. + * Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to [v0.47.3](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.3). + * Bump [ibc-go](https://github.com/cosmos/ibc-go) to [v7.1.0](https://github.com/cosmos/ibc-go/releases/tag/v7.1.0). + * Bump [CometBFT](https://github.com/cometbft/cometbft) to [v0.37.1](https://github.com/cometbft/cometbft/releases/tag/v0.37.1). +* `[x/ccv/provider]` (fix) [#945](https://github.com/cosmos/interchain-security/issues/945) Refactor `AfterUnbondingInitiated` to not panic when `PutUnbondingOnHold` returns error. +* `[x/ccv/provider]` (fix) [#977](https://github.com/cosmos/interchain-security/pull/977) Avoids panicking the provider when an unbonding delegation was removed through a `CancelUnbondingDelegation` message. +* `[x/ccv/democracy]` (feat) [#1019](https://github.com/cosmos/interchain-security/pull/1019) Whitelisting non-legacy params in the "democracy module" require the entire module to be whitelisted. + +## v2.4.0-lsm + +*November 20, 2023* + +* (fix) [#1439](https://github.com/cosmos/interchain-security/pull/1439) Fix unmarshaling for the CLI consumer double vote cmd. +* (feat!) [#1435](https://github.com/cosmos/interchain-security/pull/1435) Add height-base filter for consumer equivocation evidence. + +## v2.3.0-provider-lsm + +*November 15, 2023* + +❗ *This release is deprecated and should not be used in production.* + +* (fix!) [#1422](https://github.com/cosmos/interchain-security/pull/1422) Fix the misbehaviour handling by verifying the signatures of byzantine validators. + +## v2.2.0-provider-lsm + +❗ *This release is deprecated and should not be used in production.* + +### Cryptographic verification of equivocation +* New feature enabling the provider chain to verify equivocation evidence on its own instead of trusting consumer chains, see [EPIC](https://github.com/cosmos/interchain-security/issues/732). + +## v2.1.0-provider-lsm + +Date: September 15th, 2023 + +* (feature!) [#1280](https://github.com/cosmos/interchain-security/pull/1280) provider proposal for changing reward denoms + +## v2.0.0-lsm + +Date: August 18th, 2023 + +* (deps!) [#1120](https://github.com/cosmos/interchain-security/pull/1120) Bump [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) to [v0.45.16-ics-lsm](https://github.com/cosmos/cosmos-sdk/tree/v0.45.16-ics-lsm). This requires adapting ICS to support this SDK release. Changes are state breaking. +* (fix) [#720](https://github.com/cosmos/interchain-security/issues/720) Fix the attribute `AttributeDistributionTotal` value in `FeeDistribution` event emit. + +## v2.0.0 + +Date: June 1st, 2023 + +Unlike prior releases, the ICS `v2.0.0` release will be based on the main branch. `v2.0.0` will contain all the accumulated PRs from the various releases below, along with other PRs that were merged, but not released to production. After `v2.0.0`, we plan to revamp release practices, and how we modularize the repo for consumer/provider. + +Upgrading a provider from `v1.1.0-multiden` to `v2.0.0` will require state migrations. See [migration.go](https://github.com/cosmos/interchain-security/blob/v2.0.0/x/ccv/provider/keeper/migration.go). + +Upgrading a consumer from `v1.2.0-multiden` to `v2.0.0` will NOT require state migrations. + +Some PRs from v2.0.0 may reappear from other releases below. This is due to the fact that ICS v1.1.0 deviates from the commit ordering of the main branch, and other releases thereafter are based on v1.1.0. + +### High level changes included in v2.0.0 + +* MVP for standalone to consumer changeover, see [EPIC](https://github.com/cosmos/interchain-security/issues/756) +* MVP for soft opt out, see [EPIC](https://github.com/cosmos/interchain-security/issues/851) +* Various fixes, critical and non-critical +* Docs updates which should not affect production code + +## Notable PRs included in v2.0.0 + +* (feat!) Add DistributionTransmissionChannel to ConsumerAdditionProposal [#965](https://github.com/cosmos/interchain-security/pull/965) +* (feat/fix) limit vsc matured packets handled per endblocker [#1004](https://github.com/cosmos/interchain-security/pull/1004) +* (fix) consumer key prefix order to avoid complex migrations [#963](https://github.com/cosmos/interchain-security/pull/963) and [#991](https://github.com/cosmos/interchain-security/pull/991). The latter PR is the proper fix. +* (feat) v1->v2 migrations to accommodate a bugfix having to do with store keys, introduce new params, and deal with consumer genesis state schema changes [#975](https://github.com/cosmos/interchain-security/pull/975) and [#997](https://github.com/cosmos/interchain-security/pull/997) +* (deps) Bump github.com/cosmos/ibc-go/v4 from 4.4.0 to 4.4.2 [#982](https://github.com/cosmos/interchain-security/pull/982) +* (fix) partially revert key assignment type safety PR [#980](https://github.com/cosmos/interchain-security/pull/980) +* (fix) Remove panics on failure to send IBC packets [#876](https://github.com/cosmos/interchain-security/pull/876) +* (fix) Prevent denom DOS [#931](https://github.com/cosmos/interchain-security/pull/931) +* (fix) multisig for assigning consumer key, use json [#916](https://github.com/cosmos/interchain-security/pull/916) +* (deps) Bump github.com/cosmos/ibc-go/v4 from 4.3.0 to 4.4.0 [#902](https://github.com/cosmos/interchain-security/pull/902) +* (feat) Add warnings when provider unbonding is shorter than consumer unbonding [#858](https://github.com/cosmos/interchain-security/pull/858) +* (chore) use go 1.19 [#899](https://github.com/cosmos/interchain-security/pull/899), [#840](https://github.com/cosmos/interchain-security/pull/840) +* (feat) Standalone to consumer changeover - recycle existing transfer channel [#832](https://github.com/cosmos/interchain-security/pull/832) +* (deps) Bump IBC [862](https://github.com/cosmos/interchain-security/pull/862) +* (testing) Add tests for soft opt out [#857](https://github.com/cosmos/interchain-security/pull/857) +* (feat) Standalone to consumer changeover - staking functionalities [#794](https://github.com/cosmos/interchain-security/pull/794) +* (fix) prevent provider from sending VSCPackets with multiple updates for the same validator [#850](https://github.com/cosmos/interchain-security/pull/850) +* (feat) Soft opt out [#833](https://github.com/cosmos/interchain-security/issues/833) +* (fix) Correctly handle VSC packet with duplicate val updates on consumer [#846](https://github.com/cosmos/interchain-security/pull/846) +* (deps) bump sdk to v0.45.15.ics [#805](https://github.com/cosmos/interchain-security/pull/805) +* (refactor) Remove spm module [#812](https://github.com/cosmos/interchain-security/pull/812) +* (feat) Standalone to consumer changeover part 1 [#757](https://github.com/cosmos/interchain-security/pull/757) +* (chore) Swap names of e2e and integration tests [#681](https://github.com/cosmos/interchain-security/pull/681) +* (fix) fix StopConsumerChain not running in cachedContext [#802](https://github.com/cosmos/interchain-security/pull/802). Also in earlier releases with different commit order! +* (docs) Introduce docs website [#759](https://github.com/cosmos/interchain-security/pull/759) +* (fix) Serialize correct byte prefix for SlashLogKey [#786](https://github.com/cosmos/interchain-security/pull/786) +* (feature) Improve keeper field validation [#766](https://github.com/cosmos/interchain-security/pull/766) +* (docs) Contributing guidelines [#744](https://github.com/cosmos/interchain-security/pull/744) +* (refactor) Key assignment type safety [#725](https://github.com/cosmos/interchain-security/pull/725) +* (fix) Update protos and fix deps [#752](https://github.com/cosmos/interchain-security/pull/752) +* (api) Add consumer QueryParams [#746](https://github.com/cosmos/interchain-security/pull/746) +* (feature) New validation for keeper fields [#740](https://github.com/cosmos/interchain-security/pull/740) + +## v1.2.0-multiden + +The first release candidate for a fix built on top of v1.2.0, intended for consumers. This release adds a list of denoms on the consumer that are allowed to be sent to the provider as rewards. This prevents a potential DOS attack that was discovered during the audit of Replicated Security performed by Oak Security and funded by the Cosmos Hub community through Proposal 687. In an effort to move quickly, this release also includes a multisig fix that is effective only for provider. It shouldn't affect the consumer module. + +Note PRs were made in a private security repo. + +[full diff](https://github.com/cosmos/interchain-security/compare/v1.2.0...v1.2.0-multiden-rc0) + +## v1.1.0-multiden + +This release combines two fixes on top of v1.1.0, that we judged were urgent to get onto the Cosmos Hub before the launch of the first ICS consumer chain. This is an emergency release intended for providers. + +The first fix is to enable the use of multisigs and Ledger devices when assigning keys for consumer chains. The second is to prevent a possible DOS vector involving the reward distribution system. + +Note PRs were made in a private security repo. + +[full diff](https://github.com/cosmos/interchain-security/compare/v1.1.0...release/v1.1.0-multiden) + +### Multisig fix + +On April 25th (a week and a half ago), we began receiving reports that validators using multisigs and Ledger devices were getting errors reading Error: unable to resolve type URL /interchain_security.ccv.provider.v1.MsgAssignConsumerKey: tx parse error when attempting to assign consensus keys for consumer chains. + +We quickly narrowed the problem down to issues having to do with using the PubKey type directly in the MsgAssignConsumerKey transaction, and Amino (a deprecated serialization library still used in Ledger devices and multisigs) not being able to handle this. We attempted to fix this with the assistance of the Cosmos-SDK team, but after making no headway for a few days, we decided to simply use a JSON representation of the PubKey in the transaction. This is how it is usually represented anyway. We have verified that this fixes the problem. + +### Distribution fix + +The ICS distribution system works by allowing consumer chains to send rewards to a module address on the provider called the FeePoolAddress. From here they are automatically distributed to all validators and delegators through the distribution system that already exists to distribute staking rewards. The FeePoolAddress is usually blocked so that no tokens can be sent to it, but to enable ICS distribution we had to unblock it. + +We recently realized that unblocking the FeePoolAddress could enable an attacker to send a huge number of different denoms into the distribution system. The distribution system would then attempt to distribute them all, leading to out of memory errors. Fixing a similar attack vector that existed in the distribution system before ICS led us to this realization. + +To fix this problem, we have re-blocked the FeePoolAddress and created a new address called the ConsumerRewardsPool. Consumer chains now send rewards to this new address. There is also a new transaction type called RegisterConsumerRewardDenom. This transaction allows people to register denoms to be used as rewards from consumer chains. It costs 10 Atoms to run this transaction.The Atoms are transferred to the community pool. Only denoms registered with this command are then transferred to the FeePoolAddress and distributed out to delegators and validators. + +## v1.2.1 + +* (fix) Remove SPM [#812](https://github.com/cosmos/interchain-security/pull/812) +* (refactor) Key assignment type safety [#725](https://github.com/cosmos/interchain-security/pull/725) + +## v1.2.0 + +Date: April 13th, 2023 + +* (feat) Soft opt-out [#833](https://github.com/cosmos/interchain-security/pull/833) +* (fix) Correctly handle VSC packet with duplicate val updates on consumer [#846](https://github.com/cosmos/interchain-security/pull/846) +* (chore) bump: sdk v0.45.15-ics [#805](https://github.com/cosmos/interchain-security/pull/805) +* (api) add interchain security consumer QueryParams [#746](https://github.com/cosmos/interchain-security/pull/746) + +## v1.1.1 + +* (fix) Remove SPM [#812](https://github.com/cosmos/interchain-security/pull/812) +* (refactor) Key assignment type safety [#725](https://github.com/cosmos/interchain-security/pull/725) + +## v1.1.0 + +Date: March 24th, 2023 + +* (fix) StopConsumerChain not running in cachedContext [#802](https://github.com/cosmos/interchain-security/pull/802) + +## v1.0.0 + +Date: February 6th, 2023 + +This is the first version of Interchain Security (ICS), also known as _Replicated Security_ (RS). +Replicated Security is a feature which will allow a chain -- referred to as the _provider_ -- to share security with other chains -- referred to as _consumers_. +This means that the provider's validator set will be granted the right to validate consumer chains. +The communication between the provider and the consumer chains is done through the IBC protocol over a unique, ordered channel (one for each consumer chain). Thus, RS is an IBC application. + +### Features / sub-protocols + +RS consist of the following core features: + +- **Channel Initialization**: Enables the provider to add new consumer chains. This process is governance-gated, i.e., to add a new consumer chain, a `ConsumerAdditionProposal` governance proposal must be sent to the provider and it must receive the necessary votes. +- **Validator Set Update**: Enables the provider to + (1) update the consumers on the voting power granted to validators (based on the changes in the active validator set on the provider chain), + and (2) ensure the timely completion of unbonding operations (e.g., undelegations). +- **Consumer Initiated Slashing**: Enables the provider to jail validators for downtime infractions on the consumer chains. +- **Reward Distribution**: Enables the consumers to transfer to the provider (over IBC) a portion of their block rewards as payment for the security provided. Once transferred, these rewards are distributed on the provider using the protocol in the [distribution module of Cosmos SDK](https://docs.cosmos.network/v0.45/modules/distribution/). +- **Consumer Chain Removal**: Enables the provider to remove a consumer either after a `ConsumerRemovalProposal` passes governance or after one of the timeout periods elapses -- `InitTimeoutPeriod`, `VscTimeoutPeriod`, `IBCTimeoutPeriod`. +- **Social Slashing**: Equivocation offenses (double signing etc.) on consumer chains are logged, and then can be used in a governance proposal to slash the validators responsible. + +In addition, RS has the following features: + +- **Key Assignment**: Enables validator operators to use different consensus keys for each consumer chain validator node that they operate. +- **Jail Throttling**: Enables the provider to slow down a "worst case scenario" attack where a malicious consumer binary attempts to jail a significant amount (> 2/3) of the voting power, effectively taking control of the provider. \ No newline at end of file From 0e3e05e1483808de8e70d80a22506d669e8ecad7 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Mon, 8 Jul 2024 16:09:29 +0200 Subject: [PATCH 26/35] address comments --- CHANGELOG.md | 82 ++++++++++--------- app/consumer-democracy/app.go | 2 +- .../proposals_whitelisting.go | 2 +- app/consumer/app.go | 2 +- app/provider/app.go | 2 +- app/sovereign/app.go | 2 +- ...StateMarshalling-20240314151749-32478.fail | 10 --- ...eadAndWriteTrace-20240314151749-32478.fail | 18 ---- x/ccv/provider/keeper/genesis.go | 2 +- x/ccv/provider/keeper/key_assignment.go | 2 +- x/ccv/provider/keeper/msg_server.go | 4 +- x/ccv/provider/keeper/relay.go | 6 +- x/ccv/provider/types/msg.go | 15 +++- 13 files changed, 65 insertions(+), 84 deletions(-) delete mode 100644 tests/e2e/testdata/rapid/TestChainStateMarshalling/TestChainStateMarshalling-20240314151749-32478.fail delete mode 100644 tests/e2e/testdata/rapid/TestReadAndWriteTrace/TestReadAndWriteTrace-20240314151749-32478.fail diff --git a/CHANGELOG.md b/CHANGELOG.md index 78f0892c0b..f8489c31a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,44 +1,4 @@ # CHANGELOG -## v5.0.0 - -❗ *The provider module should not be used with this version.* - -*May 9, 2024* - -### DEPENDENCIES - -- Bump [ibc-go](https://github.com/cosmos/ibc-go) to - [v8.1.x](https://github.com/cosmos/ibc-go/releases/tag/v8.1.0). - ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) -- Bump [CometBFT](https://github.com/cometbft/cometbft) to - [v0.38.4\5](https://github.com/cometbft/cometbft/releases/tag/v0.38.5). - ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) -- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to -[v0.50.x](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.4) -([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) - -### FEATURES - -- [Consumer](x/ccv/consumer) - - Add consumer `MsgUpdateParams` from [cosmos-sdk](https://github.com/cosmos/cosmos-sdk). - ([\#1814](https://github.com/cosmos/interchain-security/pull/1814)). -- [Provider](x/ccv/provider) - - Add provider `MsgUpdateParams` from [cosmos-sdk](https://github.com/cosmos/cosmos-sdk). - ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)). - -### STATE BREAKING - -- Bump [ibc-go](https://github.com/cosmos/ibc-go) to - [v8.1.x](https://github.com/cosmos/ibc-go/releases/tag/v8.1.0). - ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) -- Bump [CometBFT](https://github.com/cometbft/cometbft) to - [v0.38.4\5](https://github.com/cometbft/cometbft/releases/tag/v0.38.5). - ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) -- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to -[v0.50.x](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.4) -([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) -- Revert `PutUnbondingOnHold` behavior to ICS@v1 -([\#1819](https://github.com/cosmos/interchain-security/pull/1819)) ## v4.3.0 @@ -91,6 +51,48 @@ - Allow consumer chains to change their PSS parameters. ([\#1932](https://github.com/cosmos/interchain-security/pull/1932)) +## v5.0.0 + +❗ *The provider module should not be used with this version.* + +*May 9, 2024* + +### DEPENDENCIES + +- Bump [ibc-go](https://github.com/cosmos/ibc-go) to + [v8.1.x](https://github.com/cosmos/ibc-go/releases/tag/v8.1.0). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) +- Bump [CometBFT](https://github.com/cometbft/cometbft) to + [v0.38.4\5](https://github.com/cometbft/cometbft/releases/tag/v0.38.5). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) +- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to +[v0.50.x](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.4) +([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) + +### FEATURES + +- [Consumer](x/ccv/consumer) + - Add consumer `MsgUpdateParams` from [cosmos-sdk](https://github.com/cosmos/cosmos-sdk). + ([\#1814](https://github.com/cosmos/interchain-security/pull/1814)). +- [Provider](x/ccv/provider) + - Add provider `MsgUpdateParams` from [cosmos-sdk](https://github.com/cosmos/cosmos-sdk). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)). + +### STATE BREAKING + +- Bump [ibc-go](https://github.com/cosmos/ibc-go) to + [v8.1.x](https://github.com/cosmos/ibc-go/releases/tag/v8.1.0). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) +- Bump [CometBFT](https://github.com/cometbft/cometbft) to + [v0.38.4\5](https://github.com/cometbft/cometbft/releases/tag/v0.38.5). + ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) +- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to +[v0.50.x](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.4) +([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) +- Revert `PutUnbondingOnHold` behavior to ICS@v1 +([\#1819](https://github.com/cosmos/interchain-security/pull/1819)) + + ## v4.2.0 May 17, 2024 diff --git a/app/consumer-democracy/app.go b/app/consumer-democracy/app.go index 50c2c1da29..664aff84ed 100644 --- a/app/consumer-democracy/app.go +++ b/app/consumer-democracy/app.go @@ -754,7 +754,7 @@ func New( }, ) if err != nil { - panic(fmt.Errorf("failed to create AnteHandler: %s", err)) + panic(fmt.Errorf("failed to create AnteHandler: %w", err)) } app.SetAnteHandler(anteHandler) diff --git a/app/consumer-democracy/proposals_whitelisting.go b/app/consumer-democracy/proposals_whitelisting.go index fb333dc014..eeee5befa2 100644 --- a/app/consumer-democracy/proposals_whitelisting.go +++ b/app/consumer-democracy/proposals_whitelisting.go @@ -29,7 +29,7 @@ type legacyParamChangeKey struct { Subspace, Key string } -// these parameters don't exist in the consumer app -- keeping them as an +// these parameters don't exist in the consumer app -- keeping them as an example var LegacyWhitelistedParams = map[legacyParamChangeKey]struct{}{ // add whitlisted legacy parameters here [cosmos-sdk <= 0.47] // commented parameters are just an example - most params have been moved to their respecitve modules diff --git a/app/consumer/app.go b/app/consumer/app.go index ab86ec8b42..8eb64bf5c6 100644 --- a/app/consumer/app.go +++ b/app/consumer/app.go @@ -576,7 +576,7 @@ func New( }, ) if err != nil { - panic(fmt.Errorf("failed to create AnteHandler: %s", err)) + panic(fmt.Errorf("failed to create AnteHandler: %w", err)) } app.SetAnteHandler(anteHandler) diff --git a/app/provider/app.go b/app/provider/app.go index 8ba64f7928..ffa071855a 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -741,7 +741,7 @@ func New( }, ) if err != nil { - panic(fmt.Errorf("failed to create AnteHandler: %s", err)) + panic(fmt.Errorf("failed to create AnteHandler: %w", err)) } app.SetInitChainer(app.InitChainer) diff --git a/app/sovereign/app.go b/app/sovereign/app.go index 67386cc70a..328fb5e4b9 100644 --- a/app/sovereign/app.go +++ b/app/sovereign/app.go @@ -597,7 +597,7 @@ func New( }, ) if err != nil { - panic(fmt.Errorf("failed to create AnteHandler: %s", err)) + panic(fmt.Errorf("failed to create AnteHandler: %w", err)) } app.SetAnteHandler(anteHandler) diff --git a/tests/e2e/testdata/rapid/TestChainStateMarshalling/TestChainStateMarshalling-20240314151749-32478.fail b/tests/e2e/testdata/rapid/TestChainStateMarshalling/TestChainStateMarshalling-20240314151749-32478.fail deleted file mode 100644 index 14da620099..0000000000 --- a/tests/e2e/testdata/rapid/TestChainStateMarshalling/TestChainStateMarshalling-20240314151749-32478.fail +++ /dev/null @@ -1,10 +0,0 @@ -# -v0.4.8#14881217339431652995 -0x0 -0x5555555555555 -0x0 -0x0 -0x38e38e38e38e4 -0x3 -0x0 -0x0 \ No newline at end of file diff --git a/tests/e2e/testdata/rapid/TestReadAndWriteTrace/TestReadAndWriteTrace-20240314151749-32478.fail b/tests/e2e/testdata/rapid/TestReadAndWriteTrace/TestReadAndWriteTrace-20240314151749-32478.fail deleted file mode 100644 index 12af62a4bf..0000000000 --- a/tests/e2e/testdata/rapid/TestReadAndWriteTrace/TestReadAndWriteTrace-20240314151749-32478.fail +++ /dev/null @@ -1,18 +0,0 @@ -# -v0.4.8#2933927387728423654 -0x5555555555555 -0x0 -0x0 -0x0 -0x0 -0x0 -0x5555555555555 -0x0 -0x0 -0x5555555555555 -0x0 -0x0 -0x38e38e38e38e4 -0x3 -0x0 -0x0 \ No newline at end of file diff --git a/x/ccv/provider/keeper/genesis.go b/x/ccv/provider/keeper/genesis.go index b8d6d179fc..b965e3ed57 100644 --- a/x/ccv/provider/keeper/genesis.go +++ b/x/ccv/provider/keeper/genesis.go @@ -21,7 +21,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState) { err := k.BindPort(ctx, ccv.ProviderPortID) if err != nil { // If the binding fails, the chain MUST NOT start - panic(fmt.Errorf("could not claim port capability: %v", err)) + panic(fmt.Errorf("could not claim port capability: %w", err)) } } diff --git a/x/ccv/provider/keeper/key_assignment.go b/x/ccv/provider/keeper/key_assignment.go index b7d1f2de0b..596c3be606 100644 --- a/x/ccv/provider/keeper/key_assignment.go +++ b/x/ccv/provider/keeper/key_assignment.go @@ -506,7 +506,7 @@ func (k Keeper) ValidatorConsensusKeyInUse(ctx sdk.Context, valAddr sdk.ValAddre val, err := k.stakingKeeper.GetValidator(ctx, valAddr) if err != nil { // Abort TX, do NOT allow validator to be created - panic(fmt.Errorf("error finding newly created validator in staking module: %s", err)) + panic(fmt.Errorf("error finding newly created validator in staking module: %w", err)) } // Get the consensus address of the validator being added diff --git a/x/ccv/provider/keeper/msg_server.go b/x/ccv/provider/keeper/msg_server.go index 4239a7cf41..a9aa6d4379 100644 --- a/x/ccv/provider/keeper/msg_server.go +++ b/x/ccv/provider/keeper/msg_server.go @@ -83,7 +83,7 @@ func (k msgServer) AssignConsumerKey(goCtx context.Context, msg *types.MsgAssign return &types.MsgAssignConsumerKeyResponse{}, nil } -// ConsumerAddition defines a rpc handler method for MsgConsumerAddition +// ConsumerAddition defines an RPC handler method for MsgConsumerAddition func (k msgServer) ConsumerAddition(goCtx context.Context, msg *types.MsgConsumerAddition) (*types.MsgConsumerAdditionResponse, error) { if k.GetAuthority() != msg.Authority { return nil, errorsmod.Wrapf(types.ErrUnauthorized, "expected %s, got %s", k.GetAuthority(), msg.Authority) @@ -97,7 +97,7 @@ func (k msgServer) ConsumerAddition(goCtx context.Context, msg *types.MsgConsume return &types.MsgConsumerAdditionResponse{}, nil } -// ConsumerRemoval defines a rpc handler method for MsgConsumerRemoval +// ConsumerRemoval defines an RPC handler method for MsgConsumerRemoval func (k msgServer) ConsumerRemoval( goCtx context.Context, msg *types.MsgConsumerRemoval) (*types.MsgConsumerRemovalResponse, error) { diff --git a/x/ccv/provider/keeper/relay.go b/x/ccv/provider/keeper/relay.go index 6373e6a7ce..4d8f862c1b 100644 --- a/x/ccv/provider/keeper/relay.go +++ b/x/ccv/provider/keeper/relay.go @@ -215,7 +215,7 @@ func (k Keeper) SendVSCPacketsToChain(ctx sdk.Context, chainID, channelID string } // QueueVSCPackets queues latest validator updates for every registered consumer chain -// failing to GetLastValidators will cause a panic in EndBlock +// failing to GetLastBondedValidators will cause a panic in EndBlock // TODO: decide if this func shouldn't return an error to be propagated to BeginBlocker func (k Keeper) QueueVSCPackets(ctx sdk.Context) { @@ -427,8 +427,8 @@ func (k Keeper) HandleSlashPacket(ctx sdk.Context, chainID string, data ccv.Slas // Obtain validator from staking keeper validator, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, providerConsAddr.ToSdkConsAddr()) - if err != nil && errors.Is(err, stakingtypes.ErrNoValidatorFound) { - k.Logger(ctx).Error("validator not found", "validator", providerConsAddr.String()) + if err != nil { + k.Logger(ctx).Error("validator not found", "validator", providerConsAddr.String(), "error", err) return } diff --git a/x/ccv/provider/types/msg.go b/x/ccv/provider/types/msg.go index 058ee1d2e5..954d5e7cd1 100644 --- a/x/ccv/provider/types/msg.go +++ b/x/ccv/provider/types/msg.go @@ -32,6 +32,7 @@ var ( _ sdk.Msg = (*MsgAssignConsumerKey)(nil) _ sdk.Msg = (*MsgConsumerAddition)(nil) _ sdk.Msg = (*MsgConsumerRemoval)(nil) + _ sdk.Msg = (*MsgConsumerModification)(nil) _ sdk.Msg = (*MsgChangeRewardDenoms)(nil) _ sdk.Msg = (*MsgSubmitConsumerMisbehaviour)(nil) _ sdk.Msg = (*MsgSubmitConsumerDoubleVoting)(nil) @@ -42,6 +43,7 @@ var ( _ sdk.HasValidateBasic = (*MsgAssignConsumerKey)(nil) _ sdk.HasValidateBasic = (*MsgConsumerAddition)(nil) _ sdk.HasValidateBasic = (*MsgConsumerRemoval)(nil) + _ sdk.HasValidateBasic = (*MsgConsumerModification)(nil) _ sdk.HasValidateBasic = (*MsgChangeRewardDenoms)(nil) _ sdk.HasValidateBasic = (*MsgSubmitConsumerMisbehaviour)(nil) _ sdk.HasValidateBasic = (*MsgSubmitConsumerDoubleVoting)(nil) @@ -244,10 +246,6 @@ func (msg *MsgConsumerAddition) ValidateBasic() error { return ErrBlankConsumerChainID } - if strings.TrimSpace(msg.ChainId) == "" { - return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "consumer chain id must not be blank") - } - if msg.InitialHeight.IsZero() { return errorsmod.Wrap(ErrInvalidConsumerAdditionProposal, "initial height cannot be zero") } @@ -306,6 +304,15 @@ func (msg *MsgConsumerRemoval) ValidateBasic() error { return nil } +// ValidateBasic implements the sdk.Msg interface. +func (msg *MsgConsumerModification) ValidateBasic() error { + if strings.TrimSpace(msg.ChainId) == "" { + return ErrBlankConsumerChainID + } + + return nil +} + // NewMsgOptIn creates a new NewMsgOptIn instance. func NewMsgOptIn(chainID string, providerValidatorAddress sdk.ValAddress, consumerConsensusPubKey, signer string) (*MsgOptIn, error) { return &MsgOptIn{ From 542b9bc751da8239af0eab3a0fa8d3f26190acb3 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Mon, 8 Jul 2024 17:50:29 +0200 Subject: [PATCH 27/35] remove cometmock from workflow --- .github/workflows/test.yml | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8790295285..fef4a7d880 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -229,37 +229,6 @@ jobs: run: | make test-e2e-compatibility-tests-latest - test-cometmock: - runs-on: Gaia-Runner-medium - steps: - - uses: actions/checkout@v4 - with: - lfs: true - - name: checkout LFS objects - run: git lfs checkout - - uses: actions/setup-go@v5 - with: - go-version: "1.21" - check-latest: true - cache: true - cache-dependency-path: go.sum - - uses: technote-space/get-diff-action@v6.1.2 - id: git_diff - with: - PATTERNS: | - **/*.go - go.mod - go.sum - **/go.mod - **/go.sum - **/Makefile - Makefile - Dockerfile* - - name: cometmock tests - if: env.GIT_DIFF - run: | - make test-e2e-short-cometmock - test-trace: runs-on: ubuntu-latest steps: From 5d6e92aba76e31aba75d1fc7ec71b4fa0b2a5f19 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Mon, 8 Jul 2024 17:55:58 +0200 Subject: [PATCH 28/35] update validatebasic for consumer modification prop type --- x/ccv/provider/types/msg.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/x/ccv/provider/types/msg.go b/x/ccv/provider/types/msg.go index 954d5e7cd1..f74d8b9d78 100644 --- a/x/ccv/provider/types/msg.go +++ b/x/ccv/provider/types/msg.go @@ -310,6 +310,11 @@ func (msg *MsgConsumerModification) ValidateBasic() error { return ErrBlankConsumerChainID } + err := ValidatePSSFeatures(msg.Top_N, msg.ValidatorsPowerCap) + if err != nil { + return errorsmod.Wrapf(ErrInvalidConsumerModificationProposal, "invalid PSS features: %s", err.Error()) + } + return nil } From edd3d7369949d789e627f43c5b1953a1dac31662 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 9 Jul 2024 08:52:40 +0200 Subject: [PATCH 29/35] add v4.3.1 to changelog --- .../2007-evidence-min-height-filter.md | 2 + .../2007-evidence-min-height-filter.md | 2 + .changelog/v4.3.1/summary.md | 1 + CHANGELOG.md | 188 +----------------- 4 files changed, 12 insertions(+), 181 deletions(-) create mode 100644 .changelog/v4.3.1/bug-fixes/provider/2007-evidence-min-height-filter.md create mode 100644 .changelog/v4.3.1/state-breaking/provider/2007-evidence-min-height-filter.md create mode 100644 .changelog/v4.3.1/summary.md diff --git a/.changelog/v4.3.1/bug-fixes/provider/2007-evidence-min-height-filter.md b/.changelog/v4.3.1/bug-fixes/provider/2007-evidence-min-height-filter.md new file mode 100644 index 0000000000..def0681a0a --- /dev/null +++ b/.changelog/v4.3.1/bug-fixes/provider/2007-evidence-min-height-filter.md @@ -0,0 +1,2 @@ +- Add missing check for the minimum height of evidence in the consumer double-vote handler. +[#2007](https://github.com/cosmos/interchain-security/pull/2007) diff --git a/.changelog/v4.3.1/state-breaking/provider/2007-evidence-min-height-filter.md b/.changelog/v4.3.1/state-breaking/provider/2007-evidence-min-height-filter.md new file mode 100644 index 0000000000..def0681a0a --- /dev/null +++ b/.changelog/v4.3.1/state-breaking/provider/2007-evidence-min-height-filter.md @@ -0,0 +1,2 @@ +- Add missing check for the minimum height of evidence in the consumer double-vote handler. +[#2007](https://github.com/cosmos/interchain-security/pull/2007) diff --git a/.changelog/v4.3.1/summary.md b/.changelog/v4.3.1/summary.md new file mode 100644 index 0000000000..3f21649ea9 --- /dev/null +++ b/.changelog/v4.3.1/summary.md @@ -0,0 +1 @@ +*July 4, 2024* \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index f8489c31a1..7e599621c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,150 +1,7 @@ # CHANGELOG -## v4.3.0 - -*June 20, 2024* - -### BUG FIXES - -- General - - Write unbonding period advisory to stderr instead of stdout - ([\#1921](https://github.com/cosmos/interchain-security/pull/1921)) -- [Provider](x/ccv/provider) - - Apply audit suggestions that include a bug fix in the way we compute the - maximum capped power. - ([\#1925](https://github.com/cosmos/interchain-security/pull/1925)) - - Replace `GetAllConsumerChains` with lightweight version - (`GetAllRegisteredConsumerChainIDs`) that doesn't call into the staking module - ([\#1946](https://github.com/cosmos/interchain-security/pull/1946)) - -### DEPENDENCIES - -- Bump [ibc-go](https://github.com/cosmos/ibc-go) to - [v7.6.0](https://github.com/cosmos/ibc-go/releases/tag/v7.6.0). - ([\#1974](https://github.com/cosmos/interchain-security/pull/1974)) - -### FEATURES - -- [Provider](x/ccv/provider) - - Allow consumer chains to change their PSS parameters. - ([\#1932](https://github.com/cosmos/interchain-security/pull/1932)) - -### IMPROVEMENTS - -- [Provider](x/ccv/provider) - - Only start distributing rewards to validators after they have been validating - for a fixed number of blocks. Introduces the `NumberOfEpochsToStartReceivingRewards` param. - ([\#1929](https://github.com/cosmos/interchain-security/pull/1929)) - -### STATE BREAKING - -- General - - Bump [ibc-go](https://github.com/cosmos/ibc-go) to - [v7.6.0](https://github.com/cosmos/ibc-go/releases/tag/v7.6.0). - ([\#1974](https://github.com/cosmos/interchain-security/pull/1974)) -- [Provider](x/ccv/provider) - - Apply audit suggestions that include a bug fix in the way we compute the - maximum capped power. ([\#1925](https://github.com/cosmos/interchain-security/pull/1925)) - - Only start distributing rewards to validators after they have been validating - for a fixed number of blocks. Introduces the `NumberOfEpochsToStartReceivingRewards` param. - ([\#1929](https://github.com/cosmos/interchain-security/pull/1929)) - - Allow consumer chains to change their PSS parameters. - ([\#1932](https://github.com/cosmos/interchain-security/pull/1932)) - -## v5.0.0 - -❗ *The provider module should not be used with this version.* - -*May 9, 2024* - -### DEPENDENCIES - -- Bump [ibc-go](https://github.com/cosmos/ibc-go) to - [v8.1.x](https://github.com/cosmos/ibc-go/releases/tag/v8.1.0). - ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) -- Bump [CometBFT](https://github.com/cometbft/cometbft) to - [v0.38.4\5](https://github.com/cometbft/cometbft/releases/tag/v0.38.5). - ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) -- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to -[v0.50.x](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.4) -([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) - -### FEATURES - -- [Consumer](x/ccv/consumer) - - Add consumer `MsgUpdateParams` from [cosmos-sdk](https://github.com/cosmos/cosmos-sdk). - ([\#1814](https://github.com/cosmos/interchain-security/pull/1814)). -- [Provider](x/ccv/provider) - - Add provider `MsgUpdateParams` from [cosmos-sdk](https://github.com/cosmos/cosmos-sdk). - ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)). - -### STATE BREAKING - -- Bump [ibc-go](https://github.com/cosmos/ibc-go) to - [v8.1.x](https://github.com/cosmos/ibc-go/releases/tag/v8.1.0). - ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) -- Bump [CometBFT](https://github.com/cometbft/cometbft) to - [v0.38.4\5](https://github.com/cometbft/cometbft/releases/tag/v0.38.5). - ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) -- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to -[v0.50.x](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.4) -([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) -- Revert `PutUnbondingOnHold` behavior to ICS@v1 -([\#1819](https://github.com/cosmos/interchain-security/pull/1819)) - - -## v4.2.0 - -May 17, 2024 - -### API BREAKING - -- [Provider](x/ccv/provider) - - Assigning a key that is already assigned by the same validator will now be a no-op instead of throwing an error. - ([\#1732](https://github.com/cosmos/interchain-security/pull/1732)) - - Changes the `list-consumer-chains` query to include a `min_power_in_top_N` field, as well as fields for all power shaping parameters of the consumer. - ([\#1863](https://github.com/cosmos/interchain-security/pull/1863)) - -### DEPENDENCIES - -- Bump [CometBFT](https://github.com/cometbft/cometbft) to - [v0.37.6](https://github.com/cometbft/cometbft/releases/tag/v0.37.6). - ([\#1876](https://github.com/cosmos/interchain-security/pull/1876)) -- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to - [v0.47.11](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.11). - ([\#1876](https://github.com/cosmos/interchain-security/pull/1876)) - -### FEATURES - -- [Provider](x/ccv/provider) - - Enable Opt In and Top N chains through gov proposals. - ([\#1587](https://github.com/cosmos/interchain-security/pull/1587)) - - Adding the Partial Set Security (PSS) feature cf. [ADR 015](https://cosmos.github.io/interchain-security/adrs/adr-015-partial-set-security). - PSS enables consumer chains to join ICS as _Top N_ or _Opt In_ chains and enables validators to opt to validate the consumer chains they want. - ([\#1809](https://github.com/cosmos/interchain-security/pull/1809)) - - Introduce power-shaping features for consumer chains. The features: (i) allow us to cap the total number of validators that can validate the consumer chain, (ii) set a cap on the maximum voting power (percentage-wise) a validator can have on a consumer chain, and (iii) introduce allowlist and denylists to restrict which validators are allowed or not to validate a consumer chain. - ([\#1830](https://github.com/cosmos/interchain-security/pull/1830)) - - Changes the `list-consumer-chains` query to include a `min_power_in_top_N` field, as well as fields for all power shaping parameters of the consumer. - ([\#1863](https://github.com/cosmos/interchain-security/pull/1863)) - - Introduces the `consumer-validators` query to retrieve the latest set consumer-validator set for a consumer chain. - ([\#1863](https://github.com/cosmos/interchain-security/pull/1867)) - -### STATE BREAKING - -- [Provider](x/ccv/provider) - - Enable Opt In and Top N chains through gov proposals. - ([\#1587](https://github.com/cosmos/interchain-security/pull/1587)) - - Assigning a key that is already assigned by the same validator will now be a no-op instead of throwing an error. - ([\#1732](https://github.com/cosmos/interchain-security/pull/1732)) - - Adding the Partial Set Security feature cf. [ADR 015](https://cosmos.github.io/interchain-security/adrs/adr-015-partial-set-security). - ([\#1809](https://github.com/cosmos/interchain-security/pull/1809)) - - Introduce power-shaping features for consumer chains. The features: (i) allow us to cap the total number of validators that can validate the consumer chain, (ii) set a cap on the maximum voting power (percentage-wise) a validator can have on a consumer chain, and (iii) introduce allowlist and denylists to restrict which validators are allowed or not to validate a consumer chain. - ([\#1830](https://github.com/cosmos/interchain-security/pull/1830)) - ## v5.0.0 -❗ *The provider module should not be used with this version.* - *May 9, 2024* ### DEPENDENCIES @@ -181,53 +38,22 @@ May 17, 2024 ([\#1698](https://github.com/cosmos/interchain-security/pull/1698)) - Revert `PutUnbondingOnHold` behavior to ICS@v1 ([\#1819](https://github.com/cosmos/interchain-security/pull/1819)) -## v4.2.0 -May 17, 2024 +## v4.3.1 -### API BREAKING +*July 4, 2024* -- [Provider](x/ccv/provider) - - Assigning a key that is already assigned by the same validator will now be a no-op instead of throwing an error. - ([\#1732](https://github.com/cosmos/interchain-security/pull/1732)) - - Changes the `list-consumer-chains` query to include a `min_power_in_top_N` field, as well as fields for all power shaping parameters of the consumer. - ([\#1863](https://github.com/cosmos/interchain-security/pull/1863)) - -### DEPENDENCIES - -- Bump [CometBFT](https://github.com/cometbft/cometbft) to - [v0.37.6](https://github.com/cometbft/cometbft/releases/tag/v0.37.6). - ([\#1876](https://github.com/cosmos/interchain-security/pull/1876)) -- Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to - [v0.47.11](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.11). - ([\#1876](https://github.com/cosmos/interchain-security/pull/1876)) - -### FEATURES +### BUG FIXES - [Provider](x/ccv/provider) - - Enable Opt In and Top N chains through gov proposals. - ([\#1587](https://github.com/cosmos/interchain-security/pull/1587)) - - Adding the Partial Set Security (PSS) feature cf. [ADR 015](https://cosmos.github.io/interchain-security/adrs/adr-015-partial-set-security). - PSS enables consumer chains to join ICS as _Top N_ or _Opt In_ chains and enables validators to opt to validate the consumer chains they want. - ([\#1809](https://github.com/cosmos/interchain-security/pull/1809)) - - Introduce power-shaping features for consumer chains. The features: (i) allow us to cap the total number of validators that can validate the consumer chain, (ii) set a cap on the maximum voting power (percentage-wise) a validator can have on a consumer chain, and (iii) introduce allowlist and denylists to restrict which validators are allowed or not to validate a consumer chain. - ([\#1830](https://github.com/cosmos/interchain-security/pull/1830)) - - Changes the `list-consumer-chains` query to include a `min_power_in_top_N` field, as well as fields for all power shaping parameters of the consumer. - ([\#1863](https://github.com/cosmos/interchain-security/pull/1863)) - - Introduces the `consumer-validators` query to retrieve the latest set consumer-validator set for a consumer chain. - ([\#1863](https://github.com/cosmos/interchain-security/pull/1867)) + - Add missing check for the minimum height of evidence in the consumer double-vote handler. + [#2007](https://github.com/cosmos/interchain-security/pull/2007) ### STATE BREAKING - [Provider](x/ccv/provider) - - Enable Opt In and Top N chains through gov proposals. - ([\#1587](https://github.com/cosmos/interchain-security/pull/1587)) - - Assigning a key that is already assigned by the same validator will now be a no-op instead of throwing an error. - ([\#1732](https://github.com/cosmos/interchain-security/pull/1732)) - - Adding the Partial Set Security feature cf. [ADR 015](https://cosmos.github.io/interchain-security/adrs/adr-015-partial-set-security). - ([\#1809](https://github.com/cosmos/interchain-security/pull/1809)) - - Introduce power-shaping features for consumer chains. The features: (i) allow us to cap the total number of validators that can validate the consumer chain, (ii) set a cap on the maximum voting power (percentage-wise) a validator can have on a consumer chain, and (iii) introduce allowlist and denylists to restrict which validators are allowed or not to validate a consumer chain. - ([\#1830](https://github.com/cosmos/interchain-security/pull/1830)) + - Add missing check for the minimum height of evidence in the consumer double-vote handler. + [#2007](https://github.com/cosmos/interchain-security/pull/2007) ## v4.3.0 From e5f982e67957ecf1008aef8edb4e6e6e2594fc7f Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 9 Jul 2024 09:06:26 +0200 Subject: [PATCH 30/35] Update app/consumer-democracy/proposals_whitelisting.go Co-authored-by: bernd-m <43466467+bermuell@users.noreply.github.com> --- app/consumer-democracy/proposals_whitelisting.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/consumer-democracy/proposals_whitelisting.go b/app/consumer-democracy/proposals_whitelisting.go index eeee5befa2..975c9dbbad 100644 --- a/app/consumer-democracy/proposals_whitelisting.go +++ b/app/consumer-democracy/proposals_whitelisting.go @@ -31,8 +31,8 @@ type legacyParamChangeKey struct { // these parameters don't exist in the consumer app -- keeping them as an example var LegacyWhitelistedParams = map[legacyParamChangeKey]struct{}{ - // add whitlisted legacy parameters here [cosmos-sdk <= 0.47] - // commented parameters are just an example - most params have been moved to their respecitve modules + // add whitelisted legacy parameters here [cosmos-sdk <= 0.47] + // commented parameters are just an example - most params have been moved to their respective modules // and they cannot be changed through legacy governance proposals {Subspace: banktypes.ModuleName, Key: "SendEnabled"}: {}, } From f65fee6bc02f4d44b15d702ca6240b2d3be71a2b Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 9 Jul 2024 14:37:17 +0200 Subject: [PATCH 31/35] nits + bump SDK to v0.50.7 --- .../2007-evidence-min-height-filter.md | 2 - .../unreleased/dependencies/2013-bump-sdk.md | 2 +- .../state-breaking/2013-bump-sdk.md | 2 +- .../2007-evidence-min-height-filter.md | 2 - app/provider/app.go | 2 - go.mod | 48 ++++----- go.sum | 100 +++++++++--------- 7 files changed, 76 insertions(+), 82 deletions(-) delete mode 100644 .changelog/unreleased/bug-fixes/provider/2007-evidence-min-height-filter.md delete mode 100644 .changelog/unreleased/state-breaking/provider/2007-evidence-min-height-filter.md diff --git a/.changelog/unreleased/bug-fixes/provider/2007-evidence-min-height-filter.md b/.changelog/unreleased/bug-fixes/provider/2007-evidence-min-height-filter.md deleted file mode 100644 index def0681a0a..0000000000 --- a/.changelog/unreleased/bug-fixes/provider/2007-evidence-min-height-filter.md +++ /dev/null @@ -1,2 +0,0 @@ -- Add missing check for the minimum height of evidence in the consumer double-vote handler. -[#2007](https://github.com/cosmos/interchain-security/pull/2007) diff --git a/.changelog/unreleased/dependencies/2013-bump-sdk.md b/.changelog/unreleased/dependencies/2013-bump-sdk.md index 47c4361f49..34354e35e7 100644 --- a/.changelog/unreleased/dependencies/2013-bump-sdk.md +++ b/.changelog/unreleased/dependencies/2013-bump-sdk.md @@ -1,3 +1,3 @@ - Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to -[v0.50.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.5) +[v0.50.7](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.7) ([\#2013](https://github.com/cosmos/interchain-security/pull/2013)) \ No newline at end of file diff --git a/.changelog/unreleased/state-breaking/2013-bump-sdk.md b/.changelog/unreleased/state-breaking/2013-bump-sdk.md index 47c4361f49..34354e35e7 100644 --- a/.changelog/unreleased/state-breaking/2013-bump-sdk.md +++ b/.changelog/unreleased/state-breaking/2013-bump-sdk.md @@ -1,3 +1,3 @@ - Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to -[v0.50.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.5) +[v0.50.7](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.7) ([\#2013](https://github.com/cosmos/interchain-security/pull/2013)) \ No newline at end of file diff --git a/.changelog/unreleased/state-breaking/provider/2007-evidence-min-height-filter.md b/.changelog/unreleased/state-breaking/provider/2007-evidence-min-height-filter.md deleted file mode 100644 index def0681a0a..0000000000 --- a/.changelog/unreleased/state-breaking/provider/2007-evidence-min-height-filter.md +++ /dev/null @@ -1,2 +0,0 @@ -- Add missing check for the minimum height of evidence in the consumer double-vote handler. -[#2007](https://github.com/cosmos/interchain-security/pull/2007) diff --git a/app/provider/app.go b/app/provider/app.go index ffa071855a..23262161b4 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -1058,7 +1058,5 @@ func MakeTestEncodingConfig() appencoding.EncodingConfig { func makeEncodingConfig() appencoding.EncodingConfig { encodingConfig := appencoding.MakeTestEncodingConfig() - // std.RegisterLegacyAminoCodec(encodingConfig.Amino) - // std.RegisterInterfaces(encodingConfig.InterfaceRegistry) return encodingConfig } diff --git a/go.mod b/go.mod index 35be2495a4..672291b9cf 100644 --- a/go.mod +++ b/go.mod @@ -7,8 +7,8 @@ require ( cosmossdk.io/math v1.3.0 github.com/cometbft/cometbft v0.38.7 github.com/cometbft/cometbft-db v0.12.0 // indirect - github.com/cosmos/cosmos-sdk v0.50.5 - github.com/cosmos/gogoproto v1.4.11 + github.com/cosmos/cosmos-sdk v0.50.7 + github.com/cosmos/gogoproto v1.4.12 github.com/cosmos/ics23/go v0.10.0 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.4 @@ -20,12 +20,12 @@ require ( github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 - golang.org/x/net v0.23.0 // indirect - golang.org/x/sys v0.18.0 // indirect - google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect - google.golang.org/grpc v1.62.1 + golang.org/x/crypto v0.22.0 // indirect + golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 + golang.org/x/net v0.24.0 // indirect + golang.org/x/sys v0.19.0 // indirect + google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/grpc v1.63.2 google.golang.org/protobuf v1.33.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -36,7 +36,7 @@ require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.6 // indirect cloud.google.com/go/storage v1.36.0 // indirect - cosmossdk.io/api v0.7.3 + cosmossdk.io/api v0.7.5 cosmossdk.io/core v0.11.0 cosmossdk.io/depinject v1.0.0-alpha.4 // indirect filippo.io/edwards25519 v1.0.0 // indirect @@ -48,14 +48,14 @@ require ( github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.4 + github.com/cosmos/cosmos-proto v1.0.0-beta.5 github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect - github.com/cosmos/iavl v1.0.1 // indirect + github.com/cosmos/iavl v1.1.2 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc @@ -111,13 +111,13 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect - github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc // indirect + github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.18.0 // indirect - github.com/prometheus/client_model v0.6.0 // indirect - github.com/prometheus/common v0.47.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/client_golang v1.19.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.52.2 // indirect + github.com/prometheus/procfs v0.13.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rs/cors v1.8.3 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect @@ -135,7 +135,7 @@ require ( go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect go.opencensus.io v0.24.0 // indirect golang.org/x/oauth2 v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect + golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/api v0.171.0 // indirect google.golang.org/appengine v1.6.8 // indirect @@ -150,18 +150,18 @@ require ( cosmossdk.io/client/v2 v2.0.0-beta.1 cosmossdk.io/collections v0.4.0 cosmossdk.io/log v1.3.1 - cosmossdk.io/store v1.0.2 + cosmossdk.io/store v1.1.0 cosmossdk.io/tools/confix v0.1.1 cosmossdk.io/x/evidence v0.1.0 cosmossdk.io/x/feegrant v0.1.0 - cosmossdk.io/x/tx v0.13.1 + cosmossdk.io/x/tx v0.13.3 cosmossdk.io/x/upgrade v0.1.1 github.com/cosmos/cosmos-db v1.0.2 github.com/cosmos/ibc-go/modules/capability v1.0.0 github.com/cosmos/ibc-go/v8 v8.2.1 github.com/informalsystems/itf-go v0.0.1 github.com/spf13/viper v1.18.2 - golang.org/x/mod v0.15.0 + golang.org/x/mod v0.17.0 google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 ) @@ -186,7 +186,7 @@ require ( github.com/google/flatbuffers v1.12.1 // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect - github.com/hashicorp/go-metrics v0.5.2 // indirect + github.com/hashicorp/go-metrics v0.5.3 // indirect github.com/hashicorp/go-plugin v1.5.2 // indirect github.com/hashicorp/yamux v0.1.1 // indirect github.com/iancoleman/strcase v0.3.0 // indirect @@ -207,9 +207,9 @@ require ( go.opentelemetry.io/otel/trace v1.24.0 // indirect go.uber.org/mock v0.2.0 // indirect go.uber.org/multierr v1.10.0 // indirect - golang.org/x/sync v0.6.0 // indirect + golang.org/x/sync v0.7.0 // indirect golang.org/x/time v0.5.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect gotest.tools/v3 v3.5.1 // indirect ) diff --git a/go.sum b/go.sum index 6de4eeaa49..07b35d5a04 100644 --- a/go.sum +++ b/go.sum @@ -184,8 +184,8 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cosmossdk.io/api v0.7.3 h1:V815i8YOwOAQa1rLCsSMjVG5Gnzs02JLq+l7ks8s1jk= -cosmossdk.io/api v0.7.3/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= +cosmossdk.io/api v0.7.5 h1:eMPTReoNmGUm8DeiQL9DyM8sYDjEhWzL1+nLbI9DqtQ= +cosmossdk.io/api v0.7.5/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= cosmossdk.io/client/v2 v2.0.0-beta.1 h1:XkHh1lhrLYIT9zKl7cIOXUXg2hdhtjTPBUfqERNA1/Q= cosmossdk.io/client/v2 v2.0.0-beta.1/go.mod h1:JEUSu9moNZQ4kU3ir1DKD5eU4bllmAexrGWjmb9k8qU= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= @@ -200,8 +200,8 @@ cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -cosmossdk.io/store v1.0.2 h1:lSg5BTvJBHUDwswNNyeh4K/CbqiHER73VU4nDNb8uk0= -cosmossdk.io/store v1.0.2/go.mod h1:EFtENTqVTuWwitGW1VwaBct+yDagk7oG/axBMPH+FXs= +cosmossdk.io/store v1.1.0 h1:LnKwgYMc9BInn9PhpTFEQVbL9UK475G2H911CGGnWHk= +cosmossdk.io/store v1.1.0/go.mod h1:oZfW/4Fc/zYqu3JmQcQdUJ3fqu5vnYTn3LZFFy8P8ng= cosmossdk.io/tools/confix v0.1.1 h1:aexyRv9+y15veH3Qw16lxQwo+ki7r2I+g0yNTEFEQM8= cosmossdk.io/tools/confix v0.1.1/go.mod h1:nQVvP1tHsGXS83PonPVWJtSbddIqyjEw99L4M3rPJyQ= cosmossdk.io/x/circuit v0.1.0 h1:IAej8aRYeuOMritczqTlljbUVHq1E85CpBqaCTwYgXs= @@ -210,8 +210,8 @@ cosmossdk.io/x/evidence v0.1.0 h1:J6OEyDl1rbykksdGynzPKG5R/zm6TacwW2fbLTW4nCk= cosmossdk.io/x/evidence v0.1.0/go.mod h1:hTaiiXsoiJ3InMz1uptgF0BnGqROllAN8mwisOMMsfw= cosmossdk.io/x/feegrant v0.1.0 h1:c7s3oAq/8/UO0EiN1H5BIjwVntujVTkYs35YPvvrdQk= cosmossdk.io/x/feegrant v0.1.0/go.mod h1:4r+FsViJRpcZif/yhTn+E0E6OFfg4n0Lx+6cCtnZElU= -cosmossdk.io/x/tx v0.13.1 h1:Mg+EMp67Pz+NukbJqYxuo8uRp7N/a9uR+oVS9pONtj8= -cosmossdk.io/x/tx v0.13.1/go.mod h1:CBCU6fsRVz23QGFIQBb1DNX2DztJCf3jWyEkHY2nJQ0= +cosmossdk.io/x/tx v0.13.3 h1:Ha4mNaHmxBc6RMun9aKuqul8yHiL78EKJQ8g23Zf73g= +cosmossdk.io/x/tx v0.13.3/go.mod h1:I8xaHv0rhUdIvIdptKIqzYy27+n2+zBVaxO6fscFhys= cosmossdk.io/x/upgrade v0.1.1 h1:aoPe2gNvH+Gwt/Pgq3dOxxQVU3j5P6Xf+DaUJTDZATc= cosmossdk.io/x/upgrade v0.1.1/go.mod h1:MNLptLPcIFK9CWt7Ra//8WUZAxweyRDNcbs5nkOcQy0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -289,8 +289,8 @@ github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInq github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= @@ -344,19 +344,19 @@ github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= github.com/cosmos/cosmos-db v1.0.2 h1:hwMjozuY1OlJs/uh6vddqnk9j7VamLv+0DBlbEXbAKs= github.com/cosmos/cosmos-db v1.0.2/go.mod h1:Z8IXcFJ9PqKK6BIsVOB3QXtkKoqUOp1vRvPT39kOXEA= -github.com/cosmos/cosmos-proto v1.0.0-beta.4 h1:aEL7tU/rLOmxZQ9z4i7mzxcLbSCY48OdY7lIWTLG7oU= -github.com/cosmos/cosmos-proto v1.0.0-beta.4/go.mod h1:oeB+FyVzG3XrQJbJng0EnV8Vljfk9XvTIpGILNU/9Co= -github.com/cosmos/cosmos-sdk v0.50.5 h1:MOEi+DKYgW67YaPgB+Pf+nHbD3V9S/ayitRKJYLfGIA= -github.com/cosmos/cosmos-sdk v0.50.5/go.mod h1:oV/k6GJgXV9QPoM2fsYDPPsyPBgQbdotv532O6Mz1OQ= +github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= +github.com/cosmos/cosmos-sdk v0.50.7 h1:LsBGKxifENR/DN4E1RZaitsyL93HU44x0p8EnMHp4V4= +github.com/cosmos/cosmos-sdk v0.50.7/go.mod h1:84xDDJEHttRT7NDGwBaUOLVOMN0JNE9x7NbsYIxXs1s= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= -github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= -github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= -github.com/cosmos/iavl v1.0.1 h1:D+mYbcRO2wptYzOM1Hxl9cpmmHU1ZEt9T2Wv5nZTeUw= -github.com/cosmos/iavl v1.0.1/go.mod h1:8xIUkgVvwvVrBu81scdPty+/Dx9GqwHnAvXz4cwF7RY= +github.com/cosmos/gogoproto v1.4.12 h1:vB6Lbe/rtnYGjQuFxkPiPYiCybqFT8QvLipDZP8JpFE= +github.com/cosmos/gogoproto v1.4.12/go.mod h1:LnZob1bXRdUoqMMtwYlcR3wjiElmlC+FkjaZRv1/eLY= +github.com/cosmos/iavl v1.1.2 h1:zL9FK7C4L/P4IF1Dm5fIwz0WXCnn7Bp1M2FxH0ayM7Y= +github.com/cosmos/iavl v1.1.2/go.mod h1:jLeUvm6bGT1YutCaL2fIar/8vGUE8cPZvh/gXEWDaDM= github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= github.com/cosmos/ibc-go/v8 v8.2.1 h1:MTsnZZjxvGD4Fv5pYyx5UkELafSX0rlPt6IfsE2BpTQ= @@ -654,8 +654,8 @@ github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVH github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-metrics v0.5.2 h1:ErEYO2f//CjKsUDw4SmLzelsK6L3ZmOAR/4P9iS7ruY= -github.com/hashicorp/go-metrics v0.5.2/go.mod h1:KEjodfebIOuBYSAe/bHTm+HChmKSxAOXPBieMLYozDE= +github.com/hashicorp/go-metrics v0.5.3 h1:M5uADWMOGCTUNU1YuC4hfknOeHNaX54LDm4oYSucoNE= +github.com/hashicorp/go-metrics v0.5.3/go.mod h1:KEjodfebIOuBYSAe/bHTm+HChmKSxAOXPBieMLYozDE= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-plugin v1.5.2 h1:aWv8eimFqWlsEiMrYZdPYl+FdHaBJSN4AWwGWfT1G2Y= @@ -868,8 +868,8 @@ github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6 github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc h1:8bQZVK1X6BJR/6nYUPxQEP+ReTsceJTKizeuwjWOPUA= -github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 h1:jik8PHtAIsPlCRJjJzl4udgEf7hawInF9texMeO2jrU= +github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= @@ -890,32 +890,32 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= -github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= -github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/common v0.52.2 h1:LW8Vk7BccEdONfrJBDffQGRtpSzi5CQaRZGtboOO2ck= +github.com/prometheus/common v0.52.2/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= +github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -1082,8 +1082,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1095,8 +1095,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1124,8 +1124,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1186,8 +1186,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1229,8 +1229,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1327,13 +1327,13 @@ golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1416,8 +1416,8 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1594,12 +1594,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 h1:rIo7ocm2roD9DcFIX67Ym8icoGCKSARAiPljFhh5suQ= google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c h1:lfpJ/2rWPa/kJgxyyXM8PrNnfCzcmxJ265mADgwmvLI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1641,8 +1641,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= -google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= From 41c17b292fe71d52f3626fa31fa5f8ee1a6ad3b1 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 10 Jul 2024 11:24:02 +0200 Subject: [PATCH 32/35] nits + use comet v38.9 --- .changelog/unreleased/dependencies/2013-bump-comet.md | 2 +- .changelog/unreleased/state-breaking/2013-bump-comet.md | 2 +- app/consumer-democracy/app.go | 1 - go.mod | 3 ++- go.sum | 6 ++++-- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.changelog/unreleased/dependencies/2013-bump-comet.md b/.changelog/unreleased/dependencies/2013-bump-comet.md index 9af87a1038..a68b1e78fe 100644 --- a/.changelog/unreleased/dependencies/2013-bump-comet.md +++ b/.changelog/unreleased/dependencies/2013-bump-comet.md @@ -1,3 +1,3 @@ - Bump [CometBFT](https://github.com/cometbft/cometbft) to - [v0.38.7](https://github.com/cometbft/cometbft/releases/tag/v0.38.7). + [v0.38.9](https://github.com/cometbft/cometbft/releases/tag/v0.38.9). ([\#2013](https://github.com/cosmos/interchain-security/pull/2013)) \ No newline at end of file diff --git a/.changelog/unreleased/state-breaking/2013-bump-comet.md b/.changelog/unreleased/state-breaking/2013-bump-comet.md index 9af87a1038..a68b1e78fe 100644 --- a/.changelog/unreleased/state-breaking/2013-bump-comet.md +++ b/.changelog/unreleased/state-breaking/2013-bump-comet.md @@ -1,3 +1,3 @@ - Bump [CometBFT](https://github.com/cometbft/cometbft) to - [v0.38.7](https://github.com/cometbft/cometbft/releases/tag/v0.38.7). + [v0.38.9](https://github.com/cometbft/cometbft/releases/tag/v0.38.9). ([\#2013](https://github.com/cosmos/interchain-security/pull/2013)) \ No newline at end of file diff --git a/app/consumer-democracy/app.go b/app/consumer-democracy/app.go index 664aff84ed..6ceb8952e4 100644 --- a/app/consumer-democracy/app.go +++ b/app/consumer-democracy/app.go @@ -151,7 +151,6 @@ var ( mint.AppModuleBasic{}, ccvdistr.AppModuleBasic{}, gov.NewAppModuleBasic( - // TODO: eventually remove upgrade proposal handler and cancel proposal handler []govclient.ProposalHandler{ paramsclient.ProposalHandler, }, diff --git a/go.mod b/go.mod index 672291b9cf..6e37628cbd 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22.2 require ( cosmossdk.io/errors v1.0.1 cosmossdk.io/math v1.3.0 - github.com/cometbft/cometbft v0.38.7 + github.com/cometbft/cometbft v0.38.9 github.com/cometbft/cometbft-db v0.12.0 // indirect github.com/cosmos/cosmos-sdk v0.50.7 github.com/cosmos/gogoproto v1.4.12 @@ -188,6 +188,7 @@ require ( github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-metrics v0.5.3 // indirect github.com/hashicorp/go-plugin v1.5.2 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/yamux v0.1.1 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/kr/pretty v0.3.1 // indirect diff --git a/go.sum b/go.sum index 07b35d5a04..218075bf11 100644 --- a/go.sum +++ b/go.sum @@ -330,8 +330,8 @@ github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/cometbft/cometbft v0.38.7 h1:ULhIOJ9+LgSy6nLekhq9ae3juX3NnQUMMPyVdhZV6Hk= -github.com/cometbft/cometbft v0.38.7/go.mod h1:HIyf811dFMI73IE0F7RrnY/Fr+d1+HuJAgtkEpQjCMY= +github.com/cometbft/cometbft v0.38.9 h1:cJBJBG0mPKz+sqelCi/hlfZjadZQGdDNnu6YQ1ZsUHQ= +github.com/cometbft/cometbft v0.38.9/go.mod h1:xOoGZrtUT+A5izWfHSJgl0gYZUE7lu7Z2XIS1vWG/QQ= github.com/cometbft/cometbft-db v0.12.0 h1:v77/z0VyfSU7k682IzZeZPFZrQAKiQwkqGN0QzAjMi0= github.com/cometbft/cometbft-db v0.12.0/go.mod h1:aX2NbCrjNVd2ZajYxt1BsiFf/Z+TQ2MN0VxdicheYuw= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= @@ -678,6 +678,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= From 2d39889b89a82cefdca25f5606b665758f0efde0 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 9 Jul 2024 14:44:26 +0200 Subject: [PATCH 33/35] add missing check to UpdateParams func in x/provider and x/consumer --- x/ccv/consumer/keeper/msg_server.go | 4 ++++ x/ccv/provider/keeper/msg_server.go | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/x/ccv/consumer/keeper/msg_server.go b/x/ccv/consumer/keeper/msg_server.go index 6031101b17..ce3e67be5c 100644 --- a/x/ccv/consumer/keeper/msg_server.go +++ b/x/ccv/consumer/keeper/msg_server.go @@ -29,6 +29,10 @@ func (k msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParam return nil, errorsmod.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", k.authority, msg.Authority) } + if err := msg.Params.Validate(); err != nil { + return nil, err + } + ctx := sdk.UnwrapSDKContext(goCtx) k.Keeper.SetParams(ctx, msg.Params) diff --git a/x/ccv/provider/keeper/msg_server.go b/x/ccv/provider/keeper/msg_server.go index a9aa6d4379..08429c55a8 100644 --- a/x/ccv/provider/keeper/msg_server.go +++ b/x/ccv/provider/keeper/msg_server.go @@ -34,6 +34,10 @@ func (k msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParam return nil, errorsmod.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", k.authority, msg.Authority) } + if err := msg.Params.Validate(); err != nil { + return nil, err + } + ctx := sdk.UnwrapSDKContext(goCtx) k.Keeper.SetParams(ctx, msg.Params) From 444e63443094d4d8db7eb025ee11113e8836669b Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 10 Jul 2024 15:58:04 +0200 Subject: [PATCH 34/35] add missing field in MsgConsumerAddition handler --- x/ccv/provider/keeper/proposal.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/x/ccv/provider/keeper/proposal.go b/x/ccv/provider/keeper/proposal.go index ba6cf2df0a..8d471f086b 100644 --- a/x/ccv/provider/keeper/proposal.go +++ b/x/ccv/provider/keeper/proposal.go @@ -40,6 +40,11 @@ func (k Keeper) HandleConsumerAdditionProposal(ctx sdk.Context, proposal *types. BlocksPerDistributionTransmission: proposal.BlocksPerDistributionTransmission, HistoricalEntries: proposal.HistoricalEntries, DistributionTransmissionChannel: proposal.DistributionTransmissionChannel, + Top_N: proposal.Top_N, + ValidatorsPowerCap: proposal.ValidatorsPowerCap, + ValidatorSetCap: proposal.ValidatorSetCap, + Allowlist: proposal.Allowlist, + Denylist: proposal.Denylist, } return k.HandleLegacyConsumerAdditionProposal(ctx, &p) From 322cb0059b6b4c1b354b629c9c78e3d06f7795a8 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 10 Jul 2024 16:00:46 +0200 Subject: [PATCH 35/35] nit --- x/ccv/democracy/distribution/module.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/ccv/democracy/distribution/module.go b/x/ccv/democracy/distribution/module.go index 9e0bdacbb6..310e542b6a 100644 --- a/x/ccv/democracy/distribution/module.go +++ b/x/ccv/democracy/distribution/module.go @@ -66,7 +66,7 @@ func NewAppModule( // BeginBlock implements HasBeginBlocker interface // The cosmos-sdk/distribution BeginBlocker functionality is replicated here, -// however it no proposer awards are allocated. +// however no proposer awards are allocated. func (am AppModule) BeginBlock(goCtx context.Context) error { ctx := sdk.UnwrapSDKContext(goCtx) defer telemetry.ModuleMeasureSince(distrtypes.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)