diff --git a/.changelog/config.toml b/.changelog/config.toml new file mode 100644 index 0000000000..5ad5d5cc42 --- /dev/null +++ b/.changelog/config.toml @@ -0,0 +1,21 @@ +project_url = "https://github.com/cosmos/interchain-security" + +# Settings related to components/sub-modules. Only relevant if you make use of +# components/sub-modules. +[components] + +# The title to use for the section of entries not relating to a specific +# component. +general_entries_title = "General" + +# The number of spaces to inject before each component-related entry. +entry_indent = 2 + + # The components themselves. Each component has a name (used when rendered + # to Markdown) and a path relative to the project folder (i.e. relative to + # the parent of the `.changelog` folder). + [components.all] + provider = { name = "Provider", path = "x/ccv/provider" } + consumer = { name = "Consumer", path = "x/ccv/consumer" } + tests = { name = "Tests", path = "tests" } + docs = { name = "Documentation", path = "docs/docs" } \ No newline at end of file diff --git a/.changelog/epilogue.md b/.changelog/epilogue.md new file mode 100644 index 0000000000..861dc712e3 --- /dev/null +++ b/.changelog/epilogue.md @@ -0,0 +1,197 @@ +## v3.1.0 + +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](./x/ccv/provider/keeper/migration.go). See the provider module's `ConsensusVersion` in [module](./x/ccv/provider/module.go) + +Upgrading a consumer from `v1.2.0-multiden` to `v2.0.0` will NOT require state migrations. See the consumer module's `ConsensusVersion` in [module](./x/ccv/consumer/module.go) + +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) cosumer 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 diff --git a/.changelog/unreleased/api-breaking/provider/1340-add-cryptographic-verification-of-equivocation-feature.md b/.changelog/unreleased/api-breaking/provider/1340-add-cryptographic-verification-of-equivocation-feature.md new file mode 100644 index 0000000000..c50662be72 --- /dev/null +++ b/.changelog/unreleased/api-breaking/provider/1340-add-cryptographic-verification-of-equivocation-feature.md @@ -0,0 +1,2 @@ +- Deprecate equivocation proposals. +([\#1340](https://github.com/cosmos/interchain-security/pull/1340)) \ No newline at end of file diff --git a/.changelog/unreleased/bug-fixes/consumer/1146-pending-packets.md b/.changelog/unreleased/bug-fixes/consumer/1146-pending-packets.md new file mode 100644 index 0000000000..0bab707fec --- /dev/null +++ b/.changelog/unreleased/bug-fixes/consumer/1146-pending-packets.md @@ -0,0 +1,2 @@ +- 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/unreleased/bug-fixes/consumer/1150-revert-wire-breaking.md b/.changelog/unreleased/bug-fixes/consumer/1150-revert-wire-breaking.md new file mode 100644 index 0000000000..067448e770 --- /dev/null +++ b/.changelog/unreleased/bug-fixes/consumer/1150-revert-wire-breaking.md @@ -0,0 +1,2 @@ +- 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/unreleased/bug-fixes/consumer/1244-validate-transfer.md b/.changelog/unreleased/bug-fixes/consumer/1244-validate-transfer.md new file mode 100644 index 0000000000..2d94c79c75 --- /dev/null +++ b/.changelog/unreleased/bug-fixes/consumer/1244-validate-transfer.md @@ -0,0 +1,2 @@ +- 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/unreleased/bug-fixes/consumer/1262-fee-pool-addr.md b/.changelog/unreleased/bug-fixes/consumer/1262-fee-pool-addr.md new file mode 100644 index 0000000000..bbb54db2e3 --- /dev/null +++ b/.changelog/unreleased/bug-fixes/consumer/1262-fee-pool-addr.md @@ -0,0 +1,2 @@ +- 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/unreleased/bug-fixes/consumer/1295-migration.md b/.changelog/unreleased/bug-fixes/consumer/1295-migration.md new file mode 100644 index 0000000000..739b08dc39 --- /dev/null +++ b/.changelog/unreleased/bug-fixes/consumer/1295-migration.md @@ -0,0 +1,2 @@ +- 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/unreleased/dependencies/1196-bump-ibc.md b/.changelog/unreleased/dependencies/1196-bump-ibc.md new file mode 100644 index 0000000000..fcf4450150 --- /dev/null +++ b/.changelog/unreleased/dependencies/1196-bump-ibc.md @@ -0,0 +1,3 @@ +- 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/unreleased/dependencies/1258-bump-ibc.md b/.changelog/unreleased/dependencies/1258-bump-ibc.md new file mode 100644 index 0000000000..68c6e2b104 --- /dev/null +++ b/.changelog/unreleased/dependencies/1258-bump-ibc.md @@ -0,0 +1,3 @@ +- 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/unreleased/dependencies/1258-bump-sdk.md b/.changelog/unreleased/dependencies/1258-bump-sdk.md new file mode 100644 index 0000000000..7344fac97e --- /dev/null +++ b/.changelog/unreleased/dependencies/1258-bump-sdk.md @@ -0,0 +1,3 @@ +- 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/unreleased/dependencies/1259-bump-sdk.md b/.changelog/unreleased/dependencies/1259-bump-sdk.md new file mode 100644 index 0000000000..247c623b7d --- /dev/null +++ b/.changelog/unreleased/dependencies/1259-bump-sdk.md @@ -0,0 +1,3 @@ +- 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/unreleased/dependencies/1373-bump-ibc.md b/.changelog/unreleased/dependencies/1373-bump-ibc.md new file mode 100644 index 0000000000..efe4e0c286 --- /dev/null +++ b/.changelog/unreleased/dependencies/1373-bump-ibc.md @@ -0,0 +1,3 @@ +- 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/unreleased/features/1336-quint-model.md b/.changelog/unreleased/features/1336-quint-model.md new file mode 100644 index 0000000000..96c4562b32 --- /dev/null +++ b/.changelog/unreleased/features/1336-quint-model.md @@ -0,0 +1,2 @@ +- 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/unreleased/features/consumer/1024-jail-throttling-v2.md b/.changelog/unreleased/features/consumer/1024-jail-throttling-v2.md new file mode 100644 index 0000000000..7570facb34 --- /dev/null +++ b/.changelog/unreleased/features/consumer/1024-jail-throttling-v2.md @@ -0,0 +1,2 @@ +- 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/unreleased/features/consumer/1164-provider-info-query.md b/.changelog/unreleased/features/consumer/1164-provider-info-query.md new file mode 100644 index 0000000000..fc1d27b964 --- /dev/null +++ b/.changelog/unreleased/features/consumer/1164-provider-info-query.md @@ -0,0 +1,4 @@ +- 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/unreleased/features/provider/1076-export-timestamps.md b/.changelog/unreleased/features/provider/1076-export-timestamps.md new file mode 100644 index 0000000000..f2a8608f8b --- /dev/null +++ b/.changelog/unreleased/features/provider/1076-export-timestamps.md @@ -0,0 +1,2 @@ +- 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/unreleased/features/provider/1321-jail-throttling-v2.md b/.changelog/unreleased/features/provider/1321-jail-throttling-v2.md new file mode 100644 index 0000000000..dd3b1a2852 --- /dev/null +++ b/.changelog/unreleased/features/provider/1321-jail-throttling-v2.md @@ -0,0 +1,2 @@ +- 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/unreleased/features/provider/1339-check-key-assignment-in-use.md b/.changelog/unreleased/features/provider/1339-check-key-assignment-in-use.md new file mode 100644 index 0000000000..9f274f7bb4 --- /dev/null +++ b/.changelog/unreleased/features/provider/1339-check-key-assignment-in-use.md @@ -0,0 +1,3 @@ +- 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/unreleased/features/provider/1340-cryptographic-equivocation-feature.md b/.changelog/unreleased/features/provider/1340-cryptographic-equivocation-feature.md new file mode 100644 index 0000000000..4a90b46488 --- /dev/null +++ b/.changelog/unreleased/features/provider/1340-cryptographic-equivocation-feature.md @@ -0,0 +1,4 @@ +- 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/unreleased/improvements/1244-consumer-unbonding.md b/.changelog/unreleased/improvements/1244-consumer-unbonding.md new file mode 100644 index 0000000000..4a8504e4ce --- /dev/null +++ b/.changelog/unreleased/improvements/1244-consumer-unbonding.md @@ -0,0 +1,2 @@ +- 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/unreleased/improvements/1324-consumer-genesis.md b/.changelog/unreleased/improvements/1324-consumer-genesis.md new file mode 100644 index 0000000000..a727be8341 --- /dev/null +++ b/.changelog/unreleased/improvements/1324-consumer-genesis.md @@ -0,0 +1,16 @@ +- 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/unreleased/improvements/1350-cleanup-types.md b/.changelog/unreleased/improvements/1350-cleanup-types.md new file mode 100644 index 0000000000..6e26fc3992 --- /dev/null +++ b/.changelog/unreleased/improvements/1350-cleanup-types.md @@ -0,0 +1,3 @@ +- 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/unreleased/improvements/consumer/1037-optimize-storage.md b/.changelog/unreleased/improvements/consumer/1037-optimize-storage.md new file mode 100644 index 0000000000..726906420b --- /dev/null +++ b/.changelog/unreleased/improvements/consumer/1037-optimize-storage.md @@ -0,0 +1,2 @@ +- 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/unreleased/state-breaking/1196-bump-ibc.md b/.changelog/unreleased/state-breaking/1196-bump-ibc.md new file mode 100644 index 0000000000..fcf4450150 --- /dev/null +++ b/.changelog/unreleased/state-breaking/1196-bump-ibc.md @@ -0,0 +1,3 @@ +- 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/unreleased/state-breaking/1244-consumer-unbonding.md b/.changelog/unreleased/state-breaking/1244-consumer-unbonding.md new file mode 100644 index 0000000000..4a8504e4ce --- /dev/null +++ b/.changelog/unreleased/state-breaking/1244-consumer-unbonding.md @@ -0,0 +1,2 @@ +- 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/unreleased/state-breaking/1258-bump-ibc.md b/.changelog/unreleased/state-breaking/1258-bump-ibc.md new file mode 100644 index 0000000000..68c6e2b104 --- /dev/null +++ b/.changelog/unreleased/state-breaking/1258-bump-ibc.md @@ -0,0 +1,3 @@ +- 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/unreleased/state-breaking/1258-bump-sdk.md b/.changelog/unreleased/state-breaking/1258-bump-sdk.md new file mode 100644 index 0000000000..7344fac97e --- /dev/null +++ b/.changelog/unreleased/state-breaking/1258-bump-sdk.md @@ -0,0 +1,3 @@ +- 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/unreleased/state-breaking/1259-bump-sdk.md b/.changelog/unreleased/state-breaking/1259-bump-sdk.md new file mode 100644 index 0000000000..247c623b7d --- /dev/null +++ b/.changelog/unreleased/state-breaking/1259-bump-sdk.md @@ -0,0 +1,3 @@ +- 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/unreleased/state-breaking/1324-consumer-genesis.md b/.changelog/unreleased/state-breaking/1324-consumer-genesis.md new file mode 100644 index 0000000000..b47f7199fd --- /dev/null +++ b/.changelog/unreleased/state-breaking/1324-consumer-genesis.md @@ -0,0 +1,2 @@ +- 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/unreleased/state-breaking/consumer/1024-jail-throttling-v2.md b/.changelog/unreleased/state-breaking/consumer/1024-jail-throttling-v2.md new file mode 100644 index 0000000000..7570facb34 --- /dev/null +++ b/.changelog/unreleased/state-breaking/consumer/1024-jail-throttling-v2.md @@ -0,0 +1,2 @@ +- 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/unreleased/state-breaking/consumer/1037-optimize-storage.md b/.changelog/unreleased/state-breaking/consumer/1037-optimize-storage.md new file mode 100644 index 0000000000..726906420b --- /dev/null +++ b/.changelog/unreleased/state-breaking/consumer/1037-optimize-storage.md @@ -0,0 +1,2 @@ +- 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/unreleased/state-breaking/consumer/1146-pending-packets.md b/.changelog/unreleased/state-breaking/consumer/1146-pending-packets.md new file mode 100644 index 0000000000..a10d75a505 --- /dev/null +++ b/.changelog/unreleased/state-breaking/consumer/1146-pending-packets.md @@ -0,0 +1,2 @@ +- 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/unreleased/state-breaking/consumer/1150-revert-wire-breaking.md b/.changelog/unreleased/state-breaking/consumer/1150-revert-wire-breaking.md new file mode 100644 index 0000000000..067448e770 --- /dev/null +++ b/.changelog/unreleased/state-breaking/consumer/1150-revert-wire-breaking.md @@ -0,0 +1,2 @@ +- 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/unreleased/state-breaking/consumer/1244-validate-transfer.md b/.changelog/unreleased/state-breaking/consumer/1244-validate-transfer.md new file mode 100644 index 0000000000..2d94c79c75 --- /dev/null +++ b/.changelog/unreleased/state-breaking/consumer/1244-validate-transfer.md @@ -0,0 +1,2 @@ +- 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/unreleased/state-breaking/consumer/1262-fee-pool-addr.md b/.changelog/unreleased/state-breaking/consumer/1262-fee-pool-addr.md new file mode 100644 index 0000000000..bbb54db2e3 --- /dev/null +++ b/.changelog/unreleased/state-breaking/consumer/1262-fee-pool-addr.md @@ -0,0 +1,2 @@ +- 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/unreleased/state-breaking/consumer/1295-migration.md b/.changelog/unreleased/state-breaking/consumer/1295-migration.md new file mode 100644 index 0000000000..739b08dc39 --- /dev/null +++ b/.changelog/unreleased/state-breaking/consumer/1295-migration.md @@ -0,0 +1,2 @@ +- 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/unreleased/state-breaking/provider/1321-jail-throttling-v2.md b/.changelog/unreleased/state-breaking/provider/1321-jail-throttling-v2.md new file mode 100644 index 0000000000..dd3b1a2852 --- /dev/null +++ b/.changelog/unreleased/state-breaking/provider/1321-jail-throttling-v2.md @@ -0,0 +1,2 @@ +- 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/unreleased/state-breaking/provider/1339-check-key-assignment-in-use.md b/.changelog/unreleased/state-breaking/provider/1339-check-key-assignment-in-use.md new file mode 100644 index 0000000000..2890582ba8 --- /dev/null +++ b/.changelog/unreleased/state-breaking/provider/1339-check-key-assignment-in-use.md @@ -0,0 +1,3 @@ +- 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/unreleased/state-breaking/provider/1340-cryptographic-equivocation-feature.md b/.changelog/unreleased/state-breaking/provider/1340-cryptographic-equivocation-feature.md new file mode 100644 index 0000000000..4a90b46488 --- /dev/null +++ b/.changelog/unreleased/state-breaking/provider/1340-cryptographic-equivocation-feature.md @@ -0,0 +1,4 @@ +- 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/.github/PULL_REQUEST_TEMPLATE/production.md b/.github/PULL_REQUEST_TEMPLATE/production.md index 7fe79eceb9..d8151fe707 100644 --- a/.github/PULL_REQUEST_TEMPLATE/production.md +++ b/.github/PULL_REQUEST_TEMPLATE/production.md @@ -30,7 +30,7 @@ I have... * [ ] Updated the relevant documentation or specification * [ ] Reviewed "Files changed" and left comments if necessary * [ ] Confirmed all CI checks have passed -* [ ] If this PR is library API breaking, bump the go.mod version string of the repo, and follow through on a new major release for both the consumer and provider +* [ ] If this PR is library API breaking, bump the go.mod version string of the repo, and follow through on a new major release ### Reviewers Checklist diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 773e5a783f..3b1bbd1653 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -72,7 +72,7 @@ updates: directory: "/" schedule: interval: daily - target-branch: "release/v3.2.x-consumer" + target-branch: "release/v3.2.x" # Only allow automated security-related dependency updates on release branches. open-pull-requests-limit: 0 labels: diff --git a/.github/workflows/automated-tests.yml b/.github/workflows/automated-tests.yml deleted file mode 100644 index f7d9988bad..0000000000 --- a/.github/workflows/automated-tests.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: Automated Tests -on: - push: - branches: - - main - - release/v* - - feat/* - pull_request: - branches: - - main - - release/v* - - feat/* -jobs: - Automated_Tests: - runs-on: ubuntu-latest - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v4 - with: - lfs: true - - name: Checkout LFS objects - run: git lfs checkout - - name: Setup Go - uses: actions/setup-go@v4 - with: - go-version: "1.20" # The Go version to download (if necessary) and use. - - name: Proto Check - run: make proto-check - - name: Unit, integration and difference tests - run: go test ./... - E2E_Tests: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - lfs: true - - name: Checkout LFS objects - run: git lfs checkout - - name: Setup Go - uses: actions/setup-go@v4 - with: - go-version: "1.20" - - name: E2E tests - run: make test-e2e-short - Cometmock_Tests: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - lfs: true - - name: Checkout LFS objects - run: git lfs checkout - - name: Setup Go - uses: actions/setup-go@v4 - with: - go-version: "1.20" - - name: E2E tests - run: make test-e2e-short-cometmock - Trace-Tests: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - lfs: true - - name: Checkout LFS objects - run: git lfs checkout - - name: Setup Go - uses: actions/setup-go@v4 - with: - go-version: "1.20" - - name: E2E tests - run: make test-trace diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index a812b9fcf2..0000000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Build -on: - push: - branches: - - main - - feat/* - pull_request: - types: [opened, synchronize, reopened] -jobs: - sonarcloud: - # skip this on forks or dependabot PRs - name: SonarCloud - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - lfs: true - - name: Checkout LFS objects - run: git lfs checkout - - name: Setup Go - uses: actions/setup-go@v4 - with: - go-version: "1.20" # The Go version to download (if necessary) and use. - - name: Test with coverage - run: go test -coverpkg=./x/... -coverprofile=coverage.out ./... - - name: SonarCloud Scan - uses: SonarSource/sonarcloud-github-action@master - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - if: env.SONAR_TOKEN != null diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 7fbd30cad7..60032cbdb1 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -29,7 +29,7 @@ jobs: path: "." - name: Setup Node.js πŸ”§ - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: "16.x" diff --git a/.github/workflows/gosec.yml b/.github/workflows/gosec.yml index 80dc4a3689..d01bfd37f4 100644 --- a/.github/workflows/gosec.yml +++ b/.github/workflows/gosec.yml @@ -9,7 +9,7 @@ on: - main - feat/* jobs: - tests: + Gosec: runs-on: ubuntu-latest env: GO111MODULE: on diff --git a/.github/workflows/proto-registry.yml b/.github/workflows/proto-registry.yml index 025c45b618..41d76f8e55 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.26.1 + - uses: bufbuild/buf-setup-action@v1.28.1 - uses: bufbuild/buf-push-action@v1 with: input: "proto" diff --git a/.github/workflows/proto.yml b/.github/workflows/proto.yml index ce525c5a8a..f4188838c6 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.26.1 + - uses: bufbuild/buf-setup-action@v1.28.1 - uses: bufbuild/buf-breaking-action@v1 with: input: "proto" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000000..efd2860398 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,239 @@ +name: Test +on: + workflow_call: + pull_request: + push: + branches: + - main + - release/v* + - feat/* + +permissions: + contents: read + +concurrency: + group: ci-${{ github.ref }}-tests + cancel-in-progress: true + +jobs: + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v4 + with: + go-version: "1.20" + check-latest: true + cache: true + cache-dependency-path: go.sum + - uses: technote-space/get-diff-action@v6.1.2 + id: git_diff + with: + PATTERNS: | + **/*.proto + **/*.go + go.mod + go.sum + **/go.mod + **/go.sum + **/Makefile + Makefile + - uses: actions/cache@v3.3.2 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.mod') }} + restore-keys: | + ${{ runner.os }}-go- + - name: proto check + run: make proto-check + - name: test & coverage report creation + if: env.GIT_DIFF + run: | + make test-unit-cov + - uses: actions/upload-artifact@v3 + if: env.GIT_DIFF + with: + name: "${{ github.sha }}-coverage" + path: ./profile.out + + test-integration: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v4 + with: + go-version: "1.20" + 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 + - name: integration tests + if: env.GIT_DIFF + run: | + make test-integration-cov + - uses: actions/upload-artifact@v3 + if: env.GIT_DIFF + with: + name: "${{ github.sha }}-integration-coverage" + path: ./integration-profile.out + + test-difference: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v4 + with: + go-version: "1.20" + 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 + - name: difference tests + if: env.GIT_DIFF + run: | + make test-difference-cov + - uses: actions/upload-artifact@v3 + if: env.GIT_DIFF + with: + name: "${{ github.sha }}-difference-coverage" + path: ./difference-profile.out + + repo-analysis: + runs-on: ubuntu-latest + needs: [tests, test-integration, test-difference] + steps: + - uses: actions/checkout@v4 + - uses: technote-space/get-diff-action@v6.1.2 + id: git_diff + with: + PATTERNS: | + **/*.go + go.mod + go.sum + **/go.mod + **/go.sum + - uses: actions/download-artifact@v3 + if: env.GIT_DIFF + with: + name: "${{ github.sha }}-coverage" + - uses: actions/download-artifact@v3 + if: env.GIT_DIFF + with: + name: "${{ github.sha }}-integration-coverage" + - uses: actions/download-artifact@v3 + if: env.GIT_DIFF + with: + name: "${{ github.sha }}-difference-coverage" + continue-on-error: true + - name: sonarcloud + if: ${{ env.GIT_DIFF && !github.event.pull_request.draft }} + uses: SonarSource/sonarcloud-github-action@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + test-e2e: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + lfs: true + - name: checkout LFS objects + run: git lfs checkout + - uses: actions/setup-go@v4 + with: + go-version: "1.20" + 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 + - name: e2e tests + run: make test-e2e-short + + 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@v4 + with: + go-version: "1.20" + 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 + - name: cometmock tests + run: make test-e2e-short-cometmock + + test-trace: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + lfs: true + - name: checkout LFS objects + run: git lfs checkout + - uses: actions/setup-go@v4 + with: + go-version: "1.20" + 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 + - name: trace-e2e tests + run: make test-trace diff --git a/.mergify.yml b/.mergify.yml index 00764d0a8c..539d0115f2 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -50,11 +50,11 @@ pull_request_rules: backport: branches: - release/v3.1.x - - name: Backport patches to the release/v3.2.x-consumer branch + - name: Backport patches to the release/v3.2.x branch conditions: - base=main - - label=A:backport/v3.2.x-consumer + - label=A:backport/v3.2.x actions: backport: branches: - - release/v3.2.x-consumer + - release/v3.2.x diff --git a/CHANGELOG.md b/CHANGELOG.md index a238df4a44..7236eb5ec7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,48 +1,5 @@ # CHANGELOG -## [Unreleased for Provider] - -Add an entry to the unreleased provider section whenever merging a PR to main that is not targeted at a specific release. These entries will eventually be included in a provider release. - -* (feature!) [#1280](https://github.com/cosmos/interchain-security/pull/1280) provider proposal for changing reward denoms -* (feature!) [#1244](https://github.com/cosmos/interchain-security/pull/1244) Update the default consumer unbonding period to 2 weeks. -* (deps) [#1259](https://github.com/cosmos/interchain-security/pull/1259) Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to [v0.47.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.5). -* (deps!) [#1258](https://github.com/cosmos/interchain-security/pull/1258) Bump [ibc-go](https://github.com/cosmos/ibc-go) to [v7.3.0](https://github.com/cosmos/ibc-go/releases/tag/v7.3.0). -* (deps) [#1258](https://github.com/cosmos/interchain-security/pull/1258) Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to [v0.47.4](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.4). -* (deps!) [#1196](https://github.com/cosmos/interchain-security/pull/1196) Bump [ibc-go](https://github.com/cosmos/ibc-go) to [v7.2.0](https://github.com/cosmos/ibc-go/releases/tag/v7.2.0). -* `[x/ccv/provider]` (fix) [#1076](https://github.com/cosmos/interchain-security/pull/1076) Add `InitTimeoutTimestamps` and `ExportedVscSendTimestamps` to exported genesis. - -## [Unreleased for Consumer] - -Add an entry to the unreleased consumer section whenever merging a PR to main that is not targeted at a specific release. These entries will eventually be included in a consumer release. - -## v3.2.0-consumer - -Date September 6th, 2023 - -A minor version upgrade to the CONSUMER CCV module. This release includes various changes involving throttling v2 functionality, validation, and bumps to deps like cosmos-sdk and ibc-go. - -Note: - -* This release is ONLY RELEVANT TO CONSUMERS. The most recent provider release is v3.1.0, and will eventually be a release postfixed with `-provider`. -* this is the first upgrade to the consumer module with a separate semver cycle from the provider module. See [contributing.md](./CONTRIBUTING.md#semantic-versioning) and [associated ADR](docs/docs/adrs/adr-012-separate-releasing.md) for more info. - -Changes: - -* (feat) [#1295](https://github.com/cosmos/interchain-security/pull/1295) increment consumer consensus version and register consumer packet migration. -* (fix!) [#1262](https://github.com/cosmos/interchain-security/pull/1262) Remove incorrect address validation on `ProviderFeePoolAddrStr` param. -* (feature!) [#1244](https://github.com/cosmos/interchain-security/pull/1244) Update the default consumer unbonding period to 2 weeks. -* (fix!) [#1244](https://github.com/cosmos/interchain-security/pull/1244) Validate token transfer messages before calling `Transfer()`. -* (deps) [#1259](https://github.com/cosmos/interchain-security/pull/1259) Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to [v0.47.5](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.5). -* (deps!) [#1258](https://github.com/cosmos/interchain-security/pull/1258) Bump [ibc-go](https://github.com/cosmos/ibc-go) to [v7.3.0](https://github.com/cosmos/ibc-go/releases/tag/v7.3.0). -* (deps) [#1258](https://github.com/cosmos/interchain-security/pull/1258) Bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to [v0.47.4](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.47.4). -* (deps!) [#1196](https://github.com/cosmos/interchain-security/pull/1196) Bump [ibc-go](https://github.com/cosmos/ibc-go) to [v7.2.0](https://github.com/cosmos/ibc-go/releases/tag/v7.2.0). -* (feat!) [#1024](https://github.com/cosmos/interchain-security/pull/1024) Throttle with retries, consumer changes. -* (fix!) [#1150](https://github.com/cosmos/interchain-security/pull/1150) Revert consumer packet data changes from #1037. -* (fix!) [#1146](https://github.com/cosmos/interchain-security/pull/1146) Proper deletion of pending packets. -* (feat!) [#1037](https://github.com/cosmos/interchain-security/pull/1037) Optimize pending packets storage on consumer, with migration. -* (feat) [#1164](https://github.com/cosmos/interchain-security/pull/1164) 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. - ## v3.1.0 Date July 11th, 2023 @@ -68,6 +25,28 @@ Interchain Security v3 uses SDK 0.47 and IBC 7. * `[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 @@ -218,3 +197,4 @@ 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. + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c376c3b824..90456c842f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,11 +14,10 @@ - [Pull Request Templates](#pull-request-templates) - [Requesting Reviews](#requesting-reviews) - [Updating Documentation](#updating-documentation) + - [Changelog](#changelog) - [Dependencies](#dependencies) - [Protobuf](#protobuf) - [Branching Model and Release](#branching-model-and-release) - - [Semantic Versioning](#semantic-versioning) - - [Backwards Compatibility](#backwards-compatibility) - [PR Targeting](#pr-targeting) Thank you for considering making contributions to the Interchain Security (ICS) repository! πŸŽ‰πŸ‘ @@ -216,6 +215,63 @@ items. In addition, use the following review explanations: If you open a PR in ICS, it is mandatory to update the relevant documentation in `/docs`. +### Changelog + +To manage and generate our changelog, we currently use [unclog](https://github.com/informalsystems/unclog). + +Every PR with types `fix`, `feat`, `deps`, and `refactor` should include a file +`.changelog/unreleased/${section}/[${component}/]${pr-number}-${short-description}.md`, +where: + +- `section` is one of + `dependencies`, `improvements`, `features`, `bug-fixes`, `state-breaking`, `api-breaking`, + and _**if multiple apply, create multiple files**_, + not necessarily with the same `short-description` or content; +- `pr-number` is the PR number; +- `short-description` is a short (4 to 6 word), hyphen separated description of the change; +- `component` is used for changes that affect one of the components defined in the [config](.changelog/config.toml), e.g., `provider`, `consumer`. + +For examples, see the [.changelog](.changelog) folder. + +Use `unclog` to add a changelog entry in `.changelog` (check the [requirements](https://github.com/informalsystems/unclog#requirements) first): +```bash +# add a general entry +unclog add \ + -i "${pr-number}-${short-description}" \ + -p "${pr-number}" \ + -s "${section}" \ + -m "${description}" \ + +# add a entry to a component +unclog add + -i "${pr-number}-${short-description}" \ + -p "${pr-number}" \ + -c "${component}" \ + -s "${section}" \ + -m "${description}" \ +``` +where `${description}` is a detailed description of the changelog entry. + +For example, +```bash +# add an entry for bumping IBC to v7.2.0 +unclog add -i "1196-bump-ibc" -p 1196 -s dependencies -m "Bump [ibc-go](https://github.com/cosmos/ibc-go) to [v7.2.0](https://github.com/cosmos/ibc-go/releases/tag/v7.2.0)" + +# add an entry for changing the consumer module; +# note that the entry is added to both state-breaking and features sections +unclog add -i "1024-jail-throttling-v2" -p 1024 -c consumer -s state-breaking -m "Add the consumer-side changes for jail throttling with retries (cf. ADR 008)." +unclog add -i "1024-jail-throttling-v2" -p 1024 -c consumer -s features -m "Add the consumer-side changes for jail throttling with retries (cf. ADR 008)." +``` + +**Note:** `unclog add` requires an editor. This can be set either by configuring +an `$EDITOR` environment variable or by manually specify an editor binary path +via the `--editor` flag. + +**Note:** Changelog entries should answer the question: "what is important about this +change for users to know?" or "what problem does this solve for users?". It +should not simply be a reiteration of the title of the associated PR, unless the +title of the PR _very_ clearly explains the benefit of a change to a user. + ## Dependencies We use [Go Modules](https://github.com/golang/go/wiki/Modules) to manage @@ -243,18 +299,6 @@ To generate the protobuf stubs, you can run `make proto-gen`. ICS adheres to the [trunk based development branching model](https://trunkbaseddevelopment.com/). User branches should start with a user name, example: `{moniker}/{issue#}-branch-name`. -### Semantic Versioning - -ICS follows [semantic versioning](https://semver.org), but with the following deviations (similar to [IBC-Go](https://github.com/cosmos/ibc-go/blob/main/RELEASES.md)): - -- A library API breaking change to EITHER the provider or consumer module will result in an increase of the MAJOR version number for BOTH modules (X.y.z-provider AND X.y.z-consumer). -- A state breaking change (change requiring coordinated upgrade and/or state migration) will result in an increase of the MINOR version number for the AFFECTED module(s) (x.Y.z-provider AND/OR x.Y.z-consumer). -- Any other changes (including node API breaking changes) will result in an increase of the PATCH version number for the AFFECTED module(s) (x.y.Z-provider AND/OR x.y.Z-consumer). - -### Backwards Compatibility - -A MAJOR version of ICS will always be backwards compatible with the previous MAJOR version of ICS. Versions before that are not supported. For example, a provider chain could run ICS at version 3.4.5, and would be compatible with consumers running ICS at 2.0.0, 2.1.2, 3.2.1, but not 1.2.7. - ### PR Targeting Ensure that you base and target your PRs on either `main` or a feature branch. diff --git a/Dockerfile b/Dockerfile index 7c45187034..665aa3d84f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,7 +21,7 @@ ADD . /interchain-security WORKDIR /interchain-security -# Do not specify version here. It leads to odd replacement behavior +# Do not specify version here. It leads to odd replacement behavior RUN if [ -d "./cosmos-sdk" ]; then go mod edit -replace github.com/cosmos/cosmos-sdk=./cosmos-sdk; fi RUN go mod tidy @@ -29,7 +29,7 @@ RUN go mod tidy RUN make install # Get Hermes build -FROM ghcr.io/informalsystems/hermes:1.4.1 AS hermes-builder +FROM otacrew/hermes-ics:evidence-cmd AS hermes-builder # Get CometMock FROM ghcr.io/informalsystems/cometmock:v0.37.x as cometmock-builder @@ -37,7 +37,7 @@ FROM ghcr.io/informalsystems/cometmock:v0.37.x as cometmock-builder # Get GoRelayer FROM ghcr.io/informalsystems/relayer-no-gas-sim:v2.3.0-rc4-no-gas-sim AS gorelayer-builder -FROM --platform=linux/amd64 fedora:36 +FROM --platform=linux/amd64 fedora:39 RUN dnf update -y RUN dnf install -y which iproute iputils procps-ng vim-minimal tmux net-tools htop jq USER root diff --git a/Dockerfile.gaia b/Dockerfile.gaia index b9f6ff007f..40dbd98da7 100644 --- a/Dockerfile.gaia +++ b/Dockerfile.gaia @@ -29,7 +29,7 @@ RUN if [ -n "${GAIA_TAG}" ]; \ then git checkout "${GAIA_TAG}"; \ # if GAIA_TAG is not set, build the latest tagged version else \ - git checkout $(git tag | tail -1); \ + git checkout $(git tag | sort -Vr | head -n1); \ fi # Also replace sdk version in the go.mod if specified diff --git a/FEATURES.md b/FEATURES.md new file mode 100644 index 0000000000..97e36f643e --- /dev/null +++ b/FEATURES.md @@ -0,0 +1,19 @@ +# Features + +The following table indicates the major ICS features available in the [currently active releases](./RELEASES.md#version-matrix): + +| Feature | `v1.2.0-multiden` | `v2.0.0` | `v2.1.0-provider-lsm` | `v2.4.0-lsm` | `v3.1.0` | `v3.2.0` | `v3.3.0` | `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) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | βœ… | diff --git a/Makefile b/Makefile index 516db825bd..33420f4c4e 100644 --- a/Makefile +++ b/Makefile @@ -10,25 +10,36 @@ install: go.sum go install $(BUILD_FLAGS) ./cmd/interchain-security-sd # run all tests: unit, integration, diff, and E2E -test: - go test ./... && go run ./tests/e2e/... +test: test-unit test-integration test-difference test-e2e -# run all unit tests +# shortcut for local development +test-dev: test-unit test-integration test-difference + +# run unit tests test-unit: - go test ./... + go test ./x/... ./app/... + +test-unit-cov: + go test ./x/... ./app/... -coverpkg=./... -coverprofile=profile.out -covermode=atomic # run unit and integration tests -test-short: - go test ./x/... ./app/... ./tests/integration/... +test-integration: + go test ./tests/integration/... -timeout 30m + +test-integration-cov: + go test ./tests/integration/... -timeout 30m -coverpkg=./... -coverprofile=integration-profile.out -covermode=atomic + +# run difference tests +test-difference: + go test ./tests/difference/... -timeout 30m + +test-difference-cov: + go test ./tests/difference/... -timeout 30m -coverpkg=./... -coverprofile=difference-profile.out -covermode=atomic # run E2E tests test-e2e: go run ./tests/e2e/... -# run difference tests -test-diff: - go test ./tests/difference/... - # run only happy path E2E tests test-e2e-short: go run ./tests/e2e/... --tc happy-path @@ -183,3 +194,10 @@ build-docs: @cd docs && ./build.sh .PHONY: build-docs + +############################################################################### +### Test Traces ### +############################################################################### + +e2e-traces: + cd tests/e2e; go test -timeout 30s -run ^TestWriteExamples -v \ No newline at end of file diff --git a/README.md b/README.md index bb6da8be76..c3e908b4b3 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,11 @@ **interchain-security** contains a working and in-production implementation of the Replicated Security protocol (aka Interchain Security V1). Replicated security is an open sourced IBC application which allows cosmos blockchains to lease their proof-of-stake security to one another. -For more details on the Replicated Security protocol, take a look at the [docs](https://cosmos.github.io/interchain-security/) or [technical specification](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/README.md). +For more details on the **Replicated Security protocol**, take a look at the [docs](https://cosmos.github.io/interchain-security/) or [technical specification](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/README.md). + +For a list of **currently active releases**, see [RELEASES.md](./RELEASES.md#version-matrix). + +For a list of **major ICS features** available in the currently active releases, see [FEATURES.md](./FEATURES.md). ## Instructions @@ -43,7 +47,7 @@ Inspect the [Makefile](./Makefile) if curious. ## Testing -See [testing docs](./docs/old/testing.md). +See [testing docs](./TESTING.md). ## Learn more diff --git a/RELEASES.md b/RELEASES.md new file mode 100644 index 0000000000..9716546410 --- /dev/null +++ b/RELEASES.md @@ -0,0 +1,117 @@ +# Releases + +- [Releases](#releases) + - [Semantic Versioning](#semantic-versioning) + - [Breaking Changes](#breaking-changes) + - [Release Cycle](#release-cycle) + - [Stable Release Policy](#stable-release-policy) + - [Version Matrix](#version-matrix) + - [Backwards Compatibility](#backwards-compatibility) + - [Notes](#notes) + +## Semantic Versioning + +Interchain Security (ICS) follows [semantic versioning](https://semver.org), but with the following deviations (similar to [IBC-Go](https://github.com/cosmos/ibc-go/blob/main/RELEASES.md)): + +- A library API breaking change will result in an increase of the MAJOR version number (X.y.z | X > 0). +- A state-machine breaking change will result in an increase of the MINOR version number (x.Y.z | x > 0). +- Any other changes (including node API breaking changes) will result in an increase of the PATCH version number (x.y.Z | x > 0). + +### Breaking Changes + +A change is considered to be ***library API breaking*** if it modifies the integration of ICS on either consumer or provider chains (i.e., it changes the way ICS is used as a library). +Note that bumping the major version of [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) or [IBC](https://github.com/cosmos/ibc-go) will be considered as a library API breaking change. + +A change is considered to be ***state-machine breaking*** if it requires a coordinated upgrade and/or state migration for either consumer or provider chains in order to preserve [state compatibility](./STATE-COMPATIBILITY.md). +Note that when bumping the dependencies of [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) and [IBC](https://github.com/cosmos/ibc-go) we will only treat patch releases as non state-machine breaking. + +A change is considered to be ***node API breaking*** if it modifies the API provided by a node of either consumer or provider chains. +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. + +❗***It is never advisable to use a non-final release in production.*** + +Final releases should contain little to no changes in comparison to the latest RC. + +A release should not be finalized until the development team and the external community have done sufficient integration tests on the targeted release. + +## Stable Release Policy + +The beginning of a new major release series is marked by the release of a new major version. +A major release series is comprised of all minor and patch releases made under the same major version number. +The series continues to receive bug fixes (released as minor or patch releases) until it reaches end of life. +The date when a major release series reaches end of life is determined by one of the following methods: + +- If there is no known chain using a major release series, then it reached end of life. + This is a temporary policy that is possible due to the relatively low number of consumer chains. +- If the next major release is made within the first 6 months, then the end of + life date of the major release series is 1 year after its initial release. +- If the next major release is made 6 months after the initial release, then the + end of life date of the major release series is 6 months after the release date + of the next major release. + +Only the following major release series have a stable release status. +All missing minor release versions have been discontinued. + +| Release | End of Life Date | +|---------|------------------| +| `v1.2.x` | February 21, 2024 | +| `v2.0.x` | June 09, 2024 | +| `v2.1.x-provider-lsm` | June 09, 2024 | +| `v2.4.x-lsm` | June 09, 2024 | +| `v3.1.x` | July 10, 2024 | +| `v3.2.x` | July 10, 2024 | +| `v3.3.x` | July 10, 2024 | +| `v4.0.x` | TBA | + +**Note**: As of [Gaia v12.0.0](https://github.com/cosmos/gaia/releases/tag/v12.0.0), +the Cosmos Hub uses a fork of Cosmos SDK ([v0.45.16-ics-lsm](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.45.16-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. +As soon as the Cosmos Hub uses mainline Cosmos SDK, the `-lsm` releases will reach end of life. + +## Version Matrix + +Versions of Golang, IBC, Cosmos SDK and CometBFT used by ICS in the currently active releases: + +| ICS | Golang | IBC | Cosmos SDK | CometBFT | Note | +|-----|--------|-----|------------|----------|------| +| [v1.2.0-multiden](https://github.com/cosmos/interchain-security/releases/tag/v1.2.0-multiden) | 1.18 | v4.2.0 | v0.45.15-ics | v0.34.27 | Consumer only | +| [v2.0.0](https://github.com/cosmos/interchain-security/releases/tag/v2.0.0) | 1.19 | v4.4.2 | v0.45.15-ics | v0.34.28 | +| [v2.1.0-provider-lsm](https://github.com/cosmos/interchain-security/releases/tag/v2.1.0-provider-lsm) | 1.19 | v4.4.2 | v0.45.16-ics-lsm | v0.34.28 | Provider only (Cosmos Hub specific) | +| [v2.4.0-lsm](https://github.com/cosmos/interchain-security/releases/tag/v2.4.0-lsm) | 1.19 | v4.4.2 | v0.45.16-ics-lsm | v0.34.28 | Provider only (Cosmos Hub specific) | +| [v3.1.0](https://github.com/cosmos/interchain-security/releases/tag/v3.1.0) | 1.20 | v7.1.0 | v0.47.3 | v0.37.2 | +| v3.2.0 | 1.20 | v7.3.0 | v0.47.5 | v0.37.2 | +| v3.3.0 | 1.20 | v7.3.0 | v0.47.5 | v0.37.2 | +| v4.0.0 | 1.20 | v7.3.0 | v0.47.5 | v0.37.2 | Provider on >= v4.0.0 backwards compatible with consumers >= v3.2.0 | + +**Note:** For a list of major ICS features available in the currently active releases, see [FEATURES.md](./FEATURES.md). + +### Backwards Compatibility + +A MAJOR version of ICS will always be backwards compatible with the previous MAJOR version of ICS. + +The following table indicates the compatibility of currently active releases: + +| Consumer | Provider | `v2.0.0` | `v2.1.0-provider-lsm` | `v2.4.0-lsm` | `v3.1.0` | `v3.2.0` | `v3.3.0` | `v4.0.0` | +|----------|----------|----------|-----------------------|--------------|----------|----------|----------|----------| +| `v1.2.0-multiden` || βœ… (1) | βœ… (1) | βœ… (1) | βœ… (1),(2) | βœ… (1),(2) | βœ… (1),(2),(4) | ❌ | +| `v2.0.0` || βœ… | βœ… | βœ… | βœ… (2) | βœ… (2) | βœ… (2),(4) | ❌ | +| `v3.1.0` || βœ… | βœ… | βœ… | βœ… | βœ… | βœ… (4) | ❌ | +| `v3.2.0` || βœ… | βœ… | βœ… | βœ… | βœ… | βœ… (4) | βœ… | +| `v3.3.0` || βœ… | βœ… | βœ… | βœ… | βœ… | βœ… | βœ… | +| `v4.0.0` || βœ… (3) | βœ… (3) | βœ… (3) | βœ… (3) | βœ… | βœ… | βœ… | + +#### 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) Remove β€œpreCCV” key +- (2) Remove β€œprehash_key_before_comparison” keys +- (3) Add .params.retry_delay_period: β€œ3600s” +- (4) Use `interchain-security-cd genesis transform` to transform the consumer genesis file obtained from the provider. \ No newline at end of file diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f1a6edb066..a09f9a4ba7 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,15 +1,17 @@ -# Replicated Security - Release Notes +# Replicated Security Release Notes -## Note this release is ONLY relevant to +❗ ***Note this release is ONLY relevant to *** ## πŸ“ Changelog diff --git a/RELEASE_PROCESS.md b/RELEASE_PROCESS.md new file mode 100644 index 0000000000..ef0863ed4f --- /dev/null +++ b/RELEASE_PROCESS.md @@ -0,0 +1,119 @@ +# Release Process + +- [Release Process](#release-process) + - [Changelog](#changelog) + - [Creating a new release branch](#creating-a-new-release-branch) + - [Cutting a new release](#cutting-a-new-release) + - [Update the changelog on main](#update-the-changelog-on-main) + - [Tagging Procedure](#tagging-procedure) + + +This document outlines the release process for Interchain Security (ICS). + +For details on ICS releases, see [RELEASES.md](./RELEASES.md). + +## Changelog + +For PRs that are changing production code, please add a changelog entry in `.changelog` (for details, see [contributing guidelines](./CONTRIBUTING.md#changelog)). + +To manage and generate the changelog on ICS, we currently use [unclog](https://github.com/informalsystems/unclog). +Read the [README.md](https://github.com/informalsystems/unclog#readme) in the unclog repo for instruction on how to install and use unclog. + +### Creating a new release branch + +Unreleased changes are collected on `main` in `.changelog/unreleased/`. +However, `.changelog/` on `main` contains also existing releases (e.g., `v3.2.0`). +Thus, when creating a new release branch (e.g., `release/v3.3.x`), the following steps are necessary: + +- create a new release branch, e.g., `release/v3.3.x` + ```bash + git checkout main + git pull + git checkout -b release/v3.3.x + ``` +- delete all the sub-folders in `.changelog/` except `unreleased/` + ```bash + find ./.changelog -mindepth 1 -maxdepth 1 -type d -not -name unreleased | xargs rm -r + ``` +- replace the content of `.changelog/epilogue.md` with the following text + ```md + ## Previous Versions + + [CHANGELOG of previous versions](https://github.com/cosmos/interchain-security/blob/main/CHANGELOG.md) + ``` +- push the release branch upstream + ```bash + git push + ``` + +### Cutting a new release + +Before cutting a _**release candidate**_ (e.g., `v3.3.0-rc0`), the following steps are necessary: + +- move to the release branch, e.g., `release/v3.3.x` + ```bash + git checkout release/v3.3.x + ``` +- move all entries in ".changelog/unreleased" to the release version, e.g., `v3.3.0`, i.e., + ```bash + unclog release v3.3.0 + ``` +- update `CHANGELOG.md`, i.e., + ```bash + unclog build > CHANGELOG.md + ``` +- open a PR (from this new created branch) against the release branch, e.g., `release/v3.3.x` + +Now you can cut the release candidate, e.g., v3.3.0-rc0 (follow the [Tagging Procedure](#tagging-procedure)). + +### Update the changelog on main + +Once the **final release** is cut, the new changelog section must be added to main: + +- checkout a new branch from the `main` branch, i.e., + ```bash + git checkout main + git pull + git checkout -b /backport_changelog + ``` +- bring the new changelog section from the release branch into this branch, e.g., + ```bash + git checkout release/v3.3.x .changelog/v3.3.0 + ``` +- remove duplicate entries that are both in `.changelog/unreleased/` and the new changelog section, e.g., `.changelog/v3.3.0` +- update `CHANGELOG.md`, i.e., + ```bash + unclog build > CHANGELOG.md + ``` +- open a PR (from this new created branch) against `main` + +## Tagging Procedure + +**Important**: _**Always create tags from your local machine**_ since all release +tags should be [signed and annotated](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits). + +The following steps are the default for tagging a specific branch commit using git +on your local machine. Usually, release branches are labeled `release/v*`: + +Ensure you have checked out the commit you wish to tag and then do: +```bash +git pull --tags +git tag -s v3.2.0 -m v3.2.0 +git push origin v3.2.0 +``` + +To re-create a tag: +```bash +# delete a tag locally +git tag -d v3.2.0 + +# push the deletion to the remote +git push --delete origin v3.2.0 + +# redo the tagging +git tag -s v3.2.0 -m v3.2.0 +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 diff --git a/SECURITY.md b/SECURITY.md index 636d34e850..95714540c7 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,79 +1,30 @@ -# Coordinated Vulnerability Disclosure Policy +## How to Report a Security Bug -The Cosmos ecosystem believes that strong security is a blend of highly -technical security researchers who care about security and the forward -progression of the ecosystem and the attentiveness and openness of Cosmos core -contributors to help continually secure our operations. +If you believe you have found a security vulnerability in the Interchain Stack, +you can report it to our primary vulnerability disclosure channel, the +[Cosmos HackerOne Bug Bounty program](https://hackerone.com/cosmos?type=team). -> **IMPORTANT**: *DO NOT* open public issues on this repository for security -> vulnerabilities. +If you prefer to report an issue via email, you may send a bug report to +security@interchain.io with the issue details, reproduction, impact, and other +information. Please submit only one unique email thread per vulnerability. +Any issues reported via email are ineligible for bounty rewards. -## Scope +Artifacts from an email report are saved at the time the email is triaged. +Please note: our team is not able to monitor dynamic content (e.g. a Google +Docs link that is edited after receipt) throughout the lifecycle of a report. +If you would like to share additional information or modify previous +information, please include it in an additional reply as an additional attachment. -| Scope | -|-----------------------| -| last release (tagged) | -| main branch | +***Please DO NOT file a public issue in this repository to report a security vulnerability.*** -The latest **release tag** of this repository is supported for security updates -as well as the **main** branch. Security vulnerabilities should be reported if -the vulnerability can be reproduced on either one of those. -## Reporting a Vulnerability +## Coordinated Vulnerability Disclosure Policy and Safe Harbor -| Reporting methods | -|---------------------------------------------------------------| -| [GitHub Private Vulnerability Reporting][gh-private-advisory] | -| [HackerOne bug bounty program][h1] | +For the most up-to-date version of the policies that govern vulnerability +disclosure, please consult the [HackerOne program page](https://hackerone.com/cosmos?type=team&view_policy=true). -All security vulnerabilities can be reported under GitHub's [Private -vulnerability reporting][gh-private-advisory] system. This will open a private -issue for the developers. Try to fill in as much of the questions as possible. -If you are not familiar with the CVSS system for assessing vulnerabilities, just -use the Low/High/Critical severity ratings. A partially filled in report for a -critical vulnerability is still better than no report at all. - -Vulnerabilities associated with the **Go, Rust or Protobuf code** of the -repository may be eligible for a [bug bounty][h1]. Please see the bug bounty -page for more details on submissions and rewards. If you think the vulnerability -is eligible for a payout, **report on HackerOne first**. - -Vulnerabilities in services and their source codes (JavaScript, web page, Google -Workspace) are not in scope for the bug bounty program, but they are welcome to -be reported in GitHub. - -### Guidelines - -We require that all researchers: - -* Abide by this policy to disclose vulnerabilities, and avoid posting - vulnerability information in public places, including GitHub, Discord, - Telegram, and Twitter. -* Make every effort to avoid privacy violations, degradation of user experience, - disruption to production systems (including but not limited to the Cosmos - Hub), and destruction of data. -* Keep any information about vulnerabilities that you’ve discovered confidential - between yourself and the Cosmos engineering team until the issue has been - resolved and disclosed. -* Avoid posting personally identifiable information, privately or publicly. - -If you follow these guidelines when reporting an issue to us, we commit to: - -* Not pursue or support any legal action related to your research on this - vulnerability -* Work with you to understand, resolve and ultimately disclose the issue in a - timely fashion - -### More information - -* See [TIMELINE.md] for an example timeline of a disclosure. -* See [DISCLOSURE.md] to see more into the inner workings of the disclosure - process. -* See [EXAMPLES.md] for some of the examples that we are interested in for the - bug bounty program. - -[gh-private-advisory]: /../../security/advisories/new -[h1]: https://hackerone.com/cosmos -[TIMELINE.md]: https://github.com/cosmos/security/blob/main/TIMELINE.md -[DISCLOSURE.md]: https://github.com/cosmos/security/blob/main/DISCLOSURE.md -[EXAMPLES.md]: https://github.com/cosmos/security/blob/main/EXAMPLES.md +The policy hosted on HackerOne is the official Coordinated Vulnerability +Disclosure policy and Safe Harbor for the Interchain Stack, and the teams and +infrastructure it supports, and it supersedes previous security policies that +have been used in the past by individual teams and projects with targets in +scope of the program. diff --git a/STATE-COMPATIBILITY.md b/STATE-COMPATIBILITY.md new file mode 100644 index 0000000000..1819aaf981 --- /dev/null +++ b/STATE-COMPATIBILITY.md @@ -0,0 +1,212 @@ +# State-Compatibility + +- [State-Compatibility](#state-compatibility) + - [Scope](#scope) + - [Validating State-Compatibility](#validating-state-compatibility) + - [AppHash](#apphash) + - [LastResultsHash](#lastresultshash) + - [Major Sources of State-incompatibility](#major-sources-of-state-incompatibility) + - [Creating Additional State](#creating-additional-state) + - [Changing Proto Field Definitions](#changing-proto-field-definitions) + - [Returning Different Errors Given Same Input](#returning-different-errors-given-same-input) + - [Variability in Gas Usage](#variability-in-gas-usage) + - [Secondary Limitations To Keep In Mind](#secondary-limitations-to-keep-in-mind) + - [Network Requests to External Services](#network-requests-to-external-services) + - [Randomness](#randomness) + - [Parallelism and Shared State](#parallelism-and-shared-state) + - [Hardware Errors](#hardware-errors) + + +It is critical for the patch releases to be state-machine compatible with prior releases in the same minor version. +For example, v3.2.1 must be state-machine compatible with v3.2.0. + +This is to ensure **determinism**, i.e., given the same input, the nodes will always produce the same output. + +State-incompatibility is allowed for major upgrades because all nodes in either the consumer or provider networks +perform it at the same time. Therefore, after the upgrade, the nodes continue functioning in a deterministic way. + +## Scope + +The state-machine scope includes the following areas: + +- All ICS messages including: + - Every msg's ValidateBasic method + - Every msg's MsgServer method + - Net gas usage, in all execution paths + - Error result returned + - State changes (namely every store write) +- AnteHandlers in "DeliverTx" mode +- All `BeginBlock`/`EndBlock` logic + +The following are **NOT** in the state-machine scope: + +- Events +- Queries that are not whitelisted +- CLI interfaces + +## Validating State-Compatibility + +CometBFT ensures state compatibility by validating a number of hashes that can be found [here](https://github.com/cometbft/cometbft/blob/9f76e8da150414ce73eed2c4f248947b657c7587/proto/tendermint/types/types.proto#L70-L77). + +`AppHash` and `LastResultsHash` are the common sources of problems stemming from our work. +To avoid these problems, let's now examine how these hashes work. + +### AppHash + +**Note:** The following explanation is simplified for clarity. + +An app hash is a hash of hashes of every store's Merkle root that is returned by ABCI's `Commit()` from Cosmos-SDK to CometBFT. +Cosmos-SDK [takes an app hash of the application state](https://github.com/osmosis-labs/cosmos-sdk/blob/5c9a51c277d067e0ec5cf48df30a85fae95bcd14/store/rootmulti/store.go#L430), and propagates it to CometBFT which, in turn, compares it to the app hash of the rest of the network. +Then, CometBFT ensures that the app hash of the local node matches the app hash of the network. + +### LastResultsHash + +`LastResultsHash` is the root hash of all results from the transactions in the block returned by the ABCI's `DeliverTx`. + +The [`LastResultsHash`](https://github.com/cometbft/cometbft/blob/v0.34.29/types/results.go#L47-L54) +in CometBFT [v0.34.29](https://github.com/cometbft/cometbft/releases/tag/v0.34.29) contains: + +1. Tx `GasWanted` + +2. Tx `GasUsed` + > `GasUsed` being Merkelized means that we cannot freely reorder methods that consume gas. + > We should also be careful of modifying any validation logic since changing the + > locations where we error or pass might affect transaction gas usage. + > + > There are plans to remove this field from being Merkelized in a subsequent CometBFT release, + > at which point we will have more flexibility in reordering operations / erroring. + +3. Tx response `Data` + + > The `Data` field includes the proto marshalled Tx response. Therefore, we cannot + > change these in patch releases. + +4. Tx response `Code` + + > This is an error code that is returned by the transaction flow. In the case of + > success, it is `0`. On a general error, it is `1`. Additionally, each module + > defines its custom error codes. + > For example, `x/provider` currently has [these error codes](./x/ccv/provider/types/errors.go) defined. + > + > As a result, it is important to avoid changing custom error codes or change + > the semantics of what is valid logic in transaction flows. + +Note that all of the above stem from `DeliverTx` execution path, which handles: + +- `AnteHandler`'s marked as deliver tx +- `msg.ValidateBasic` +- execution of a message from the message server + +The `DeliverTx` return back to the CometBFT is defined [here](https://github.com/cosmos/cosmos-sdk/blob/d11196aad04e57812dbc5ac6248d35375e6603af/baseapp/abci.go#L293-L303). + +## Major Sources of State-incompatibility + +### Creating Additional State + +By erroneously creating database entries that exist in Version A but not in +Version B, we can cause the app hash to differ across nodes running +these versions in the network. Therefore, this must be avoided. + +### Changing Proto Field Definitions + +For example, if we change a field that gets persisted to the database, +the app hash will differ across nodes running these versions in the network. + +Additionally, this affects `LastResultsHash` because it contains a `Data` field that is a marshaled proto message. + +### Returning Different Errors Given Same Input + +```go +// Version A +func (sk Keeper) validateAmount(ctx context.Context, amount math.Int) error { + if amount.IsNegative() { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "amount must be positive or zero") + } + return nil +} +``` + +```go +// Version B +func (sk Keeper) validateAmount(ctx context.Context, amount math.Int) error { + if amount.IsNegative() || amount.IsZero() { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "amount must be positive") + } + return nil +} +``` + +Note that now an amount of 0 can be valid in "Version A", but invalid in "Version B". +Therefore, if some nodes are running "Version A" and others are running "Version B", +the final app hash might not be deterministic. + +Additionally, a different error message does not matter because it +is not included in any hash. However, an error code `sdkerrors.ErrInvalidRequest` does. +It translates to the `Code` field in the `LastResultsHash` and participates in +its validation. + +### Variability in Gas Usage + +For transaction flows (or any other flow that consumes gas), it is important +that the gas usage is deterministic. + +Currently, gas usage is being Merklized in the state. As a result, reordering functions +becomes risky. + +Suppose my gas limit is 2000 and 1600 is used up before entering +`someInternalMethod`. Consider the following: + +```go +func someInternalMethod(ctx sdk.Context) { + object1 := readOnlyFunction1(ctx) # consumes 1000 gas + object2 := readOnlyFunction2(ctx) # consumes 500 gas + doStuff(ctx, object1, object2) +} +``` + +- It will run out of gas with `gasUsed = 2600` where 2600 getting merkelized +into the tx results. + +```go +func someInternalMethod(ctx sdk.Context) { + object2 := readOnlyFunction2(ctx) # consumes 500 gas + object1 := readOnlyFunction1(ctx) # consumes 1000 gas + doStuff(ctx, object1, object2) +} +``` + +- It will run out of gas with `gasUsed = 2100` where 2100 is getting merkelized +into the tx results. + +Therefore, we introduced a state-incompatibility by merklezing diverging gas +usage. + +## Secondary Limitations To Keep In Mind + +### Network Requests to External Services + +It is critical to avoid performing network requests to external services +since it is common for services to be unavailable or rate-limit. + +Imagine a service that returns exchange rates when clients query its HTTP endpoint. +This service might experience downtime or be restricted in some geographical areas. + +As a result, nodes may get diverging responses where some +get successful responses while others errors, leading to state breakage. + +### Randomness + +Randomness cannot be used in the state machine, as the state machine must be deterministic. + +**Note:** Iteration order over `map`s is non-deterministic, so to be deterministic +you must gather the keys, and sort them all prior to iterating over all values. + +### Parallelism and Shared State + +Threads and Goroutines might preempt differently in different hardware. Therefore, +they should be avoided for the sake of determinism. Additionally, it is hard +to predict when the multi-threaded state can be updated. + +### Hardware Errors + +This is out of the developer's control but is mentioned for completeness. \ No newline at end of file diff --git a/docs/old/testing.md b/TESTING.md similarity index 95% rename from docs/old/testing.md rename to TESTING.md index 4c288f5136..40117f9127 100644 --- a/docs/old/testing.md +++ b/TESTING.md @@ -29,15 +29,24 @@ Tests can be run using `make`: # run unit, integration, diff, and E2E tests make test -# run unit and integration tests - prefer this for local development -make test-short +# run unit tests +make test-unit + +# run integration tests +make test-integration # run difference tests -make test-diff +make test-difference + +# run unit, integration, and difference tests - shortcut for local development +mate test-dev # run E2E tests make test-e2e +# run only happy path E2E tests +make test-e2e-short + # equivalent to make test with caching disabled make test-no-cache ``` diff --git a/app/consumer-democracy/app.go b/app/consumer-democracy/app.go index 09b13520ae..7d5646f1dc 100644 --- a/app/consumer-democracy/app.go +++ b/app/consumer-democracy/app.go @@ -79,7 +79,6 @@ 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" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" @@ -112,7 +111,6 @@ import ( ccvdistr "github.com/cosmos/interchain-security/v3/x/ccv/democracy/distribution" ccvgov "github.com/cosmos/interchain-security/v3/x/ccv/democracy/governance" ccvstaking "github.com/cosmos/interchain-security/v3/x/ccv/democracy/staking" - ccvtypes "github.com/cosmos/interchain-security/v3/x/ccv/types" ) const ( @@ -713,7 +711,7 @@ func New( return fromVM, fmt.Errorf("failed to unmarshal genesis state: %w", err) } - consumerGenesis := ccvtypes.ConsumerGenesisState{} + consumerGenesis := consumertypes.GenesisState{} appCodec.MustUnmarshalJSON(appState[consumertypes.ModuleName], &consumerGenesis) consumerGenesis.PreCCV = true diff --git a/app/consumer/genesis.go b/app/consumer/genesis.go index 5bf0c1da80..f6641f45a7 100644 --- a/app/consumer/genesis.go +++ b/app/consumer/genesis.go @@ -2,8 +2,20 @@ package app import ( "encoding/json" + "fmt" + "os" + "path/filepath" + "strings" + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" "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/v3/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v3/x/ccv/types" ) // The genesis state of the blockchain is represented here as a map of raw json @@ -15,7 +27,103 @@ import ( // object provided to it during init. type GenesisState map[string]json.RawMessage +// Migration of consumer genesis content as it is exported from a provider version v1,2,3 +// to a format readable by current consumer implementation. +func transform(jsonRaw []byte, ctx client.Context) (json.RawMessage, error) { + // v1,2,3 uses deprecated fields of GenesisState type + oldConsumerGenesis := consumerTypes.GenesisState{} + err := ctx.Codec.UnmarshalJSON(jsonRaw, &oldConsumerGenesis) + if err != nil { + return nil, fmt.Errorf("reading consumer genesis data failed: %s", err) + } + + // some sanity checks for v2 transformation + if len(oldConsumerGenesis.Provider.InitialValSet) > 0 { + return nil, fmt.Errorf("invalid source version. Unexpected element 'provider.initial_val_set'") + } + + if oldConsumerGenesis.Provider.ClientState != nil { + return nil, fmt.Errorf("invalid source version. Unexpected element 'provider.client_state'") + } + + if oldConsumerGenesis.Provider.ConsensusState != nil { + return nil, fmt.Errorf("invalid source version. Unexpected element 'provider.consensus_state'") + } + + // Use DefaultRetryDelayPeriod if not set + if oldConsumerGenesis.Params.RetryDelayPeriod == 0 { + oldConsumerGenesis.Params.RetryDelayPeriod = types.DefaultRetryDelayPeriod + } + + // Version 2 of provider genesis data fills up deprecated fields + // ProviderClientState, ConsensusState and InitialValSet + newGenesis := types.ConsumerGenesisState{ + Params: oldConsumerGenesis.Params, + Provider: types.ProviderInfo{ + ClientState: oldConsumerGenesis.ProviderClientState, + ConsensusState: oldConsumerGenesis.ProviderConsensusState, + InitialValSet: oldConsumerGenesis.InitialValSet, + }, + } + + newJson, err := ctx.Codec.MarshalJSON(&newGenesis) + if err != nil { + return nil, fmt.Errorf("failed marshalling data to new type: %s", err) + } + return newJson, nil +} + +// Transform a consumer genesis json file exported from a given ccv provider version +// to a consumer genesis json format supported by current ccv consumer version. +// Result will be written to defined output. +func TransformConsumerGenesis(cmd *cobra.Command, args []string) error { + sourceFile := args[0] + + jsonRaw, err := os.ReadFile(filepath.Clean(sourceFile)) + if err != nil { + return err + } + + clientCtx := client.GetClientContextFromCmd(cmd) + newConsumerGenesis, err := transform(jsonRaw, clientCtx) + if err != nil { + return err + } + + bz, err := newConsumerGenesis.MarshalJSON() + if err != nil { + return fmt.Errorf("failed exporting new consumer genesis to JSON: %s", err) + } + + sortedBz, err := sdk.SortJSON(bz) + if err != nil { + return fmt.Errorf("failed sorting transformed consumer genesis JSON: %s", err) + } + + cmd.Println(string(sortedBz)) + return nil +} + // NewDefaultGenesisState generates the default state for the application. func NewDefaultGenesisState(cdc codec.JSONCodec) GenesisState { return ModuleBasics.DefaultGenesis(cdc) } + +// GetConsumerGenesisTransformCmd transforms Consumer Genesis JSON content exported from a +// provider version v1,v2 or v3 to a JSON format supported by this consumer version. +func GetConsumerGenesisTransformCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "transform [genesis-file]", + Short: "Transform CCV consumer genesis from an older provider version not supporting current format", + Long: strings.TrimSpace( + fmt.Sprintf(`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: +$ %s transform /path/to/ccv_consumer_genesis.json`, version.AppName), + ), + Args: cobra.ExactArgs(1), + RunE: TransformConsumerGenesis, + } + + return cmd +} diff --git a/app/consumer/genesis_test.go b/app/consumer/genesis_test.go new file mode 100644 index 0000000000..82292fbdbb --- /dev/null +++ b/app/consumer/genesis_test.go @@ -0,0 +1,215 @@ +package app_test + +import ( + "bytes" + "context" + "io/fs" + "os" + "path/filepath" + "testing" + "time" + + "github.com/spf13/cobra" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/x/auth/types" + + app "github.com/cosmos/interchain-security/v3/app/consumer" + consumerTypes "github.com/cosmos/interchain-security/v3/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v3/x/ccv/types" +) + +// Testdata mapping consumer genesis exports to a provider module version as +// used by transformation function for consumer genesis content. +var consumerGenesisStates map[string]string = map[string]string{ + "v2": ` + { + "params": { + "enabled": true, + "blocks_per_distribution_transmission": "1500", + "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": "1728000s", + "soft_opt_out_threshold": "", + "reward_denoms": [], + "provider_reward_denoms": [] + }, + "provider_client_id": "", + "provider_channel_id": "", + "new_chain": true, + "provider_client_state": { + "chain_id": "cosmoshub-4", + "trust_level": { + "numerator": "1", + "denominator": "3" + }, + "trusting_period": "1197504s", + "unbonding_period": "1814400s", + "max_clock_drift": "10s", + "frozen_height": { + "revision_number": "0", + "revision_height": "0" + }, + "latest_height": { + "revision_number": "4", + "revision_height": "15211521" + }, + "proof_specs": [ + { + "leaf_spec": { + "hash": "SHA256", + "prehash_key": "NO_HASH", + "prehash_value": "SHA256", + "length": "VAR_PROTO", + "prefix": "AA==" + }, + "inner_spec": { + "child_order": [ + 0, + 1 + ], + "child_size": 33, + "min_prefix_length": 4, + "max_prefix_length": 12, + "empty_child": null, + "hash": "SHA256" + }, + "max_depth": 0, + "min_depth": 0 + }, + { + "leaf_spec": { + "hash": "SHA256", + "prehash_key": "NO_HASH", + "prehash_value": "SHA256", + "length": "VAR_PROTO", + "prefix": "AA==" + }, + "inner_spec": { + "child_order": [ + 0, + 1 + ], + "child_size": 32, + "min_prefix_length": 1, + "max_prefix_length": 1, + "empty_child": null, + "hash": "SHA256" + }, + "max_depth": 0, + "min_depth": 0 + } + ], + "upgrade_path": [ + "upgrade", + "upgradedIBCState" + ], + "allow_update_after_expiry": true, + "allow_update_after_misbehaviour": true + }, + "provider_consensus_state": { + "timestamp": "2023-05-08T11:00:01.563901871Z", + "root": { + "hash": "qKVnVSXlsjDHC8ekKcy/0zSjzr3YekCurld9R4W07EI=" + }, + "next_validators_hash": "E08978F493101A3C5D459FB3087B8CFBA9E82D7A1FE1441E7D77E11AC0586BAC" + }, + "maturing_packets": [], + "initial_val_set": [ + { + "pub_key": { + "ed25519": "cOQZvh/h9ZioSeUMZB/1Vy1Xo5x2sjrVjlE/qHnYifM=" + }, + "power": "2345194" + }, + { + "pub_key": { + "ed25519": "vGSKfbQyKApvBhinpOOA0XQAdjxceihYNwtGskfZGyQ=" + }, + "power": "463811" + } + ], + "height_to_valset_update_id": [], + "outstanding_downtime_slashing": [], + "pending_consumer_packets": { + "list": [] + }, + "last_transmission_block_height": { + "height": "0" + }, + "preCCV": false + } + + `, +} + +func getClientCtx() client.Context { + encodingConfig := app.MakeTestEncodingConfig() + return client.Context{}. + WithCodec(encodingConfig.Codec). + WithInterfaceRegistry(encodingConfig.InterfaceRegistry). + WithTxConfig(encodingConfig.TxConfig). + WithLegacyAmino(encodingConfig.Amino). + WithInput(os.Stdin). + WithAccountRetriever(types.AccountRetriever{}) +} + +// Setup client context +func getGenesisTransformCmd() (*cobra.Command, error) { + cmd := app.GetConsumerGenesisTransformCmd() + clientCtx := getClientCtx() + ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx) + cmd.SetContext(ctx) + err := client.SetCmdClientContext(cmd, clientCtx) + return cmd, err +} + +// Check transformation of a version 2 ConsumerGenesis export to +// consumer genesis json format used by current consumer implementation. +func TestConsumerGenesisTransformationV2(t *testing.T) { + version := "v2" + filePath := filepath.Join(t.TempDir(), "oldConsumerGenesis.json") + + err := os.WriteFile( + filePath, + []byte(consumerGenesisStates[version]), + fs.FileMode(0o644)) + require.NoError(t, err) + defer os.Remove(filePath) + + cmd, err := getGenesisTransformCmd() + require.NoError(t, err, "Error setting up transformation command: %s", err) + cmd.SetArgs([]string{filePath}) + + output := new(bytes.Buffer) + cmd.SetOutput(output) + require.NoError(t, err) + _, err = cmd.ExecuteC() + require.NoError(t, err) + + consumerGenesis := consumerTypes.GenesisState{} + + bz := output.Bytes() + ctx := client.GetClientContextFromCmd(cmd) + err = ctx.Codec.UnmarshalJSON(bz, &consumerGenesis) + require.NoError(t, err, "Error unmarshalling transformed genesis state :%s", err) + + // Some basic sanity checks on the content. + require.Nil(t, consumerGenesis.ProviderClientState) + require.NotNil(t, consumerGenesis.Provider.ClientState) + require.Equal(t, "cosmoshub-4", consumerGenesis.Provider.ClientState.ChainId) + + require.Nil(t, consumerGenesis.ProviderConsensusState) + require.NotNil(t, consumerGenesis.Provider.ConsensusState) + require.Equal(t, time.Date(2023, time.May, 8, 11, 0, 1, 563901871, time.UTC), + consumerGenesis.Provider.ConsensusState.Timestamp) + + require.Empty(t, consumerGenesis.InitialValSet) + require.NotEmpty(t, consumerGenesis.Provider.InitialValSet) + require.Equal(t, consumerGenesis.Params.RetryDelayPeriod, ccvtypes.DefaultRetryDelayPeriod) +} diff --git a/app/provider/app.go b/app/provider/app.go index 4550ec77d2..f0f5e9e61e 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -140,7 +140,6 @@ var ( ibcclientclient.UpgradeProposalHandler, ibcproviderclient.ConsumerAdditionProposalHandler, ibcproviderclient.ConsumerRemovalProposalHandler, - ibcproviderclient.EquivocationProposalHandler, ibcproviderclient.ChangeRewardDenomsProposalHandler, }, ), @@ -204,7 +203,7 @@ type App struct { // nolint: golint // different fee-pool from the consumer chain ConsumerKeeper DistrKeeper distrkeeper.Keeper - GovKeeper govkeeper.Keeper + GovKeeper *govkeeper.Keeper // Gov Keeper must be a pointer in the app, so we can SetRouter on it correctly CrisisKeeper crisiskeeper.Keeper UpgradeKeeper upgradekeeper.Keeper ParamsKeeper paramskeeper.Keeper @@ -412,6 +411,17 @@ func New( app.SlashingKeeper, ) + app.GovKeeper = govkeeper.NewKeeper( + appCodec, + keys[govtypes.StoreKey], + app.AccountKeeper, + app.BankKeeper, + app.StakingKeeper, + app.MsgServiceRouter(), + govtypes.DefaultConfig(), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + app.ProviderKeeper = ibcproviderkeeper.NewKeeper( appCodec, keys[providertypes.StoreKey], @@ -424,9 +434,9 @@ func New( app.StakingKeeper, app.SlashingKeeper, app.AccountKeeper, - app.EvidenceKeeper, app.DistrKeeper, app.BankKeeper, + app.GovKeeper, authtypes.FeeCollectorName, ) @@ -441,22 +451,14 @@ func New( AddRoute(ibchost.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)). AddRoute(providertypes.RouterKey, ibcprovider.NewProviderProposalHandler(app.ProviderKeeper)). AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)) - 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(), - ) // Set legacy router for backwards compatibility with gov v1beta1 app.GovKeeper.SetLegacyRouter(govRouter) + app.GovKeeper = app.GovKeeper.SetHooks( + govtypes.NewMultiGovHooks(app.ProviderKeeper.Hooks()), + ) + app.TransferKeeper = ibctransferkeeper.NewKeeper( appCodec, keys[ibctransfertypes.StoreKey], @@ -477,6 +479,16 @@ 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 @@ -493,7 +505,7 @@ 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)), - gov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(govtypes.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)), distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)), @@ -590,7 +602,7 @@ func New( 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)), + 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)), diff --git a/cmd/interchain-security-cd/cmd/root.go b/cmd/interchain-security-cd/cmd/root.go index 30c032bbea..f1a8445982 100644 --- a/cmd/interchain-security-cd/cmd/root.go +++ b/cmd/interchain-security-cd/cmd/root.go @@ -202,7 +202,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { // add keybase, auxiliary RPC, query, genesis, and tx child commands rootCmd.AddCommand( rpc.StatusCommand(), - genesisCommand(encodingConfig), + genesisCommand(encodingConfig, consumer.GetConsumerGenesisTransformCmd()), queryCommand(), txCommand(), keys.Commands(consumer.DefaultNodeHome), diff --git a/docs/docs/adrs/adr-002-throttle.md b/docs/docs/adrs/adr-002-throttle.md index e60c619ca9..fe3d0a30b0 100644 --- a/docs/docs/adrs/adr-002-throttle.md +++ b/docs/docs/adrs/adr-002-throttle.md @@ -9,6 +9,7 @@ title: Jail Throttling * 2023-01-26: Initial Draft * 2023-02-07: Property refined, ADR ready to review/merge +* 2023-11-22: Refactor for better understanding ## Status @@ -16,58 +17,97 @@ Accepted ## Context -The CCV spec is based around the assumption that the provider binary and all consumers binaries are non-malicious, and follow the defined protocols. In practice, this assumption may not hold. A malicious consumer binary could potentially include code which is able to send many slash/jail packets at once to the provider. +The CCV spec is based around the assumption that the provider binary and all consumers binaries are non-malicious, and follow the defined protocols. +In practice, this assumption may not hold. +A malicious consumer binary could potentially include code which is able to send many slash/jail packets at once to the provider. -Before the throttling feature was implemented, the following attack was possible. Attacker(s) would create provider validators just below the provider's active set. Using a malicious consumer binary, slash packets would be relayed to the provider, that would slash/jail a significant portion (or all) of honest validator at once. Control of the provider would then pass over to the attackers' validators. This enables the attacker(s) to halt the provider. Or even worse, commit arbitrary state on the provider, potentially stealing all tokens bridged to the provider over IBC. +Before the throttling feature was implemented, the following attack was possible. +Attacker(s) would create provider validators just below the provider's active set. +Using a malicious consumer binary, slash packets would be relayed to the provider, that would slash/jail a significant portion (or all) of honest validator at once. +Control of the provider would then pass over to the attackers' validators. +This enables the attacker(s) to halt the provider. +Or even worse, commit arbitrary state on the provider, potentially stealing all tokens bridged to the provider over IBC. ## Decision -The throttling feature was designed to slow down the mentioned attack from above, allowing validators and the community to appropriately respond to the attack. Ie. this feature limits (enforced by on-chain params) the rate that the provider validator set can be jailed over time. +The throttling feature was designed to slow down the mentioned attack from above, allowing validators and the community to appropriately respond to the attack, +i.e., this feature limits (enforced by on-chain params) the rate that the provider validator set can be jailed over time. -### State Required - Slash Meter +### Required State -There exists one slash meter on the provider which stores an amount of voting power (integer), corresponding to an allowance of validators that can be jailed over time. This meter is initialized to a certain value on genesis, decremented by the amount of voting power jailed whenever a slash packet is handled, and periodically replenished as decided by on-chain params. +**Slash meter:** There exists one slash meter on the provider which stores an amount of voting power (integer), corresponding to an allowance of validators that can be jailed over time. +This meter is initialized to a certain value on genesis, decremented by the amount of voting power jailed whenever a slash packet is handled, and periodically replenished as decided by on-chain params. -### State Required - Global entry queue +**Global entry queue:** There exists a single queue which stores "global slash entries". +These entries allow the provider to appropriately handle slash packets sent from any consumer in FIFO ordering. +This queue is responsible for coordinating the order that slash packets (from multiple chains) are handled over time. -There exists a single queue which stores "global slash entries". These entries allow the provider to appropriately handle slash packets sent from any consumer in FIFO ordering. This queue is responsible for coordinating the order that slash packets (from multiple chains) are handled over time. +**Per-chain data queue:** For each established consumer, there exists a queue which stores "throttled packet data", +i.e.,pending slash packet data is queued together with pending VSC matured packet data in FIFO ordering. +Order is enforced by IBC sequence number. +These "per-chain" queues are responsible for coordinating the order that slash packets are handled in relation to VSC matured packets from the same chain. -### State Required - Per-chain data queue +_Note:_ The reason for a multiple-queue design is the _VSC Maturity and Slashing Order_ property (see [spec](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/system_model_and_properties.md#consumer-initiated-slashing)). +There are other ways to ensure such a property (like a queue of linked lists, etc.), but the proposed approach seemed to be the most understandable and easiest to implement with a KV store. -For each established consumer, there exists a queue which stores "throttled packet data". Ie. pending slash packet data is queued together with pending VSC matured packet data in FIFO ordering. Order is enforced by IBC sequence number. These "per-chain" queues are responsible for coordinating the order that slash packets are handled in relation to VSC matured packets from the same chain. +### Params -### Reasoning - Multiple queues +`SlashMeterReplenishPeriod` -- the period after which the slash meter is replenished. -For reasoning on why this feature was implemented with multiple queues, see [spec](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/system_model_and_properties.md#consumer-initiated-slashing). Specifically the section on _VSC Maturity and Slashing Order_. There are other ways to ensure such a property (like a queue of linked lists, etc.), but the implemented protocol seemed to be the most understandable and easiest to implement with a KV store. +`SlashMeterReplenishFraction` -- the portion (in range [0, 1]) of total voting power that is replenished to the slash meter when a replenishment occurs. This param also serves as a maximum fraction of total voting power that the slash meter can hold. -### Protocol Overview - OnRecvSlashPacket +`MaxThrottledPackets` -- the maximum amount of throttled slash or vsc matured packets that can be queued from a single consumer before the provider chain halts, it should be set to a large value. +This param would allow provider binaries to panic deterministically in the event that packet throttling results in a large amount of state-bloat. In such a scenario, packet throttling could prevent a violation of safety caused by a malicious consumer, at the cost of provider liveness. + +### Protocol Overview + +#### OnRecvSlashPacket Upon the provider receiving a slash packet from any of the established consumers during block execution, two things occur: 1. A global slash entry is queued. 2. The data of such a packet is added to the per-chain queue. -### Protocol Overview - OnRecvVSCMaturedPacket +#### OnRecvVSCMaturedPacket Upon the provider receiving a VSCMatured packet from any of the established consumers during block execution, the VSCMatured packet data is added to the per-chain queue. -### Endblocker Step 1 - Slash Meter Replenishment +#### Endblocker + +In the `EndBlock` of the provider CCV module, there are three actions performed: + +- replenish the slash meter; +- handle the leading `VSCMaturedPackets`; +- and handle the throttle queues. + +##### Slash Meter Replenishment -Once the slash meter becomes not full, it'll be replenished after `SlashMeterReplenishPeriod (param)` by incrementing the meter with its allowance for the replenishment block, where `allowance` = `SlashMeterReplenishFraction (param)` * `currentTotalVotingPower`. The slash meter will never exceed its current allowance (fn of the total voting power for the block) in value. Note a few things: +Once the slash meter becomes not full, it'll be replenished after `SlashMeterReplenishPeriod` by incrementing the meter with its allowance for the replenishment block, where `allowance` = `SlashMeterReplenishFraction` * `currentTotalVotingPower`. +The slash meter will never exceed its current allowance (function of the total voting power for the block) in value. -1. The slash meter can go negative in value, and will do so when handling a single slash packet that jails a validator with significant voting power. In such a scenario, the slash meter may take multiple replenishment periods to once again reach a positive value (or 0), meaning no other slash packets may be handled for multiple replenishment periods. -2. Total voting power of a chain changes over time, especially as validators are jailed. As validators are jailed, total voting power decreases, and so does the jailing allowance. See below for more detailed throttling property discussion. -3. The voting power allowance added to the slash meter during replenishment will always be greater than or equal to 1. If the `SlashMeterReplenishFraction (param)` is set too low, integer rounding will put this minimum value into effect. That is, if `SlashMeterReplenishFraction` * `currentTotalVotingPower` < 1, then the effective allowance would be 1. This min value of allowance ensures that there's some packets handled over time, even if that is a very long time. It's a crude solution to an edge case caused by too small of a replenishment fraction. +Note a few things: -The behavior described above is achieved by executing `CheckForSlashMeterReplenishment()` every endblock, BEFORE `HandleThrottleQueues()` is executed. +1. The slash meter can go negative in value, and will do so when handling a single slash packet that jails a validator with significant voting power. + In such a scenario, the slash meter may take multiple replenishment periods to once again reach a positive value (or 0), meaning no other slash packets may be handled for multiple replenishment periods. +2. Total voting power of a chain changes over time, especially as validators are jailed. + As validators are jailed, total voting power decreases, and so does the jailing allowance. + See below for more detailed throttling property discussion. +3. The voting power allowance added to the slash meter during replenishment will always be greater than or equal to 1. + If the `SlashMeterReplenishFraction` is set too low, integer rounding will put this minimum value into effect. + That is, if `SlashMeterReplenishFraction` * `currentTotalVotingPower` < 1, then the effective allowance would be 1. + This min value of allowance ensures that there's some packets handled over time, even if that is a very long time. + It's a crude solution to an edge case caused by too small of a replenishment fraction. -### Endblocker Step 2 - HandleLeadingVSCMaturedPackets +The behavior described above is achieved by executing `CheckForSlashMeterReplenishment()` every `EndBlock`, BEFORE `HandleThrottleQueues()` is executed. -Every block it is possible that VSCMatured packet data was queued before any slash packet data. Since this "leading" VSCMatured packet data does not have to be throttled (see _VSC Maturity and Slashing Order_), we can handle all VSCMatured packet data at the head of the queue, before the any throttling or packet data handling logic executes. +##### Handle Leading VSCMaturedPackets -### Endblocker Step 3 - HandleThrottleQueues +In every block, it is possible that `VSCMaturedPacket` data was queued before any slash packet data. +Since this "leading" VSCMatured packet data does not have to be throttled (see _VSC Maturity and Slashing Order_), we can handle all VSCMatured packet data at the head of the queue, before the any throttling or packet data handling logic executes. -Every endblocker the following pseudo-code is executed to handle data from the throttle queues. +##### Handle Throttle Queues + +In every `EndBlock`, the following logic is executed to handle data from the throttle queues. ```typescript meter := getSlashMeter() @@ -91,55 +131,59 @@ while meter.IsPositiveOrZero() && entriesExist() { ### System Properties -All CCV system properties should be maintained by implementing this feature, see: [CCV spec - Consumer Initiated Slashing](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/system_model_and_properties.md#consumer-initiated-slashing). +All CCV system properties should be maintained by implementing this feature, see [CCV spec - Consumer Initiated Slashing](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/system_model_and_properties.md#consumer-initiated-slashing). -One implementation-specific property introduced is that if any of the chain-specific packet data queues become larger than `MaxThrottledPackets (param)`, then the provider binary will panic, and the provider chain will halt. Therefore this param should be set carefully. See `SetThrottledPacketDataSize`. This behavior ensures that if the provider binaries are queuing up more packet data than machines can handle, the provider chain halts deterministically between validators. +One implementation-specific property introduced is that if any of the chain-specific packet data queues become larger than `MaxThrottledPackets`, then the provider binary will panic, and the provider chain will halt. +Therefore this param should be set carefully. See `SetThrottledPacketDataSize`. +This behavior ensures that if the provider binaries are queuing up more packet data than machines can handle, the provider chain halts deterministically between validators. ### Main Throttling Property Using on-chain params and the sub protocol defined, slash packet throttling is implemented such that the following property holds under some conditions. -First, we define the following: +First, we introduce the following definitions: * A consumer initiated slash attack "starts" when the first slash packet from such an attack is received by the provider. * The "initial validator set" for the attack is the validator set that existed on the provider when the attack started. -* There is a list of honest validators s.t if they are jailed, `X`% of the initial validator set will be jailed. +* There is a list of honest validators such that if they are jailed, `X`% of the initial validator set will be jailed. -For the following property to hold, these assumptions must be true: +For the Throttling Property to hold, the following assumptions must be true: 1. We assume the total voting power of the chain (as a function of delegations) does not increase over the course of the attack. 2. No validator has more than `SlashMeterReplenishFraction` of total voting power on the provider. -3. `SlashMeterReplenishFraction` is large enough that `SlashMeterReplenishFraction` * `currentTotalVotingPower` > 1. Ie. the replenish fraction is set high enough that we can ignore the effects of rounding. +3. `SlashMeterReplenishFraction` is large enough that `SlashMeterReplenishFraction` * `currentTotalVotingPower` > 1, + i.e., the replenish fraction is set high enough that we can ignore the effects of rounding. 4. `SlashMeterReplenishPeriod` is sufficiently longer than the time it takes to produce a block. _Note if these assumptions do not hold, throttling will still slow down the described attack in most cases, just not in a way that can be succinctly described. It's possible that more complex properties can be defined._ -Property: - -> The time it takes to jail/tombstone `X`% of the initial validator set will be greater than or equal to `(X * SlashMeterReplenishPeriod / SlashMeterReplenishFraction) - 2 * SlashMeterReplenishPeriod` - -Intuition: - -Let's use the following notation: - -* $C$: Number of replenishment cycles -* $P$: $\text{SlashMeterReplenishPeriod}$ -* $F$: $\text{SlashMeterReplenishFraction}$ -* $V_{\mathit{max}}$: Max power of a validator as a fraction of total voting power - -In $C$ number of replenishment cycles, the fraction of total voting power that can be removed, $a$, is $a \leq F \cdot C + V_{\mathit{max}}$ (where $V_{\mathit{max}}$ is there to account for the power fraction of the last validator removed, one which pushes the meter to the negative value). - -So, we need at least $C \geq \frac{a - V_{\mathit{max}}}{F}$ cycles to remove $a$ fraction of the total voting power. - -Since we defined the start of the attack to be the moment when the first slash request arrives, then $F$ fraction of the initial validator set can be jailed immediately. For the remaining $X - F$ fraction of the initial validator set to be jailed, it takes at least $C \geq \frac{(X - F) - V_{\mathit{max}}}{F}$ cycles. Using the assumption that $V_{\mathit{max}} \leq F$ (assumption 2), we get $C \geq \frac{X - 2F}{F}$ cycles. - -In order to execute $C$ cycles, we need $C \cdot P$ time. - -Thus, jailing the remaining $X - F$ fraction of the initial validator set corresponds to $\frac{P \cdot (X - 2F)}{F}$ time. - -In other words, the attack must take at least $\frac{P \cdot X}{F} - 2P$ time (in the units of replenish period $P$). - -This property is useful because it allows us to reason about the time it takes to jail a certain percentage of the initial provider validator set from consumer initiated slash requests. For example, if `SlashMeterReplenishFraction` is set to 0.06, then it takes no less than 4 replenishment periods to jail 33% of the initial provider validator set on the Cosmos Hub. Note that as of writing this on 11/29/22, the Cosmos Hub does not have a validator with more than 6% of total voting power. +**Throttling Property**: The time it takes to jail/tombstone `X`% of the initial validator set will be greater than or equal to +$\mathit{SlashMeterReplenishPeriod} \cdot \frac{X}{\mathit{SlashMeterReplenishFraction}} - 2 \cdot \mathit{SlashMeterReplenishPeriod}$. + +> **Intuition** +> +> Let's use the following notation: +> +> * $C$: Number of replenishment cycles +> * $P$: $\mathit{SlashMeterReplenishPeriod}$ +> * $F$: $\mathit{SlashMeterReplenishFraction}$ +> * $V_{\mathit{max}}$: Max power of a validator as a fraction of total voting power +> +> In $C$ number of replenishment cycles, the fraction of total voting power that can be removed, $a$, is $a \leq F \cdot C + V_{\mathit{max}}$ (where $V_{\mathit{max}}$ is there to account for the power fraction of the last validator removed, one which pushes the meter to the negative value). +> +> So, we need at least $C \geq \frac{a - V_{\mathit{max}}}{F}$ cycles to remove $a$ fraction of the total voting power. +> +> Since we defined the start of the attack to be the moment when the first slash request arrives, then $F$ fraction of the initial validator set can be jailed immediately. For the remaining $X - F$ fraction of the initial validator set to be jailed, it takes at least $C \geq \frac{(X - F) - V_{\mathit{max}}}{F}$ cycles. Using the assumption that $V_{\mathit{max}} \leq F$ (assumption 2), we get $C \geq \frac{X - 2F}{F}$ cycles. +> +> In order to execute $C$ cycles, we need $C \cdot P$ time. +> +> Thus, jailing the remaining $X - F$ fraction of the initial validator set corresponds to $\frac{P \cdot (X - 2F)}{F}$ time. +> +> In other words, the attack must take at least $\frac{P \cdot X}{F} - 2P$ time (in the units of replenish period $P$). + +This property is useful because it allows us to reason about the time it takes to jail a certain percentage of the initial provider validator set from consumer initiated slash requests. +For example, if `SlashMeterReplenishFraction` is set to `0.06`, then it takes no less than 4 replenishment periods to jail 33% of the initial provider validator set on the Cosmos Hub. +Note that as of writing this on 11/29/22, the Cosmos Hub does not have a validator with more than 6% of total voting power. Note also that 4 replenishment period is a worst case scenario that depends on well crafted attack timings. @@ -160,7 +204,9 @@ In summary, the throttling mechanism as designed has desirable properties whethe ### Negative -* Throttling introduces a vector for a malicious consumer chain to halt the provider, see issue below. However, this is sacrificing liveness in a edge case scenario for the sake of security. As an improvement, [using retries](https://github.com/cosmos/interchain-security/issues/713) would fully prevent this attack vector. +* Throttling introduces a vector for a malicious consumer chain to halt the provider, see issue below. + However, this is sacrificing liveness in a edge case scenario for the sake of security. + As an improvement, [using retries](https://github.com/cosmos/interchain-security/issues/713) would fully prevent this attack vector. ### Neutral diff --git a/docs/docs/adrs/adr-005-cryptographic-equivocation-verification.md b/docs/docs/adrs/adr-005-cryptographic-equivocation-verification.md index 657ca25355..d4f9bd2bf8 100644 --- a/docs/docs/adrs/adr-005-cryptographic-equivocation-verification.md +++ b/docs/docs/adrs/adr-005-cryptographic-equivocation-verification.md @@ -158,4 +158,4 @@ light client or double signing attacks on a consumer chain. * [ICS misbehaviour handling PR](https://github.com/cosmos/interchain-security/pull/826) * [Consumer double voting handler PR](https://github.com/cosmos/interchain-security/pull/1232) * [Architectural diagrams](https://docs.google.com/document/d/1fe1uSJl1ZIYWXoME3Yf4Aodvz7V597Ric875JH-rigM/edit#heading=h.rv4t8i6d6jfn) -* [ADR on equivocation slashing](https://github.com/cosmos/interchain-security/blob/main/docs/docs/adrs/adr-013-equivocation-slashing.md) \ No newline at end of file +* [ADR on equivocation slashing](https://github.com/cosmos/interchain-security/blob/main/docs/docs/adrs/adr-013-equivocation-slashing.md) diff --git a/docs/docs/adrs/adr-008-throttle-retries.md b/docs/docs/adrs/adr-008-throttle-retries.md index 1faf7bd7ee..7c5015d512 100644 --- a/docs/docs/adrs/adr-008-throttle-retries.md +++ b/docs/docs/adrs/adr-008-throttle-retries.md @@ -21,44 +21,66 @@ For context on why the throttling mechanism exists, see [ADR 002](./adr-002-thro Note the terms slash throttling and jail throttling are synonymous, since in replicated 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 slash packets can be handled over time. Throttled slash packets are persisted on the provider, leading to multiple possible issues. Namely: +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: -* If slash or vsc matured packets are actually throttled/queued on the provider, state can grow and potentially lead to a DoS attack. We have short term solutions around this, but overall they come with their own weaknesses. See [#594](https://github.com/cosmos/interchain-security/issues/594). -* If a jailing attack described in [ADR 002](adr-002-throttle.md) were actually to be carried out with the current throttling design, we'd likely have to halt the provider, and perform an emergency upgrade and/or migration to clear the queues of slash packets that were deemed to be malicious. Alternatively, validators would just have to _tough it out_ and wait for the queues to clear, during which all/most validators would be jailed. Right after being jailed, vals would have to unjail themselves promptly to ensure safety. The synchronous coordination required to maintain safety in such a scenario is not ideal. +* If `SlashPackets` or `VSCMaturedPackets` are actually throttled/queued on the provider, state can grow and potentially lead to a DoS attack. + We have short term solutions around this, but overall they come with their own weaknesses. + See [#594](https://github.com/cosmos/interchain-security/issues/594). +* If a jailing attack described in [ADR 002](adr-002-throttle.md) were actually to be carried out with the current throttling design, we'd likely have to halt the provider, and perform an emergency upgrade and/or migration to clear the queues of `SlashPackets` that were deemed to be malicious. + Alternatively, validators would just have to _tough it out_ and wait for the queues to clear, during which all/most validators would be jailed. + Right after being jailed, validators would have to unjail themselves promptly to ensure safety. + The coordination required to maintain safety in such a scenario is not ideal. -So what's the solution? We can improve the throttling mechanism to instead queue/persist relevant data on each consumer, and have consumers retry slash requests as needed. +As as solution, we can improve the throttling mechanism to instead queue/persist relevant data on each consumer, and have consumers retry slash requests as needed. ## Decision ### Consumer changes -Note the consumer already queues up both slash and vsc matured packets via `AppendPendingPacket`. Those packets are dequeued every endblock in `SendPackets` and sent to the provider. +Note the consumer already queues up both `SlashPackets` and `VSCMaturedPackets` via `AppendPendingPacket`. +Those packets are dequeued in every `EndBlock` in `SendPackets` and sent to the provider. -Instead, we will now introduce the following logic on endblock: +Instead, we will now introduce the following logic on `EndBlock`: -* Slash packets will always be sent to the provider once they're at the head of the queue. However, once sent, the consumer will not send any trailing vsc matured packets from the queue until the provider responds with an ack that the slash packet has been handled (ie. val was jailed). That is, slash packets block the sending of trailing vsc matured packets in the consumer queue. -* If two slash packets are at the head of the queue, the consumer will send the first slash packet, and then wait for a success ack from the provider before sending the second slash packet. This seems like it'd simplify implementation. -* VSC matured packets at the head of the queue (ie. NOT trailing a slash packet) can be sent immediately, and do not block any other packets in the queue, since the provider always handles them immediately. +* Slash packets will always be sent to the provider once they're at the head of the queue. + However, once sent, the consumer will not send any subsequent `VSCMaturedPackets` from the queue until the provider responds with an acknowledgement that the sent `SlashPacket` has been handled, i.e., validator was jailed. + That is, `SlashPackets` block the sending of subsequent `VSCMaturedPackets` in the consumer queue. +* If two `SlashPackets` are at the head of the queue, the consumer will send the first `SlashPacket`, and then wait for a success acknowledgement from the provider before sending the second `SlashPacket`. + This seems like it'd simplify implementation. +* `VSCMaturedPackets` at the head of the queue (i.e., NOT following a `SlashPacket`) can be sent immediately, and do not block any other packets in the queue, since the provider always handles them immediately. -To prevent the provider from having to keep track of what slash packets have been rejected, the consumer will have to retry the sending of slash packets over some period of time. This can be achieved with an on-chain consumer param. The suggested param value would probably be 1/2 of the provider's `SlashMeterReplenishmentPeriod`, although it doesn't matter too much as long as the param value is sane. +To prevent the provider from having to keep track of what `SlashPackets` have been rejected, the consumer will have to retry the sending of `SlashPackets` over some period of time. +This can be achieved with an on-chain consumer param, i.e., `RetryDelayPeriod`. +To reduce the amount of redundant re-sends, we recommend setting `RetryDelayPeriod ~ SlashMeterReplenishmentPeriod`, i.e., waiting for the provider slash meter to be replenished before resending the rejected `SlashPacket`. -Note to prevent weird edge case behavior, a retry would not be attempted until either a success ack or failure ack has been recv from the provider. +Note to prevent weird edge case behavior, a retry would not be attempted until either a success or failure acknowledgement has been received from the provider. -With the behavior described, we maintain very similar behavior to the current throttling mechanism regarding the timing that slash and vsc matured packets are handled on the provider. Obviously the queueing and blocking logic is moved, and the two chains would have to send more messages between one another (only in the case the throttling mechanism is triggered). +With the behavior described, we maintain very similar behavior to the previous throttling mechanism regarding the timing that `SlashPackets` and `VSCMaturedPackets` are handled on the provider. +Obviously the queueing and blocking logic is moved, and the two chains would have to send more messages between one another (only in the case the throttling mechanism is triggered). -In the normal case, when no or a few slash packets are being sent, the VSCMaturedPackets will not be delayed, and hence unbonding will not be delayed. +In the normal case, when no or a few `SlashPackets` are being sent, the `VSCMaturedPackets` will not be delayed, and hence unbonding will not be delayed. -For implementation of this design, see [throttle_retry.go](../../../x/ccv/consumer/keeper/throttle_retry.go). +For the implementation of this design, see [throttle_retry.go](https://github.com/cosmos/interchain-security/blob/fec3eccad59416cbdb6844e279f59e3f81242888/x/ccv/consumer/keeper/throttle_retry.go). -### Consumer pending packets storage optimization +#### Consumer pending packets storage optimization -In addition to the mentioned consumer changes above. An optimization will need to be made to the consumer's pending packets storage to properly implement the feature from this ADR. +In addition to the mentioned consumer changes, an optimization will need to be made to the consumer's pending packets storage to properly implement the feature from this ADR. -The consumer ccv module previously queued "pending packets" to be sent on each endblocker in [SendPackets](https://github.com/cosmos/interchain-security/blob/3bc4e7135066d848aac60b0787364c07157fd36d/x/ccv/consumer/keeper/relay.go#L178). These packets are queued in state with a protobuf list of `ConsumerPacketData`. For a single append operation, the entire list is deserialized, then a packet is appended to that list, and the list is serialized again. See older version of [AppendPendingPacket](https://github.com/cosmos/interchain-security/blob/05c2dae7c6372b1252b9e97215d07c6aa7618f33/x/ccv/consumer/keeper/keeper.go#L606). That is, a single append operation has O(N) complexity, where N is the size of the list. +The consumer ccv module previously queued "pending packets" to be sent in each `EndBlock` in [SendPackets](https://github.com/cosmos/interchain-security/blob/3bc4e7135066d848aac60b0787364c07157fd36d/x/ccv/consumer/keeper/relay.go#L178). +These packets are queued in state with a protobuf list of `ConsumerPacketData`. +For a single append operation, the entire list is deserialized, then a packet is appended to that list, and the list is serialized again. +See older version of [AppendPendingPacket](https://github.com/cosmos/interchain-security/blob/05c2dae7c6372b1252b9e97215d07c6aa7618f33/x/ccv/consumer/keeper/keeper.go#L606). +That is, a single append operation has O(N) complexity, where N is the size of the list. -This poor append performance isn't a problem when the pending packets list is small. But with this ADR being implemented, the pending packets list could potentially grow to the order of thousands of entries, in the scenario that a slash packet is bouncing. +This poor append performance isn't a problem when the pending packets list is small. +But with this ADR being implemented, the pending packets list could potentially grow to the order of thousands of entries when `SlashPackets` need to be resent. -We can improve the append time for this queue by converting it from a protobuf-esq list, to a queue implemented with sdk-esq code. The idea is to persist an uint64 index that will be incremented each time you queue up a packet. You can think of this as storing the tail of the queue. Then, packet data will be keyed by that index, making the data naturally ordered byte-wise for sdk's iterator. The index will also be stored in the packet data value bytes, so that the index can later be used to delete certain packets from the queue. +We can improve the append time for this queue by converting it from a protobuf-esq list, to a queue implemented with sdk-esq code. +The idea is to persist an uint64 index that will be incremented each time you queue up a packet. +You can think of this as storing the tail of the queue. +Then, packet data will be keyed by that index, making the data naturally ordered byte-wise for sdk's iterator. +The index will also be stored in the packet data value bytes, so that the index can later be used to delete certain packets from the queue. Two things are achieved with this approach: @@ -67,33 +89,44 @@ Two things are achieved with this approach: ### Provider changes -The main change needed for the provider is the removal of queuing logic for slash and vsc matured packets upon being received. +The main change needed for the provider is the removal of queuing logic for `SlashPackets` and `VSCMaturedPackets` upon being received. -Instead, the provider will consult the slash meter to determine if a slash packet can be handled immediately. If not, the provider will return an ack message to the consumer communicating that the slash packet could not be handled, and needs to be sent again in the future (retried). +Instead, the provider will consult the slash meter to determine if a `SlashPacket` can be handled immediately. +If not, the provider will return an acknowledgement message to the consumer communicating that the `SlashPacket` could not be handled, and needs to be sent again in the future (retried). -VSCMatured packets will always be handled immediately upon being received by the provider. +`VSCMaturedPackets` will always be handled immediately upon being received by the provider. Note [spec](https://github.com/cosmos/ibc/blob/main/spec/app/ics-028-cross-chain-validation/system_model_and_properties.md#consumer-initiated-slashing). Specifically the section on _VSC Maturity and Slashing Order_. Previously the onus was on the provider to maintain this property via queuing packets and handling them FIFO. -Now this property will be maintained by the consumer sending packets in the correct order, and blocking the sending of VSCMatured packets as needed. Then, the ordered IBC channel will ensure that Slash/VSCMatured packets are received in the correct order on the provider. +Now this property will be maintained by the consumer sending packets in the correct order, and blocking the sending of `VSCMaturedPackets` as needed. Then, the ordered IBC channel will ensure that `SlashPackets` and `VSCMaturedPackets` are received in the correct order on the provider. -The provider's main responsibility regarding throttling will now be to determine if a recv slash packet can be handled via slash meter etc., and appropriately ack to the sending consumer. +The provider's main responsibility regarding throttling will now be to determine if a received `SlashPacket` can be handled via slash meter etc., and appropriately acknowledge to the sending consumer. -### Why the provider can handle VSCMatured packets immediately +#### Handling `VSCMaturedPackets` immediately -First we answer, what does a VSCMatured packet communicate to the provider? A VSCMatured packet communicates that a VSC has been applied to a consumer long enough that infractions committed on the consumer could have been submitted. +#### Why the provider can handle VSCMatured packets immediately -If the consumer is following the queuing/blocking protocol described. No bad behavior occurs, `VSC Maturity and Slashing Order` property is maintained. +A `VSCMaturedPacket` communicates to the provider that sufficient time passed on the consumer since the corresponding `VSCPacket` has been applied (on the consumer) such that infractions committed on the consumer could have been submitted. -If a consumer sends VSCMatured packets too leniently: The consumer is malicious and sending duplicate vsc matured packets, or sending the packets sooner than the ccv protocol specifies. In this scenario, the provider needs to handle vsc matured packets immediately to prevent DOS, state bloat, or other issues. The only possible negative outcome is that the malicious consumer may not be able to jail a validator who should have been jailed. The malicious behavior only creates a negative outcome for the chain that is being malicious. +If the consumer is following the queuing/blocking protocol described, then no bad behavior occurs and the _VSC Maturity and Slashing Order_ property is maintained. -If a consumer blocks the sending of VSCMatured packets: The consumer is malicious and blocking vsc matured packets that should have been sent. This will block unbonding only up until the VSC timeout period has elapsed. At that time, the consumer is removed. Again the malicious behavior only creates a negative outcome for the chain that is being malicious. +If a consumer sends `VSCMaturedPackets` too leniently -- the consumer is malicious and sends duplicate `VSCMaturedPackets`, or sends the packets sooner than the CCV protocol specifies -- then the provider needs to handle `VSCMaturedPackets` immediately to prevent DOS, state bloat, or other issues. +The only possible negative outcome is that the malicious consumer may not be able to jail a validator who should have been jailed. +The malicious behavior only creates a negative outcome for the consumer chain that is being malicious. + +If a consumer blocks the sending of `VSCMaturedPackets`, then unbonding operations on the provider will be delayed, but only until the VSC timeout period has elapsed. +At that time, the consumer is removed. +Again the malicious behavior only creates a negative outcome for the consumer chain that is being malicious. ### Splitting of PRs and Upgrade Order -This feature will implement consumer changes in [#1024](https://github.com/cosmos/interchain-security/pull/1024). Note these changes should be deployed to prod for all consumers before the provider changes are deployed to prod. That is the consumer changes in #1024 are compatible with the current ("v1") provider implementation of throttling that's running on the Cosmos Hub as of July 2023. +This feature will implement consumer changes in [#1024](https://github.com/cosmos/interchain-security/pull/1024). + +❗***These changes should be deployed to production for all consumers before the provider changes are deployed to production.*** + +In other words, the consumer changes in [#1024](https://github.com/cosmos/interchain-security/pull/1024) are compatible with the current ("v1") provider implementation of throttling that's running on the Cosmos Hub as of July 2023. -Once all consumers have deployed the changes in #1024, the provider changes from (TBD) can be deployed to prod, fully enabling v2 throttling. +Once all consumers have deployed the changes in #1024, the provider changes from [#1321](https://github.com/cosmos/interchain-security/pull/1321) can be deployed to production, fully enabling v2 throttling. ## Consequences @@ -101,12 +134,13 @@ Once all consumers have deployed the changes in #1024, the provider changes from * Consumers still aren't trustless, but the provider is now less susceptible to mismanaged or malicious consumers. * Recovering from the "jailing attack" is more elegant. * Some issues like [#1001](https://github.com/cosmos/interchain-security/issues/1001) will now be handled implicitly by the improved throttling mechanism. -* Slash and vsc matured packets can be handled immediately once recv by the provider if the slash meter allows. -* In general, we reduce the amount of computation that happens in the provider end-blocker. +* `SlashPackets` and `VSCMaturedPackets` can be handled immediately once received by the provider if the slash meter allows. +* In general, we reduce the amount of computation that happens in the provider `EndBlock`. ### Positive -* We no longer have to reason about a "global queue" and a "chain specific queue", and keeping those all in-sync. Now slash and vsc matured packet queuing is handled on each consumer individually. +* We no longer have to reason about a "global queue" and a "chain specific queue", and keeping those all in-sync. + Now `SlashPackets` and `VSCMaturedPackets` queuing is handled on each consumer individually. * Due to the above, the throttling protocol becomes less complex overall. * We no longer have to worry about throttle related DoS attack on the provider, since no queuing exists on the provider. @@ -117,7 +151,7 @@ Once all consumers have deployed the changes in #1024, the provider changes from ### Neutral -* Core throttling logic on the provider remains unchanged, ie. slash meter, replenishment cycles, etc. +* Core throttling logic on the provider remains unchanged, i.e., slash meter, replenishment cycles, etc. ## References diff --git a/docs/docs/adrs/adr-012-separate-releasing.md b/docs/docs/adrs/adr-012-separate-releasing.md index 386c8add29..fbc4b94198 100644 --- a/docs/docs/adrs/adr-012-separate-releasing.md +++ b/docs/docs/adrs/adr-012-separate-releasing.md @@ -8,10 +8,11 @@ title: Separate Releasing * {8/18/22}: Initial draft of idea in [#801](https://github.com/cosmos/interchain-security/issues/801) * {8/22/22}: Put idea in this ADR +* {11/10/22}: Reject this ADR ## Status -Accepted +Rejected ## Context @@ -63,8 +64,12 @@ We upgrade `main` to use a new version of SDK. This is a major version bump, tri ### Negative -* Slightly more complexity. -* This solution does not allow having provider and consumer on separate versions of e.g. the Cosmos SDK +* ~~Slightly more complexity.~~Considerably more complex to manage the ICS library. + This is because ICS needs to support multiple versions of SDK (e.g., 0.45, 0.47, 0.50). + In addition, ICS needs to support a special fork of SDK (with LSM included) for the Cosmos Hub. + This means that instead of focusing on main the development team needs to manage multiple release + branches with different dependency trees. +* This solution does not allow having provider and consumer on separate versions of e.g. the Cosmos SDK. ### Neutral diff --git a/docs/docs/consumer-development/changeover-procedure.md b/docs/docs/consumer-development/changeover-procedure.md index 825a0bdae4..446f91775b 100644 --- a/docs/docs/consumer-development/changeover-procedure.md +++ b/docs/docs/consumer-development/changeover-procedure.md @@ -48,7 +48,7 @@ RevisionNumber: 0, RevisionHeight: 111 * `spawn_time` listed in the proposal MUST be before the `upgrade_height` listed in the the upgrade proposal on the standalone chain. :::caution -`spawn_time` must occur before the `upgrade_height` on the standalone chain is reached becasue the `provider` chain must generate the `ConsumerGenesis` that contains the **validator set** that will be used after the changeover. +`spawn_time` must occur before the `upgrade_height` on the standalone chain is reached because the `provider` chain must generate the `ConsumerGenesis` that contains the **validator set** that will be used after the changeover. ::: * `unbonding_period` must correspond to the value used on the standalone chain. Otherwise, the clients used for the ccv protocol may be incorrectly initialized. @@ -128,7 +128,7 @@ To help validators and other node runners onboard onto your chain, please prepar This should include (at minimum): -- [ ] genesis.json with CCV data (after spawn time passes) +- [ ] genesis.json with CCV data (after spawn time passes). Check if CCV data needs to be transformed (see [Transform Consumer Genesis](./consumer-genesis-transformation.md)) - [ ] information about relevant seed/peer nodes you are running - [ ] relayer information (compatible versions) - [ ] copy of your governance proposal (as JSON) diff --git a/docs/docs/consumer-development/consumer-genesis-transformation.md b/docs/docs/consumer-development/consumer-genesis-transformation.md new file mode 100644 index 0000000000..5a19e5c71d --- /dev/null +++ b/docs/docs/consumer-development/consumer-genesis-transformation.md @@ -0,0 +1,29 @@ +--- +sidebar_position: 6 +--- + +# Consumer Genesis Transformation + +Preparing a consumer chain for onboarding requires some information explaining how to run your chain. This includes a genesis file with CCV data where the CCV data is exported from the provider chain and added to the consumers genesis file (for more details check the documentaion on [Onboarding](./onboarding.md) and [Changeover](./changeover-procedure.md)). +In case that the provider chain is running an older version of the InterChainSecurity (ICS) module than the consumer chain the exported CCV data might need to be transformed to the format supported by the ICS implementation run on the consumer chain. This is the case if the cosumer chain runs version 4 of ICS or later and the provider is running version 3 or older of the ICS module. + +To transform such CCV data follow the instructions below + +## 1. Prerequisite +- Provider chain is running version 3 or older of the ICS provider module +- Consumer is running version 4 or later of the ICS consumer module. +- interchain-security-cd application complies to the version run on the consumer chain + +## 2. Export the CCV data +Export the CCV data from the provider chain as descibed in the [Onboarding](./onboarding.md) and [Changeover](./changeover-procedure.md)) your following. +As a result the CCV data will be stored in a file in JSON format. + +## 3. Transform CCV data +To transform the CCV data to the newer format run the following command. +``` +interchain-security-cd genesis transform [genesis-file] +``` +where 'genesis-file' is the path to the file containing the CCV data exported in [step 2](#2-export-the-ccv-data). +As a result the CCV data in the new format will be written to standard output. + +Use the new CCV data as described in the procedure you're following. \ No newline at end of file diff --git a/docs/docs/consumer-development/onboarding.md b/docs/docs/consumer-development/onboarding.md index c9b503ed66..893af0a3b1 100644 --- a/docs/docs/consumer-development/onboarding.md +++ b/docs/docs/consumer-development/onboarding.md @@ -21,7 +21,7 @@ To help validators and other node runners onboard onto your chain, please prepar This should include (at minimum): - [ ] genesis.json without CCV data (before the proposal passes) -- [ ] genesis.json with CCV data (after spawn time passes) +- [ ] genesis.json with CCV data (after spawn time passes). Check if CCV data needs to be transformed (see [Transform Consumer Genesis](./consumer-genesis-transformation.md)) - [ ] information about relevant seed/peer nodes you are running - [ ] relayer information (compatible versions) - [ ] copy of your governance proposal (as JSON) diff --git a/docs/docs/features/proposals.md b/docs/docs/features/proposals.md index de4f2dc421..70077944ea 100644 --- a/docs/docs/features/proposals.md +++ b/docs/docs/features/proposals.md @@ -74,37 +74,6 @@ Minimal example: } ``` -## `EquivocationProposal` -:::tip -`EquivocationProposal` will only be accepted on the provider chain if at least one of the consumer chains submits equivocation evidence to the provider. -Sending equivocation evidence to the provider is handled automatically by the interchain security protocol when an equivocation infraction is detected on the consumer chain. -::: - -Proposal type used to suggest slashing a validator for double signing on consumer chain. -When proposals of this type are passed, the validator in question will be slashed for equivocation on the provider chain. - -:::warning -Take note that an equivocation slash causes a validator to be tombstoned (can never re-enter the active set). -Tombstoning a validator on the provider chain will remove the validator from the validator set of all consumer chains. -::: - -Minimal example: -```js -{ - "title": "Validator-1 double signed on consumerchain-1", - "description": "Here is more information about the infraction so you can verify it yourself", - // the list of equivocations that will be processed - "equivocations": [ - { - "height": 14444680, - "time": "2023-02-28T20:40:00.000000Z", - "power": 5500000, - "consensus_address": "" - } - ] -} -``` - ## ChangeRewardDenomProposal :::tip `ChangeRewardDenomProposal` will only be accepted on the provider chain if at least one of the denomsToAdd or denomsToRemove fields is populated with at least one denom. Also, a denom cannot be repeated in both sets. @@ -121,30 +90,3 @@ Minimal example: "denomsToRemove": [] } ``` - -### Notes -When submitting equivocation evidence through an `EquivocationProposal` please take note that you need to use the consensus address (`valcons`) of the offending validator on the **provider chain**. -Besides that, the `height` and the `time` fields should be mapped to the **provider chain** to avoid your evidence being rejected. - -Before submitting the proposal please check that the evidence is not outdated by comparing the infraction height with the `max_age_duration` and `max_age_num_blocks` consensus parameters of the **provider chain**. - -### Gaia example: -``` -➜ ~ cat genesis.json | jq ".consensus_params" -{ - "block": { - ... - }, - "evidence": { - "max_age_duration": "172800000000000", - "max_age_num_blocks": "1000000", - "max_bytes": "50000" - }, - "validator": { - ... - }, - "version": {} -} -``` - -Any `EquivocationProposal` transactions that submit evidence with `height` older than `max_age_num_blocks` and `time` older than `max_age_duration` will be considered invalid. diff --git a/docs/docs/features/slashing.md b/docs/docs/features/slashing.md index 4c74153b15..cdf166da8c 100644 --- a/docs/docs/features/slashing.md +++ b/docs/docs/features/slashing.md @@ -20,17 +20,10 @@ Instead of slashing, the provider will only jail offending validator for the dur Slash throttling (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. ::: -## Double-signing (equivocation) -infractions are not acted upon immediately. +# Cryptographic verification of equivocation and slashing +The Cryptographic verification of equivocation allows external agents to submit evidences of light client and double signing attacks observed on a consumer chain. When valid evidence is received, the malicious validators will be slashed, jailed, and tombstoned on the provider. -Upon receiving double signing evidence, the provider chain will take note of the evidence and allow for `EquivocationProposal` to be submitted to slash the offending validator. -Any `EquivocationProposal`s to slash a validator that has not double signed on any of the consumer chains will be automatically rejected by the provider chain. +The feature is outlined in [ADR-005](../adrs/adr-005-cryptographic-equivocation-verification.md) and [ADR-013](../adrs/adr-013-equivocation-slashing.md). -:::info -The offending validator will only be slashed (and tombstoned) if an `EquivocationProposal` is accepted and passed through governance. - -The offending validator will effectively get slashed and tombstoned on all consumer chains. -::: - - -You can find instructions on creating `EquivocationProposal`s [here](./proposals#equivocationproposal). +By sending a `MsgSubmitConsumerMisbehaviour` or a `MsgSubmitConsumerDoubleVoting` transaction, the provider will + verify the reported equivocation and, if successful, slash, jail, and tombstone the malicious validator. \ No newline at end of file diff --git a/docs/docs/introduction/overview.md b/docs/docs/introduction/overview.md index f61fe4d209..aba31751e1 100644 --- a/docs/docs/introduction/overview.md +++ b/docs/docs/introduction/overview.md @@ -30,10 +30,6 @@ To ensure the security of the consumer chain, provider delegators cannot unbond If downtime is initiated by a validator on a consumer chain, a downtime packet will be relayed to the provider to jail that validator for a set amount of time. The validator who committed downtime will then miss out on staking rewards for the configured jailing period. -### Equivocation (Double Sign) Slashing - -Evidence of equivocation must be submitted to provider governance and be voted on. This behavior is an extra safeguard before a validator is slashed, and may be replaced by a more automated system in the future. - ### Tokenomics and Rewards Consumer chains are free to create their own native token which can be used for fees, and can be created on the consumer chain in the form of inflationary rewards. These rewards can be used to incentivize user behavior, for example, LPing or staking. A portion of these fees and rewards will be sent to provider chain stakers, but that proportion is completely customizable by the developers, and subject to governance. diff --git a/docs/docs/introduction/params.md b/docs/docs/introduction/params.md index 9f68cc706c..9b89a1d038 100644 --- a/docs/docs/introduction/params.md +++ b/docs/docs/introduction/params.md @@ -14,10 +14,10 @@ The parameters necessary for Interchain Security (ICS) are defined in ICS relies on the following time-based parameters. ### ProviderUnbondingPeriod -is the unbonding period on the provider chain as configured during chain genesis. This parameter can later be changed via governance. +`ProviderUnbondingPeriod` is the unbonding period on the provider chain as configured during chain genesis. This parameter can later be changed via governance. ### ConsumerUnbondingPeriod -is the unbonding period on the consumer chain. +`ConsumerUnbondingPeriod` is the unbonding period on the consumer chain. :::info `ConsumerUnbondingPeriod` is set via the `ConsumerAdditionProposal` governance proposal to add a new consumer chain. @@ -34,7 +34,7 @@ Unbonding operations (such as undelegations) are completed on the provider only ### TrustingPeriodFraction -is used to calculate the `TrustingPeriod` of created IBC clients on both provider and consumer chains. +`TrustingPeriodFraction` is used to calculate the `TrustingPeriod` of created IBC clients on both provider and consumer chains. Setting `TrustingPeriodFraction` to `0.5` would result in the following: @@ -49,7 +49,7 @@ Note that a light clients must be updated within the `TrustingPeriod` in order t For more details, see the [IBC specification of Tendermint clients](https://github.com/cosmos/ibc/blob/main/spec/client/ics-007-tendermint-client/README.md). ### CCVTimeoutPeriod -is the period used to compute the timeout timestamp when sending IBC packets. +`CCVTimeoutPeriod` is the period used to compute the timeout timestamp when sending IBC packets. For more details, see the [IBC specification of Channel & Packet Semantics](https://github.com/cosmos/ibc/blob/main/spec/core/ics-004-channel-and-packet-semantics/README.md#sending-packets). @@ -62,14 +62,14 @@ CCVTimeoutPeriod may have different values on the provider and consumer chains. - `CCVTimeoutPeriod` on the consumer is initial set via the `ConsumerAdditionProposal` ### InitTimeoutPeriod -is the maximum allowed duration for CCV channel initialization to execute. +`InitTimeoutPeriod` is the maximum allowed duration for CCV channel initialization to execute. For any consumer chain, if the CCV channel is not established within `InitTimeoutPeriod` then the consumer chain will be removed and therefore will not be secured by the provider chain. The countdown starts when the `spawn_time` specified in the `ConsumerAdditionProposal` is reached. -### `VscTimeoutPeriod` -is the provider-side param that enables the provider to timeout VSC packets even when a consumer chain is not live. +### VscTimeoutPeriod +`VscTimeoutPeriod` is the provider-side param that enables the provider to timeout VSC packets even when a consumer chain is not live. If the `VscTimeoutPeriod` is ever reached for a consumer chain that chain will be considered not live and removed from interchain security. :::tip @@ -77,10 +77,10 @@ If the `VscTimeoutPeriod` is ever reached for a consumer chain that chain will b ::: ### BlocksPerDistributionTransmission -is the number of blocks between rewards transfers from the consumer to the provider. +`BlocksPerDistributionTransmission` is the number of blocks between rewards transfers from the consumer to the provider. ### TransferPeriodTimeout -is the period used to compute the timeout timestamp when sending IBC transfer packets from a consumer to the provider. +`TransferPeriodTimeout` is the period used to compute the timeout timestamp when sending IBC transfer packets from a consumer to the provider. If this timeout expires, then the transfer is attempted again after `BlocksPerDistributionTransmission` blocks. - `TransferPeriodTimeout` on the consumer is initial set via the `ConsumerAdditionProposal` gov proposal to add the consumer @@ -90,16 +90,26 @@ If this timeout expires, then the transfer is attempted again after `BlocksPerDi ## Slash Throttle Parameters ### SlashMeterReplenishPeriod -exists on the provider such that once the slash meter becomes not-full, the slash meter is replenished after this period has elapsed. +`SlashMeterReplenishPeriod` exists on the provider such that once the slash meter becomes not-full, the slash meter is replenished after this period has elapsed. The meter is replenished to an amount equal to the slash meter allowance for that block, or `SlashMeterReplenishFraction * CurrentTotalVotingPower`. ### SlashMeterReplenishFraction -exists on the provider as the portion (in range [0, 1]) of total voting power that is replenished to the slash meter when a replenishment occurs. +`SlashMeterReplenishFraction` exists on the provider as the portion (in range [0, 1]) of total voting power that is replenished to the slash meter when a replenishment occurs. This param also serves as a maximum fraction of total voting power that the slash meter can hold. The param is set/persisted as a string, and converted to a `sdk.Dec` when used. ### MaxThrottledPackets -exists on the provider as the maximum amount of throttled slash or vsc matured packets that can be queued from a single consumer before the provider chain halts, it should be set to a large value. + +`MaxThrottledPackets` exists on the provider as the maximum amount of throttled slash or vsc matured packets that can be queued from a single consumer before the provider chain halts, it should be set to a large value. This param would allow provider binaries to panic deterministically in the event that packet throttling results in a large amount of state-bloat. In such a scenario, packet throttling could prevent a violation of safety caused by a malicious consumer, at the cost of provider liveness. + +:::info +`MaxThrottledPackets` was deprecated in ICS versions >= v3.2.0 due to the implementation of [ADR-008](../adrs/adr-008-throttle-retries.md). +::: + +### RetryDelayPeriod + +`RetryDelayPeriod` exists on the consumer for **ICS versions >= v3.2.0** (introduced by the implementation of [ADR-008](../adrs/adr-008-throttle-retries.md)) and is the period at which the consumer retries to send a `SlashPacket` that was rejected by the provider. + diff --git a/docs/docs/validators/overview.md b/docs/docs/validators/overview.md index 35ce56cdb3..4d764703be 100644 --- a/docs/docs/validators/overview.md +++ b/docs/docs/validators/overview.md @@ -91,7 +91,7 @@ More information is available in [Downtime Slashing documentation](../features/s ::: ## Double-signing Infractions -To learn more about equivocation handling in replicated security check out the [Slashing](../features/slashing.md#double-signing-equivocation) and [EquivocationProposal](../features/proposals.md#equivocationproposal) documentation sections +To learn more about equivocation handling in replicated security check out the [Slashing](../features/slashing.md) documentation section. ## Key assignment Validators can use different consensus keys on the provider and each of the consumer chains. The consumer chain consensus key must be registered on the provider before use. diff --git a/docs/package-lock.json b/docs/package-lock.json index aaeed671cd..1e1cb22f1b 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -16,7 +16,7 @@ "@you54f/theme-github-codeblock": "^0.1.1", "autoprefixer": "^10.4.13", "clsx": "^1.2.1", - "postcss": "^8.4.21", + "postcss": "^8.4.31", "postcss-import": "^15.1.0", "prism-react-renderer": "^1.3.5", "react": "^17.0.2", @@ -204,16 +204,81 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/compat-data": { "version": "7.21.0", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz", @@ -260,11 +325,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.21.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz", - "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dependencies": { - "@babel/types": "^7.21.0", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -396,9 +461,9 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "engines": { "node": ">=6.9.0" } @@ -415,23 +480,23 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -552,28 +617,28 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "engines": { "node": ">=6.9.0" } @@ -614,12 +679,12 @@ } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -691,9 +756,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", - "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "bin": { "parser": "bin/babel-parser.js" }, @@ -1938,31 +2003,31 @@ } }, "node_modules/@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz", - "integrity": "sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==", - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.21.1", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.2", - "@babel/types": "^7.21.2", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1971,12 +2036,12 @@ } }, "node_modules/@babel/types": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz", - "integrity": "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -8085,9 +8150,15 @@ } }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -8657,9 +8728,9 @@ } }, "node_modules/postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "funding": [ { "type": "opencollective", @@ -8668,10 +8739,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -12935,11 +13010,63 @@ } }, "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "requires": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } } }, "@babel/compat-data": { @@ -12977,11 +13104,11 @@ } }, "@babel/generator": { - "version": "7.21.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz", - "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "requires": { - "@babel/types": "^7.21.0", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -13080,9 +13207,9 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==" + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==" }, "@babel/helper-explode-assignable-expression": { "version": "7.18.6", @@ -13093,20 +13220,20 @@ } }, "@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "requires": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-member-expression-to-functions": { @@ -13194,22 +13321,22 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==" }, "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" }, "@babel/helper-validator-option": { "version": "7.21.0", @@ -13238,12 +13365,12 @@ } }, "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "dependencies": { @@ -13299,9 +13426,9 @@ } }, "@babel/parser": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", - "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==" + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==" }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.18.6", @@ -14106,39 +14233,39 @@ } }, "@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" } }, "@babel/traverse": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz", - "integrity": "sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==", - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.21.1", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.2", - "@babel/types": "^7.21.2", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "requires": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz", - "integrity": "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, @@ -18630,9 +18757,9 @@ } }, "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" }, "negotiator": { "version": "0.6.3", @@ -19035,11 +19162,11 @@ } }, "postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "requires": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } diff --git a/docs/package.json b/docs/package.json index a2b516536d..0df776c7d6 100644 --- a/docs/package.json +++ b/docs/package.json @@ -22,7 +22,7 @@ "@you54f/theme-github-codeblock": "^0.1.1", "autoprefixer": "^10.4.13", "clsx": "^1.2.1", - "postcss": "^8.4.21", + "postcss": "^8.4.31", "postcss-import": "^15.1.0", "prism-react-renderer": "^1.3.5", "react": "^17.0.2", diff --git a/go.mod b/go.mod index 8483e0a097..6381587dc8 100644 --- a/go.mod +++ b/go.mod @@ -4,12 +4,12 @@ go 1.20 require ( cosmossdk.io/errors v1.0.0 - cosmossdk.io/math v1.1.2 + cosmossdk.io/math v1.2.0 github.com/cometbft/cometbft v0.37.2 github.com/cometbft/cometbft-db v0.8.0 github.com/cosmos/cosmos-sdk v0.47.5 github.com/cosmos/gogoproto v1.4.10 - github.com/cosmos/ibc-go/v7 v7.3.0 + github.com/cosmos/ibc-go/v7 v7.3.1 github.com/cosmos/ics23/go v0.10.0 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 @@ -19,22 +19,22 @@ require ( github.com/oxyno-zeta/gomock-extra-matcher v1.2.0 github.com/rakyll/statik v0.1.7 // indirect github.com/spf13/cast v1.5.1 - github.com/spf13/cobra v1.7.0 + github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.8.4 github.com/tidwall/gjson v1.17.0 - golang.org/x/crypto v0.11.0 // indirect - golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb - golang.org/x/net v0.12.0 // indirect - golang.org/x/sys v0.11.0 // indirect - google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect - google.golang.org/grpc v1.58.2 + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/grpc v1.59.0 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v2 v2.4.0 ) require ( - cloud.google.com/go v0.110.4 // indirect - cloud.google.com/go/compute v1.21.0 // indirect + cloud.google.com/go v0.110.7 // indirect + cloud.google.com/go/compute v1.23.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.1 // indirect cloud.google.com/go/storage v1.30.1 // indirect @@ -57,7 +57,7 @@ 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 v0.7.9 // 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.2 @@ -84,13 +84,13 @@ require ( github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.1.0 // indirect + github.com/golang/glog v1.1.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect - github.com/google/go-cmp v0.5.9 + github.com/google/go-cmp v0.6.0 github.com/google/orderedcode v0.0.1 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/uuid v1.3.1 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.11.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect @@ -152,9 +152,9 @@ require ( github.com/zondax/ledger-go v0.14.1 // indirect go.etcd.io/bbolt v1.3.7 // indirect go.opencensus.io v0.24.0 // indirect - golang.org/x/oauth2 v0.10.0 // indirect - golang.org/x/term v0.10.0 // indirect - golang.org/x/text v0.12.0 // indirect + golang.org/x/oauth2 v0.11.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.126.0 // indirect google.golang.org/appengine v1.6.7 // indirect @@ -167,7 +167,7 @@ require ( require ( github.com/spf13/viper v1.16.0 - google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 + google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d ) require ( @@ -184,7 +184,7 @@ require ( github.com/rs/zerolog v1.30.0 // indirect go.uber.org/mock v0.2.0 // indirect golang.org/x/sync v0.3.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect ) // following versions might cause unexpected behavior diff --git a/go.sum b/go.sum index b062a13dc2..9619db64ae 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,12 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= 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= -cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= @@ -34,8 +32,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9 cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.110.4 h1:1JYyxKMN9hd5dR2MYTPWkGUgcoxVVhg0LKNKEo0qvmk= -cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= +cloud.google.com/go v0.110.7 h1:rJyC7nWRg2jWGZ4wSJ5nY65GTdYJkg0cd/uXb+ACI6o= +cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= @@ -59,7 +57,6 @@ cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUM cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= -cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= @@ -73,8 +70,8 @@ cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= -cloud.google.com/go/compute v1.21.0 h1:JNBsyXVoOoNJtTQcnEY5uYpZIbeCTYIeDe0Xh1bySMk= -cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= +cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= @@ -190,7 +187,6 @@ 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= -collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= 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= @@ -201,31 +197,23 @@ cosmossdk.io/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04= cosmossdk.io/errors v1.0.0/go.mod h1:+hJZLuhdDE0pYN8HkOrVNwrIOYvUGnn6+4fjnJs/oV0= cosmossdk.io/log v1.2.1 h1:Xc1GgTCicniwmMiKwDxUjO4eLhPxoVdI9vtMW8Ti/uk= cosmossdk.io/log v1.2.1/go.mod h1:GNSCc/6+DhFIj1aLn/j7Id7PaO8DzNylUZoOYBL9+I4= -cosmossdk.io/math v1.1.2 h1:ORZetZCTyWkI5GlZ6CZS28fMHi83ZYf+A2vVnHNzZBM= -cosmossdk.io/math v1.1.2/go.mod h1:l2Gnda87F0su8a/7FEKJfFdJrM0JZRXQaohlgJeyQh0= +cosmossdk.io/math v1.2.0 h1:8gudhTkkD3NxOP2YyyJIYYmt6dQ55ZfJkDOaxXpy7Ig= +cosmossdk.io/math v1.2.0/go.mod h1:l2Gnda87F0su8a/7FEKJfFdJrM0JZRXQaohlgJeyQh0= cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw= cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= -git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3/go.mod h1:wMEGFFFNuPos7vHmWXfszqImLppbc0wEhh6JBfJIUgw= -git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9/go.mod h1:BVJwbDfVjCjoFiKrhkei6NdGcZYpkDkdyCdg1ukytRA= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= 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/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= -github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= 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 v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.5.0/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/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= @@ -233,24 +221,16 @@ 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= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= -github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= 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= @@ -266,15 +246,6 @@ github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX 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-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= -github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= -github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= -github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= -github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= -github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= -github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= 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= @@ -284,35 +255,11 @@ 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/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= -github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= -github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.21.0-beta.0.20201114000516-e9c7a5ac6401/go.mod h1:Sv4JPQ3/M+teHz9Bo5jBpkNcP0x6r7rdihlNL/7tTAs= -github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= -github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= 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/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= 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/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= -github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= -github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= -github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= -github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= 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= @@ -320,7 +267,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/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= 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= @@ -340,7 +286,6 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -360,19 +305,14 @@ github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9D github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/coinbase/kryptology v1.8.0/go.mod h1:RYXOAPdzOGUe3qlSFkMGn58i3xUA8hmxYHksuq+8ciI= -github.com/coinbase/rosetta-sdk-go v0.7.9 h1:lqllBjMnazTjIqYrOGv8h8jxjg9+hJazIGZr9ZvoCcA= -github.com/coinbase/rosetta-sdk-go v0.7.9/go.mod h1:0/knutI7XGVqXmmH4OQD8OckFrbQ8yMsUZTG7FXCR2M= +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.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc= github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs= github.com/cometbft/cometbft-db v0.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo= github.com/cometbft/cometbft-db v0.8.0/go.mod h1:6ASCP4pfhmrCBpfk01/9E1SI29nD3HfVHrY4PG8x5c0= 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/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= -github.com/consensys/bavard v0.1.8-0.20210915155054-088da2f7f54a/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= -github.com/consensys/gnark-crypto v0.5.3/go.mod h1:hOdPlWQV1gDLp7faZVeg8Y0iEPFaOUnCc4XeCCk96p0= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= 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= @@ -396,8 +336,8 @@ github.com/cosmos/gogoproto v1.4.10 h1:QH/yT8X+c0F4ZDacDv3z+xE3WU1P1Z3wQoLMBRJoK github.com/cosmos/gogoproto v1.4.10/go.mod h1:3aAZzeRWpAwr+SS/LLkICX2/kDFyaYVzckBDzygIxek= github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38= github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A= -github.com/cosmos/ibc-go/v7 v7.3.0 h1:QtGeVMi/3JeLWuvEuC60sBHpAF40Oenx/y+bP8+wRRw= -github.com/cosmos/ibc-go/v7 v7.3.0/go.mod h1:mUmaHFXpXrEdcxfdXyau+utZf14pGKVUiXwYftRZZfQ= +github.com/cosmos/ibc-go/v7 v7.3.1 h1:bil1IjnHdyWDASFYKfwdRiNtFP6WK3osW7QFEAgU4I8= +github.com/cosmos/ibc-go/v7 v7.3.1/go.mod h1:wvx4pPBofe5ZdMNV3OFRxSI4auEP5Qfqf8JXLLNV04g= 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.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKyF3nNqAXZA= @@ -406,50 +346,32 @@ github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzU github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= 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.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +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/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= 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/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= -github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= 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.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= 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/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= -github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= 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/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= 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= -github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= -github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= @@ -459,7 +381,6 @@ github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= 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/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= 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= @@ -472,14 +393,10 @@ 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/ethereum/go-ethereum v1.10.17/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= @@ -488,9 +405,6 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo 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/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= -github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= 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/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -498,9 +412,6 @@ 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= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= -github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= -github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= -github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -517,9 +428,6 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= @@ -527,9 +435,7 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+ github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= @@ -541,7 +447,6 @@ github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= @@ -552,12 +457,9 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= -github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -598,12 +500,10 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 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.11.0/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= @@ -618,11 +518,11 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -651,11 +551,10 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= @@ -684,10 +583,8 @@ github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= 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.4.2/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/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= 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= @@ -706,7 +603,6 @@ github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIv 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= -github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= @@ -744,16 +640,12 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= -github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= 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/huin/goupnp v1.0.3-0.20220313090229-ca81a64b4204/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= 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= @@ -761,22 +653,7 @@ github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPt github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= -github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= -github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= -github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= -github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= -github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= -github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= -github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= -github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= -github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= 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= @@ -787,7 +664,6 @@ github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -796,34 +672,24 @@ github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= -github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 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.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= -github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= 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.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -832,12 +698,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= @@ -846,39 +708,25 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8= github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= -github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= 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/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= -github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -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.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= 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 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= 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= @@ -899,27 +747,20 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= -github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= -github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= -github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= @@ -927,21 +768,17 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/neilotoole/errgroup v0.1.6/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= 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/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= 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= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= 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= @@ -953,7 +790,6 @@ github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= @@ -966,18 +802,14 @@ github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIw github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= 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/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= -github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= 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/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= 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= @@ -988,7 +820,6 @@ 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/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= 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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -1008,10 +839,8 @@ github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T 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/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= 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.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= 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= @@ -1026,14 +855,11 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O 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/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= 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= -github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= -github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= 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= @@ -1054,11 +880,6 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0 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= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= -github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -1080,8 +901,8 @@ github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= 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.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +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= @@ -1092,7 +913,6 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An 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/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= 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= @@ -1101,7 +921,6 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -1122,22 +941,14 @@ github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2l 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/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM= github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM= -github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= -github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= 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= @@ -1148,17 +959,8 @@ 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= 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/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= 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= @@ -1194,39 +996,26 @@ 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/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 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-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 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= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/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-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/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-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= -golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/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= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= @@ -1239,7 +1028,6 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk 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/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= 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= @@ -1268,7 +1056,7 @@ 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.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU= -golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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= @@ -1306,19 +1094,16 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 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-20210220033124-5f55cee0dc0d/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= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/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= @@ -1334,8 +1119,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.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= 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= @@ -1361,8 +1146,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= -golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU= +golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1390,7 +1175,6 @@ golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5h 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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1400,7 +1184,6 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w 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-20190813064441-fde4db37ae7a/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= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1411,7 +1194,6 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1431,23 +1213,18 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-20210124154548-22da62e12c0c/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-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/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= @@ -1458,7 +1235,6 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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= @@ -1487,14 +1263,13 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc 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.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= 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= @@ -1506,21 +1281,17 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1545,7 +1316,6 @@ golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1581,6 +1351,7 @@ 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.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 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= @@ -1590,12 +1361,6 @@ golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNq golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= -gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1663,7 +1428,6 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -1671,7 +1435,6 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= @@ -1766,12 +1529,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-20230711160842-782d3b101e98 h1:Z0hjGZePRE0ZBWotvtrwxFNrNE9CUAGtplaDK5NNI/g= -google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0= -google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw= -google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= 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= @@ -1813,8 +1576,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.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= -google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= 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= @@ -1839,7 +1602,6 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= @@ -1847,12 +1609,9 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1869,7 +1628,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C 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 v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1879,16 +1637,13 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/proto/interchain_security/ccv/consumer/v1/consumer.proto b/proto/interchain_security/ccv/consumer/v1/consumer.proto index 39d6eb29de..b386bc2e9a 100644 --- a/proto/interchain_security/ccv/consumer/v1/consumer.proto +++ b/proto/interchain_security/ccv/consumer/v1/consumer.proto @@ -1,27 +1,24 @@ syntax = "proto3"; package interchain_security.ccv.consumer.v1; -import "interchain_security/ccv/v1/wire.proto"; - option go_package = "github.com/cosmos/interchain-security/v3/x/ccv/consumer/types"; import "google/protobuf/any.proto"; import "gogoproto/gogo.proto"; import "cosmos_proto/cosmos.proto"; -import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; // -// Note any type defined in this file is ONLY used internally to the consumer CCV module. -// These schemas can change with proper consideration of compatibility or migration. -// +// Note any type defined in this file is ONLY used internally to the consumer +// CCV module. These schemas can change with proper consideration of +// compatibility or migration. -// CrossChainValidator defines the type used to store validator information internal -// to the consumer CCV module. Note one cross chain validator entry is persisted for -// each consumer validator, where incoming VSC packets update this data, which is eventually -// forwarded to comet for consumer chain consensus. +// CrossChainValidator defines the type used to store validator information +// internal to the consumer CCV module. Note one cross chain validator entry is +// persisted for each consumer validator, where incoming VSC packets update this +// data, which is eventually forwarded to comet for consumer chain consensus. // -// Note this type is only used internally to the consumer CCV module. +// Note this type is only used internally to the consumer CCV module. message CrossChainValidator { bytes address = 1; int64 power = 2; @@ -34,8 +31,8 @@ message CrossChainValidator { // A record storing the state of a slash packet sent to the provider chain // which may bounce back and forth until handled by the provider. -// -// Note this type is only used internally to the consumer CCV module. +// +// Note this type is only used internally to the consumer CCV module. message SlashRecord { bool waiting_on_reply = 1; google.protobuf.Timestamp send_time = 2 diff --git a/proto/interchain_security/ccv/consumer/v1/genesis.proto b/proto/interchain_security/ccv/consumer/v1/genesis.proto new file mode 100644 index 0000000000..bb33f34501 --- /dev/null +++ b/proto/interchain_security/ccv/consumer/v1/genesis.proto @@ -0,0 +1,92 @@ +syntax = "proto3"; + +package interchain_security.ccv.consumer.v1; + +option go_package = "github.com/cosmos/interchain-security/v3/x/ccv/consumer/types"; + +import "interchain_security/ccv/v1/shared_consumer.proto"; +import "ibc/lightclients/tendermint/v1/tendermint.proto"; + +import "gogoproto/gogo.proto"; +import "interchain_security/ccv/v1/wire.proto"; +import "google/protobuf/timestamp.proto"; +import "tendermint/abci/types.proto"; + + + + +// GenesisState defines the CCV consumer genesis state +// +// Note: this type is only used on consumer side and references shared types with +// provider +message GenesisState { + // ConsumerParams is a shared type with provider module + interchain_security.ccv.v1.ConsumerParams params = 1 + [ (gogoproto.nullable) = false ]; + // Client ID of the provider. Empty for a new chain, filled in on restart. + string provider_client_id = 2; + // Channel ID of the provider. Empty for a new chain, filled in on restart. + string provider_channel_id = 3; + // true for new chain, false for chain restart. + bool new_chain = 4; + // !!! DEPRECATED !!! ProviderClientState is deprecated. Use provider.client_state instead + ibc.lightclients.tendermint.v1.ClientState provider_client_state = 5 [ deprecated = true]; + // !!! DEPRECATED !!! ProviderConsensusState is deprecated. Use provider.consensus_state instead + ibc.lightclients.tendermint.v1.ConsensusState provider_consensus_state = 6 [ deprecated = true]; + // MaturingPackets nil on new chain, filled in on restart. + repeated MaturingVSCPacket maturing_packets = 7 + [ (gogoproto.nullable) = false ]; + // !!! DEPRECATED !!!! InitialValset is deprecated. Use provider.initial_val_set instead + repeated .tendermint.abci.ValidatorUpdate initial_val_set = 8 [ (gogoproto.nullable) = false, deprecated = true ]; + // HeightToValsetUpdateId nil on new chain, filled in on restart. + repeated HeightToValsetUpdateID height_to_valset_update_id = 9 + [ (gogoproto.nullable) = false ]; + // OutstandingDowntimes nil on new chain, filled in on restart. + repeated OutstandingDowntime outstanding_downtime_slashing = 10 + [ (gogoproto.nullable) = false ]; + // PendingConsumerPackets nil on new chain, filled in on restart. + ConsumerPacketDataList pending_consumer_packets = 11 + [ (gogoproto.nullable) = false ]; + // LastTransmissionBlockHeight nil on new chain, filled in on restart. + LastTransmissionBlockHeight last_transmission_block_height = 12 + [ (gogoproto.nullable) = false ]; + // flag indicating whether the consumer CCV module starts in pre-CCV state + bool preCCV = 13; + interchain_security.ccv.v1.ProviderInfo provider = 14 + [ (gogoproto.nullable) = false ]; +} + +// HeightValsetUpdateID represents a mapping internal to the consumer CCV module +// which links a block height to each recv valset update id. +message HeightToValsetUpdateID { + uint64 height = 1; + uint64 valset_update_id = 2; +} + +// OutstandingDowntime defines the type used internally to the consumer CCV +// module and is used in order to not send multiple slashing requests for +// the same downtime infraction. +message OutstandingDowntime { string validator_consensus_address = 1; } + +// LastTransmissionBlockHeight is the last time validator holding +// pools were transmitted to the provider chain. This type is used internally +// to the consumer CCV modul. +message LastTransmissionBlockHeight { int64 height = 1; } + +// MaturingVSCPacket represents a vsc packet that is maturing internal to the +// consumer CCV module, where the consumer has not yet relayed a VSCMatured +// packet back to the provider. +message MaturingVSCPacket { + uint64 vscId = 1; + google.protobuf.Timestamp maturity_time = 2 + [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; +} + +// ConsumerPacketDataList is a list of consumer packet data packets. +// +// Note this type is used internally to the consumer CCV module +// for exporting / importing state in InitGenesis and ExportGenesis. +message ConsumerPacketDataList { + repeated interchain_security.ccv.v1.ConsumerPacketData list = 1 + [ (gogoproto.nullable) = false ]; +} diff --git a/proto/interchain_security/ccv/consumer/v1/query.proto b/proto/interchain_security/ccv/consumer/v1/query.proto index b21e07341a..3c56aed7ea 100644 --- a/proto/interchain_security/ccv/consumer/v1/query.proto +++ b/proto/interchain_security/ccv/consumer/v1/query.proto @@ -7,6 +7,7 @@ option go_package = "github.com/cosmos/interchain-security/v3/x/ccv/consumer/typ import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; import "interchain_security/ccv/consumer/v1/consumer.proto"; +import "interchain_security/ccv/v1/wire.proto"; service Query { // ConsumerGenesis queries the genesis state needed to start a consumer chain @@ -24,6 +25,11 @@ service Query { rpc QueryProviderInfo(QueryProviderInfoRequest) returns (QueryProviderInfoResponse) { option (google.api.http).get = "/interchain_security/ccv/consumer/provider-info"; } + + // QueryThrottleState returns on-chain state relevant to throttled consumer packets + rpc QueryThrottleState(QueryThrottleStateRequest) returns (QueryThrottleStateResponse) { + option (google.api.http).get = "/interchain_security/ccv/consumer/throttle_state"; + } } // NextFeeDistributionEstimate holds information about next fee distribution @@ -65,6 +71,14 @@ message QueryProviderInfoResponse { ChainInfo provider = 2 [ (gogoproto.nullable) = false ]; } +message QueryThrottleStateRequest {} + +message QueryThrottleStateResponse { + SlashRecord slash_record = 1 [ (gogoproto.nullable) = true ]; + repeated interchain_security.ccv.v1.ConsumerPacketData packet_data_queue = 2 [ (gogoproto.nullable) = false ]; +} + + message ChainInfo { string chainID = 1; string clientID = 2; diff --git a/proto/interchain_security/ccv/provider/v1/genesis.proto b/proto/interchain_security/ccv/provider/v1/genesis.proto index 9cefe26ee0..2899c4e1f2 100644 --- a/proto/interchain_security/ccv/provider/v1/genesis.proto +++ b/proto/interchain_security/ccv/provider/v1/genesis.proto @@ -8,7 +8,6 @@ import "gogoproto/gogo.proto"; import "interchain_security/ccv/v1/shared_consumer.proto"; import "interchain_security/ccv/v1/wire.proto"; import "interchain_security/ccv/provider/v1/provider.proto"; -import "tendermint/crypto/keys.proto"; // GenesisState defines the CCV provider chain genesis state message GenesisState { diff --git a/proto/interchain_security/ccv/provider/v1/provider.proto b/proto/interchain_security/ccv/provider/v1/provider.proto index b0de16097b..f871a90e25 100644 --- a/proto/interchain_security/ccv/provider/v1/provider.proto +++ b/proto/interchain_security/ccv/provider/v1/provider.proto @@ -4,7 +4,6 @@ package interchain_security.ccv.provider.v1; option go_package = "github.com/cosmos/interchain-security/v3/x/ccv/provider/types"; -import "interchain_security/ccv/v1/shared_consumer.proto"; import "interchain_security/ccv/v1/wire.proto"; import "gogoproto/gogo.proto"; import "google/protobuf/timestamp.proto"; @@ -107,10 +106,13 @@ message ConsumerRemovalProposal { // punish a validator for equivocation on a consumer chain. // // This type is only used internally to the consumer CCV module. +// WARNING: This message is deprecated now that equivocations can be submitted +// and verified automatically on the provider. (see SubmitConsumerDoubleVoting in proto/interchain-security/ccv/provider/v1/tx.proto). message EquivocationProposal { + option deprecated = true; // the title of the proposal string title = 1; - // the description of the proposal +// the description of the proposal string description = 2; // the list of equivocations that will be processed repeated cosmos.evidence.v1beta1.Equivocation equivocations = 3; @@ -152,6 +154,10 @@ message GlobalSlashEntry { // Params defines the parameters for CCV Provider module message Params { + + // Reserve 8th slot for removed max throttled packet param + reserved 8; + ibc.lightclients.tendermint.v1.ClientState template_client = 1; // TrustingPeriodFraction is used to compute the consumer and provider IBC // client's TrustingPeriod from the chain defined UnbondingPeriod @@ -179,10 +185,6 @@ message Params { // total voting power that the slash meter can hold. string slash_meter_replenish_fraction = 7; - // The maximum amount of throttled slash or vsc matured packets - // that can be queued for a single consumer before the provider chain halts. - int64 max_throttled_packets = 8; - // The fee required to be paid to add a reward denom cosmos.base.v1beta1.Coin consumer_reward_denom_registration_fee = 9 [ (gogoproto.nullable) = false ]; @@ -209,6 +211,7 @@ message ConsumerRemovalProposals { // AddressList contains a list of consensus addresses message AddressList { repeated bytes addresses = 1; } +// ChannelToChain is used to map a CCV channel ID to the consumer chainID message ChannelToChain { string channel_id = 1; string chain_id = 2; diff --git a/proto/interchain_security/ccv/provider/v1/query.proto b/proto/interchain_security/ccv/provider/v1/query.proto index 6dfcdcb320..05071a354c 100644 --- a/proto/interchain_security/ccv/provider/v1/query.proto +++ b/proto/interchain_security/ccv/provider/v1/query.proto @@ -65,14 +65,6 @@ service Query { "/interchain_security/ccv/provider/throttle_state"; } - // QueryThrottledConsumerPacketData returns a list of pending packet data - // instances (slash packet and vsc matured) for a single consumer chain - rpc QueryThrottledConsumerPacketData(QueryThrottledConsumerPacketDataRequest) - returns (QueryThrottledConsumerPacketDataResponse) { - option (google.api.http).get = - "/interchain_security/ccv/provider/pending_consumer_packets"; - } - // QueryRegisteredConsumerRewardDenoms returns a list of consumer reward // denoms that are registered rpc QueryRegisteredConsumerRewardDenoms( @@ -81,6 +73,15 @@ service Query { option (google.api.http).get = "/interchain_security/ccv/provider/registered_consumer_reward_denoms"; } + + // QueryProposedConsumerChainIDs returns the chain IDs of the proposed consumer chain addition proposals + // that are still in the voting period + rpc QueryProposedConsumerChainIDs( + QueryProposedChainIDsRequest) + returns (QueryProposedChainIDsResponse) { + option (google.api.http).get = + "/interchain_security/ccv/provider/proposed_consumer_chains"; + } } message QueryConsumerGenesisRequest { string chain_id = 1; } @@ -151,39 +152,22 @@ message QueryThrottleStateResponse { // full google.protobuf.Timestamp next_replenish_candidate = 3 [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; - // data relevant to currently throttled slash packets - repeated ThrottledSlashPacket packets = 4; } -message QueryThrottledConsumerPacketDataRequest { string chain_id = 1; } +message QueryRegisteredConsumerRewardDenomsRequest {} -message QueryThrottledConsumerPacketDataResponse { - string chain_id = 1; - uint64 size = 2; - repeated ThrottledPacketDataWrapper packetDataInstances = 3 - [ (gogoproto.nullable) = false ]; +message QueryRegisteredConsumerRewardDenomsResponse { + repeated string denoms = 1; } -// A query wrapper type for the global entry and data relevant to a throttled -// slash packet. -message ThrottledSlashPacket { - interchain_security.ccv.provider.v1.GlobalSlashEntry global_entry = 1 - [ (gogoproto.nullable) = false ]; - interchain_security.ccv.v1.SlashPacketData data = 2 - [ (gogoproto.nullable) = false ]; -} +message QueryProposedChainIDsRequest {} -// ThrottledPacketDataWrapper contains either SlashPacketData or -// VSCMaturedPacketData -message ThrottledPacketDataWrapper { - oneof data { - interchain_security.ccv.v1.SlashPacketData slash_packet = 1; - interchain_security.ccv.v1.VSCMaturedPacketData vsc_matured_packet = 2; - } +message QueryProposedChainIDsResponse { + repeated ProposedChain proposedChains = 1 + [ (gogoproto.nullable) = false ]; } -message QueryRegisteredConsumerRewardDenomsRequest {} - -message QueryRegisteredConsumerRewardDenomsResponse { - repeated string denoms = 1; +message ProposedChain { + string chainID = 1; + uint64 proposalID = 2; } diff --git a/proto/interchain_security/ccv/provider/v1/tx.proto b/proto/interchain_security/ccv/provider/v1/tx.proto index 7d4cce685e..ada2bffde8 100644 --- a/proto/interchain_security/ccv/provider/v1/tx.proto +++ b/proto/interchain_security/ccv/provider/v1/tx.proto @@ -3,15 +3,18 @@ package interchain_security.ccv.provider.v1; option go_package = "github.com/cosmos/interchain-security/v3/x/ccv/provider/types"; -import "google/api/annotations.proto"; import "gogoproto/gogo.proto"; import "cosmos_proto/cosmos.proto"; import "google/protobuf/any.proto"; +import "ibc/lightclients/tendermint/v1/tendermint.proto"; +import "tendermint/types/evidence.proto"; + // Msg defines the Msg service. service Msg { - rpc AssignConsumerKey(MsgAssignConsumerKey) - returns (MsgAssignConsumerKeyResponse); + rpc AssignConsumerKey(MsgAssignConsumerKey) returns (MsgAssignConsumerKeyResponse); + rpc SubmitConsumerMisbehaviour(MsgSubmitConsumerMisbehaviour) returns (MsgSubmitConsumerMisbehaviourResponse); + rpc SubmitConsumerDoubleVoting(MsgSubmitConsumerDoubleVoting) returns (MsgSubmitConsumerDoubleVotingResponse); } message MsgAssignConsumerKey { @@ -28,3 +31,33 @@ message MsgAssignConsumerKey { } 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 (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + string submitter = 1; + // The Misbehaviour of the consumer chain wrapping + // two conflicting IBC headers + ibc.lightclients.tendermint.v1.Misbehaviour misbehaviour = 2; +} + +message MsgSubmitConsumerMisbehaviourResponse {} + + +// MsgSubmitConsumerDoubleVoting defines a message that reports +// a double signing infraction observed on a consumer chain +message MsgSubmitConsumerDoubleVoting { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + string submitter = 1; + // The equivocation of the consumer chain wrapping + // an evidence of a validator that signed two conflicting votes + tendermint.types.DuplicateVoteEvidence duplicate_vote_evidence = 2; + // The light client header of the infraction block + ibc.lightclients.tendermint.v1.Header infraction_block_header = 3; +} + +message MsgSubmitConsumerDoubleVotingResponse {} diff --git a/proto/interchain_security/ccv/v1/shared_consumer.proto b/proto/interchain_security/ccv/v1/shared_consumer.proto index 4a44548ea3..149e8630c5 100644 --- a/proto/interchain_security/ccv/v1/shared_consumer.proto +++ b/proto/interchain_security/ccv/v1/shared_consumer.proto @@ -6,27 +6,26 @@ option go_package = "github.com/cosmos/interchain-security/v3/x/ccv/types"; import "tendermint/abci/types.proto"; import "ibc/lightclients/tendermint/v1/tendermint.proto"; -import "ibc/core/channel/v1/channel.proto"; import "google/protobuf/duration.proto"; import "gogoproto/gogo.proto"; -import "interchain_security/ccv/v1/wire.proto"; -import "google/protobuf/timestamp.proto"; // -// Note any type defined in this file is referenced/persisted in both the consumer and provider CCV modules, -// but not sent over the wire. These schemas could change, only with careful consideration of effects! +// Note any type defined in this file is referenced/persisted in both the +// consumer and provider CCV modules, but not sent over the wire. These schemas +// could change, only with careful consideration of effects! // // ConsumerParams defines the parameters for CCV consumer module. -// +// // Note this type is referenced in both the consumer and provider CCV modules, -// and persisted on the provider, see MakeConsumerGenesis and SetConsumerGenesis. +// and persisted on the provider, see MakeConsumerGenesis and +// SetConsumerGenesis. // message ConsumerParams { // TODO: Remove enabled flag and find a better way to setup integration tests // See: https://github.com/cosmos/interchain-security/issues/339 bool enabled = 1; - + /////////////////////// // Distribution Params // Number of blocks between ibc-token-transfers from the consumer chain to @@ -34,7 +33,7 @@ message ConsumerParams { // the accumulated tokens are divided and sent consumer redistribution // address. int64 blocks_per_distribution_transmission = 2; - + // Channel, and provider-chain receiving address to send distribution token // transfers over. These parameters is auto-set during the consumer <-> // provider handshake procedure. @@ -43,111 +42,62 @@ message ConsumerParams { // Sent CCV related IBC packets will timeout after this duration google.protobuf.Duration ccv_timeout_period = 5 [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; - + // Sent transfer related IBC packets will timeout after this duration google.protobuf.Duration transfer_timeout_period = 6 [ (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 = 7; - + // 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 = 8; - + // Unbonding period for the consumer, // which should be smaller than that of the provider in general. 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; - + // Reward denoms. These are the denominations which are allowed to be sent to // the provider as rewards. repeated string reward_denoms = 11; - + // Provider-originated reward denoms. These are denoms coming from the // provider which are allowed to be used as rewards. e.g. "uatom" repeated string provider_reward_denoms = 12; -} -// ConsumerGenesisState defines the CCV consumer chain genesis state. -// -// Note this type is referenced in both the consumer and provider CCV modules, -// and persisted on the provider, see MakeConsumerGenesis and SetConsumerGenesis. -message ConsumerGenesisState { - ConsumerParams params = 1 [ (gogoproto.nullable) = false ]; - string provider_client_id = 2; // empty for a new chain, filled in on restart. - string provider_channel_id = - 3; // empty for a new chain, filled in on restart. - bool new_chain = - 4; // true for new chain, false for chain restart. - // ProviderClientState filled in on new chain, nil on restart. - ibc.lightclients.tendermint.v1.ClientState provider_client_state = 5; - // ProviderConsensusState filled in on new chain, nil on restart. - ibc.lightclients.tendermint.v1.ConsensusState provider_consensus_state = 6; - // MaturingPackets nil on new chain, filled in on restart. - repeated MaturingVSCPacket - maturing_packets = 7 [ (gogoproto.nullable) = false ]; - // InitialValset filled in on new chain and on restart. - repeated .tendermint.abci.ValidatorUpdate initial_val_set = 8 - [ (gogoproto.nullable) = false ]; - // HeightToValsetUpdateId nil on new chain, filled in on restart. - repeated HeightToValsetUpdateID height_to_valset_update_id = 9 - [ (gogoproto.nullable) = false ]; - // OutstandingDowntimes nil on new chain, filled in on restart. - repeated OutstandingDowntime outstanding_downtime_slashing = 10 - [ (gogoproto.nullable) = false ]; - // PendingConsumerPackets nil on new chain, filled in on restart. - ConsumerPacketDataList pending_consumer_packets = - 11 [ (gogoproto.nullable) = false ]; - // LastTransmissionBlockHeight nil on new chain, filled in on restart. - LastTransmissionBlockHeight - last_transmission_block_height = 12 [ (gogoproto.nullable) = false ]; - bool preCCV = 13; // flag indicating whether the consumer CCV module starts in - // pre-CCV state -} - -// HeightValsetUpdateID represents a mapping internal to the consumer CCV module -// AND used in shared consumer genesis state, which links a block height to each recv valset update id. -message HeightToValsetUpdateID { - uint64 height = 1; - uint64 valset_update_id = 2; + // The period after which a consumer can retry sending a throttled packet. + google.protobuf.Duration retry_delay_period = 13 + [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; } -// OutstandingDowntime defines the type used internally to the consumer CCV module, -// AND used in shared consumer genesis state, in order to not send multiple slashing -// requests for the same downtime infraction. -message OutstandingDowntime { string validator_consensus_address = 1; } - -// LastTransmissionBlockHeight is the last time validator holding -// pools were transmitted to the provider chain. This type is used internally -// to the consumer CCV module AND used in shared consumer genesis state. -message LastTransmissionBlockHeight { int64 height = 1; } - -// MaturingVSCPacket represents a vsc packet that is maturing internal to the -// consumer CCV module, where the consumer has not yet relayed a VSCMatured packet -// back to the provider. This type is used internally to the consumer CCV module -// AND used in shared consumer genesis state. -message MaturingVSCPacket { - uint64 vscId = 1; - google.protobuf.Timestamp maturity_time = 2 - [ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ]; +// ConsumerGenesisState defines shared genesis information between provider and +// consumer +message ConsumerGenesisState { + ConsumerParams params = 1 [ (gogoproto.nullable) = false ]; + ProviderInfo provider = 2 [ (gogoproto.nullable) = false ]; + // true for new chain, false for chain restart. + bool new_chain = 3; // TODO:Check if this is really needed } -// ConsumerPacketDataList is a list of consumer packet data packets. -// -// Note this type is is used internally to the consumer CCV module -// for exporting / importing state in InitGenesis and ExportGenesis, -// AND included in the consumer genesis type (reffed by provider and consumer modules), -// hence this is a shared type. -message ConsumerPacketDataList { - repeated interchain_security.ccv.v1.ConsumerPacketData list = 1 [ (gogoproto.nullable) = false ]; +// ProviderInfo defines all information a consumer needs from a provider +// Shared data type between provider and consumer +message ProviderInfo { + // ProviderClientState filled in on new chain, nil on restart. + ibc.lightclients.tendermint.v1.ClientState client_state = 1; + // ProviderConsensusState filled in on new chain, nil on restart. + ibc.lightclients.tendermint.v1.ConsensusState consensus_state = 2; + // InitialValset filled in on new chain and on restart. + repeated .tendermint.abci.ValidatorUpdate initial_val_set = 3 + [ (gogoproto.nullable) = false ]; } diff --git a/sonar-project.properties b/sonar-project.properties index 34d8d28397..d845247826 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -2,7 +2,7 @@ sonar.projectKey=cosmos_interchain-security sonar.organization=cosmos # This is the name and version displayed in the SonarCloud UI. -#sonar.projectName=interchain-security +sonar.projectName=Interchain Security #sonar.projectVersion=1.0 # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. @@ -14,10 +14,10 @@ sonar.organization=cosmos # All golang artifacts sonar.sources=. # Do not calculate coverage metrics for statements in these files -sonar.exclusions=**/vendor/**,**/*.pb.go,**/*.pb.gw.go,proto,**/*_test.go,tests/**,testutil/**,legacy_ibc_testing/**,docs/**,app/**,cmd/**, +sonar.exclusions=**/vendor/**,**/*.pb.go,**/*.pb.gw.go,proto,**/*_test.go,tests/**,testutil/**,docs/**,app/**,cmd/**, sonar.tests=. # Run unit and integration tests, but not E2E tests sonar.test.inclusions=**/*_test.go # Do not run any vendor tests sonar.test.exclusions=**/vendor/** -sonar.go.coverage.reportPaths=coverage.out +sonar.go.coverage.reportPaths=coverage.out,*profile.out diff --git a/tests/difference/core/driver/setup.go b/tests/difference/core/driver/setup.go index c1d1c272ff..cf9d5e470d 100644 --- a/tests/difference/core/driver/setup.go +++ b/tests/difference/core/driver/setup.go @@ -207,7 +207,7 @@ func (b *Builder) getAppBytesAndSenders( bondDenom := sdk.DefaultBondDenom genesisStaking := stakingtypes.GenesisState{} - genesisConsumer := ccv.ConsumerGenesisState{} + genesisConsumer := consumertypes.GenesisState{} if genesis[stakingtypes.ModuleName] != nil { // If staking module genesis already exists @@ -217,7 +217,7 @@ func (b *Builder) getAppBytesAndSenders( if genesis[consumertypes.ModuleName] != nil { app.AppCodec().MustUnmarshalJSON(genesis[consumertypes.ModuleName], &genesisConsumer) - genesisConsumer.InitialValSet = initValPowers + genesisConsumer.Provider.InitialValSet = initValPowers genesisConsumer.Params.Enabled = true genesis[consumertypes.ModuleName] = app.AppCodec().MustMarshalJSON(&genesisConsumer) } @@ -522,7 +522,7 @@ func (b *Builder) createConsumersLocalClientGenesis() *ibctmtypes.ClientState { ) } -func (b *Builder) createConsumerGenesis(client *ibctmtypes.ClientState) *ccv.ConsumerGenesisState { +func (b *Builder) createConsumerGenesis(client *ibctmtypes.ClientState) *consumertypes.GenesisState { providerConsState := b.provider().LastHeader.ConsensusState() valUpdates := tmtypes.TM2PB.ValidatorUpdates(b.provider().Vals) @@ -539,8 +539,9 @@ func (b *Builder) createConsumerGenesis(client *ibctmtypes.ClientState) *ccv.Con "0", // disable soft opt-out []string{}, []string{}, + ccv.DefaultRetryDelayPeriod, ) - return ccv.NewInitialConsumerGenesisState(client, providerConsState, valUpdates, params) + return consumertypes.NewInitialGenesisState(client, providerConsState, valUpdates, params) } // The state of the data returned is equivalent to the state of two chains diff --git a/tests/difference/core/quint_model/README.md b/tests/difference/core/quint_model/README.md new file mode 100644 index 0000000000..0cef3bc632 --- /dev/null +++ b/tests/difference/core/quint_model/README.md @@ -0,0 +1,72 @@ +This folder contains a Quint model for the core logic of Cross-Chain Validation (CCV). + +### File structure +The files are as follows: +- ccv.qnt: Contains the type definitions, data structures, functional logic for CCV. +The core of the protocol. +- ccv_model.qnt: Contains the stateful part of the model for CCV. Very roughly speaking, this could be seen as "e2e tests". +Also contains invariants. +- ccv_test.qnt: Contains unit tests for the functional layer of CCV. +- libraries/*: Libraries that don't belong to CCV, but are used by it. + +### Model details + +To see the data structures used in the model, see the `ProtocolState` type in ccv.qnt. + +The "public" endpoints of the model are those functions that take as an input the protocol state, and return a `Result`. +Other functions are for utility. + +The parameters of the protocol are defined as consts in [ccv.qnt](ccv.qnt). + +### Tests + +To run unit tests, run +``` +quint test ccv_test.qnt +``` +and +``` +quint test ccv_model.qnt +``` + +### Invariants + +The invariants to check are in [ccv_model.qnt](ccv_model.qnt). +Check a single invariant by running +`quint run --invariant INVARIANT_NAME ccv_model.qnt`, +or all invariants one after another with the help of the script `run_invariants.sh`. +Each invariant takes about a minute to run. + +Invariants are as follows: +- [X] ValidatorUpdatesArePropagatedInv: When a validator power update is comitted on chain, a packet containing that change in voting power is sent to all running consumers. +- [X] ValidatorSetHasExistedInv: Every validator set on consumer chains is/was a validator set on the provider. +- [X] SameVscPacketsInv: Ensure that consumer chains receive the same VscPackets in the same order. +Because of nuances with starting/stopping consumers, this invariant is not as simple as it sounds. In detail: +For consumer chains c1, c2, if both c1 and c2 received a packet p1 sent at t1 and a packet p2 sent at t2, +then both have received ALL packets that were sent between t1 and t2 in the same order. +- [X] MatureOnTimeInv: For every ValidatorSetChangePacket received by a consumer chain at +time t, a MaturedVscPacket is sent back to the provider in the first block +with a timestamp >= t + UnbondingPeriod on that consumer. +- [X] EventuallyMatureOnProviderInv: If we send a VscPacket, this is eventually responded to by all consumers +that were running at the time the packet was sent (and are still running). + +Invariants can also be model-checked by Apalache, using this command: +``` +quint verify --invariant ValidatorUpdatesArePropagatedInv,ValidatorSetHasExistedInv,SameVscPacketsInv,MatureOnTimeInv,EventuallyMatureOnProviderInv \ + ccv_model.qnt +``` + +### Sanity Checks + +Sanity checks verify that certain patterns of behaviour can appear in the model. +In detail, they are invariant checks that we expect to fail. +They usually negate the appearance of some behaviour, i.e. `not(DesirableBehaviour)`. +Then, a counterexample for this is an example trace exhibiting the behaviour. + +They are run like invariant checks, i.e. `quint run --invariant SANITY_CHECK_NAME ccv_model.qnt`. +The available sanity checks are: +- CanRunConsumer +- CanStopConsumer +- CanTimeoutConsumer +- CanSendVscPackets +- CanSendVscMaturedPackets \ No newline at end of file diff --git a/tests/difference/core/quint_model/ccv.qnt b/tests/difference/core/quint_model/ccv.qnt new file mode 100644 index 0000000000..0e07b4476c --- /dev/null +++ b/tests/difference/core/quint_model/ccv.qnt @@ -0,0 +1,811 @@ +// -*- mode: Bluespec; -*- +module ccv_types { + import Time.* from "./libraries/Time" + + type Node = str + type Chain = str + type Power = int + type VscId = int + type ValidatorSet = Node -> Power + type Height = int + // a list of validator sets per blocks, ordered by recency + type VotingPowerHistory = List[ValidatorSet] + + type VscPacket = + { + // the identifier for this packet + id: VscId, + // the new validator set. in the implementation, this would be a list of validator updates + validatorSet: ValidatorSet, + // the time at which the packet was sent. used to check whether packets have timed out. + sendingTime: Time + } + + type VscMaturedPacket = + { + // the id of the VscPacket that matured + id: VscId, + // the time at which the packet was sent. used to check whether packets have timed out. + sendingTime: Time + } + + + // state that each chain needs to store, whether consumer or provider. + type ChainState = { + // Stores the list of voting powers that corresponded to voting powers + // at blocks over the chains entire existence. + // Voting powers should be ordered by recency in descending order. + votingPowerHistory: VotingPowerHistory, + + // the current validator set on each chain. + // this will be included in the next block, but might not be final yet, + // e.g. there may be more modifications in the current block. + currentValidatorSet: ValidatorSet, + + // the latest timestamp that was comitted on chain + lastTimestamp: Time, + } + + // utility function: returns a chain state that is initialized minimally. + pure def GetEmptyChainState(): ChainState = + { + votingPowerHistory: List(), + currentValidatorSet: Map(), + lastTimestamp: 0, + } + + // Defines the current state of the provider chain. Essentially, all information here is stored by the provider on-chain (or could be derived purely by information that is on-chain). + type ProviderState = + { + // the state that each chain needs to store + chainState: ChainState, + + // Stores, for each consumer chain, the list of packets that have been sent to the consumer chain + // and *have not been received yet*. + // In the implementation, this would roughly be the unacknowledged packets on an ibc channel. + outstandingPacketsToConsumer: Chain -> List[VscPacket], + + // the set of received VscMaturedPackets + receivedMaturations: Set[VscMaturedPacket], + + // Stores VscPackets which have been sent but where the provider has *not received a response yet*. + sentVscPacketsToConsumer: Chain -> List[VscPacket], + + // stores whether, in this block, the validator set has changed. + // this is needed because the validator set might be considered to have changed, even though + // it is still technically identical at our level of abstraction, e.g. a validator power change on the provider + // might leave the validator set the same because a delegation and undelegation cancel each other out. + providerValidatorSetChangedInThisBlock: bool, + + // stores, for each consumer chain, its current status - + // not consumer, running, or stopped + consumerStatus: Chain -> str, + + // a monotonic strictly increasing and positive ID that is used + // to uniquely identify the Vscs sent to the consumer chains. + runningVscId: int, + } + + // utility function: returns a provider state that is initialized minimally. + pure def GetEmptyProviderState(): ProviderState = + { + chainState: GetEmptyChainState, + outstandingPacketsToConsumer: Map(), + receivedMaturations: Set(), + sentVscPacketsToConsumer: Map(), + providerValidatorSetChangedInThisBlock: false, + consumerStatus: Map(), + runningVscId: 0, + } + + + // Defines the current state of a consumer chain. This information is accessible to that consumer on-chain. + type ConsumerState = { + // the state that each chain needs to store + chainState: ChainState, + + // Stores the maturation times for VscPackets received by this consumer + maturationTimes: VscPacket -> Time, + + // stores the received vscpackets in descending order of recency, + // i.e. newest first. + receivedVscPackets: List[VscPacket], + + // Stores the list of packets that have been sent to the provider chain by this consumer + // and have not been received yet. + // ordered by recency, so the head is the oldest packet. + // In the implementation, essentially unacknowledged IBC packets. + outstandingPacketsToProvider: List[VscMaturedPacket], + } + + // utility function: returns a consumer state that is initialized minimally. + pure def GetEmptyConsumerState(): ConsumerState = + { + chainState: GetEmptyChainState, + maturationTimes: Map(), + outstandingPacketsToProvider: List(), + receivedVscPackets: List(), + } + + // the state of the protocol consists of the composition of the state of one provider chain with potentially many consumer chains. + type ProtocolState = { + providerState: ProviderState, + // the state of each consumer chain. + // note that we assume that this contains all consumer chains that may ever exist, + // and consumer chains that are currently not running will have providerState.consumerStatus == NOT_CONSUMER or STOPPED. + consumerStates: Chain -> ConsumerState + } + + // gets a protocol state that is initialized minimally. + pure def GetEmptyProtocolState(): ProtocolState = + { + providerState: GetEmptyProviderState, + consumerStates: Map(), + } + + type Error = str + + // we return either a result or an error. + // if hasError() is true, newState may be arbitrary, but the error will be meaningful. + // if hasError() is false, error may be arbitrary, but newState will be meaningful. + type Result = { + newState: ProtocolState, + error: Error + } + + pure def Ok(newState: ProtocolState): Result = { + { + newState: newState, + error: "" + } + } + + pure def Err(msg: str): Result = { + { + newState: { + providerState: { + chainState: { + votingPowerHistory: List(), + currentValidatorSet: Map(), + lastTimestamp: 0, + }, + outstandingPacketsToConsumer: Map(), + receivedMaturations: Set(), + sentVscPacketsToConsumer: Map(), + providerValidatorSetChangedInThisBlock: false, + consumerStatus: Map(), + runningVscId: 0, + }, + consumerStates: Map(), + }, + error: msg + } + } + + pure def hasError(result: Result): bool = result.error != "" + + // possible consumer statuses + pure val STOPPED = "stopped" // the chain was once a consumer chain, but has been voluntarily dropped by the provider. + pure val TIMEDOUT = "timedout" // the chain has timed out and was dropped by the provider. This is only used for involuntary drops. + pure val RUNNING = "running" //Β the chain is currently a consumer chain. Running chains are those that get sent VscPackets. + pure val NOT_CONSUMER = "not consumer" // the chain has never been a consumer chain, and is available to become one. + // When a chain is dropped, it cannot become a consumer again - we assume that would be done by another consumer becoming running. + + // the provider chain. + // given as a pure val so that we can switch cases based on + // whether a chain is the provider or not + pure val PROVIDER_CHAIN = "provider" +} + +module ccv { + // Implements the core logic of the cross-chain validation protocol. + + // Things that are not modelled: + // * Reward distribution + // * Starting/Stopping chains during execution + // * Slashes + + // Things that explicitly are modelled: + // * Validator set changes are propagated from provider to consumers + // * Vsc packets mature + + // We assume that packet receive + ack happen synchronously, + // i.e. when the packet is delivered, the ack is delivered right afterwards. + // This is because it is nontrivial in practice to get a relayer to relay a packet, but not its ack. + + import Time.* from "./libraries/Time" + import extraSpells.* from "./libraries/extraSpells" + import ccv_types.* + + + // =================== + // PROTOCOL PARAMETERS + // =================== + + // the set of all possible consumer chains. + const ConsumerChains: Set[Chain] + + // For each chain, this defines the time between the initiation of an unbonding and its maturation. + const UnbondingPeriodPerChain: Chain -> int + + // The maximum time duration between sending any VscPacket to any consumer chain and receiving the + // corresponding VscMaturedPacket, without timing out the consumer chain and consequently removing it. + const VscTimeout: int + + // The timeoutTimestamp for sent packets. Can differ by chain. + const CcvTimeout: Chain -> int + + // =================== + // PROTOCOL LOGIC contains the meat of the protocol + // functions here roughly correspond to API calls that can be triggered from external sources + // =================== + + // the power of a validator on the provider chain is changed to the given amount. We do not care how this happens, + // e.g. via undelegations, or delegations, ... + pure def votingPowerChange(currentState: ProtocolState, validator: Node, amount: int): Result = { + if (amount < 0) { + Err("Voting power changes must be nonnegative") + } else { + pure val currentValidatorSet = currentState.providerState.chainState.currentValidatorSet + pure val newValidatorSet = currentValidatorSet.put(validator, amount) + // set the validator set changed flag + val newProviderState = currentState.providerState.with( + "providerValidatorSetChangedInThisBlock", true + ) + pure val tmpState = currentState.with( + "providerState", newProviderState + ) + pure val newState = setProviderValidatorSet(tmpState, newValidatorSet) + Ok(newState) + } + } + + // 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. + // 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 + // that indicates whether the consumer timed out or not. + // If the result has an error, the second return should be ignored. + pure def deliverPacketToProvider(currentState: ProtocolState, sender: Chain): (Result, bool) = { + if (not(isRunningConsumer(sender, currentState.providerState))) { + (Err("Sender is not currently a consumer - must have 'running' status!"), false) + } else if (length(currentState.consumerStates.get(sender).outstandingPacketsToProvider) == 0) { + (Err("No outstanding packets to deliver"), false) + } else { + val packet = currentState.consumerStates.get(sender).outstandingPacketsToProvider.head() + if(packet.sendingTime + CcvTimeout.get(sender) < currentState.providerState.chainState.lastTimestamp) { + // drop consumer + val result = stopConsumers( + currentState.providerState.consumerStatus, + Set(), + Set(sender) + ) + + val newConsumerStatus = result._1 + val err = result._2 + if (err != "") { + (Err(err), false) + } else { + val newProviderState = currentState.providerState.with( + "consumerStatus", newConsumerStatus + ) + val newState = currentState.with( + "providerState", newProviderState + ) + (Ok(newState), true) // true because the packet timed out + } + } else { + // the packet has not timed out, so receive it on the provider + val result = recvPacketOnProvider(currentState, sender, packet) + val tmpState = result.newState + if (result.hasError()) { + (result, false) + } else { + (Ok(removeOutstandingPacketFromConsumer(tmpState, sender)), false) // false because the packet did not time out + } + } + } + } + + // Delivers the next queued VscPacket from the provider chain to a consumer chain. + // Arguments are the current state and the consumer chain, to which the packet will be delivered. + // If this packet will time out on the consumer on delivery, + // the consumer will be dropped. + // The first return is the result of the operation, the second result is a boolean + // that indicates whether the consumer timed out or not. + // If the result has an error, the second return should be ignored. + pure def deliverPacketToConsumer(currentState: ProtocolState, receiver: Chain): (Result, bool) = { + if (not(isRunningConsumer(receiver, currentState.providerState))) { + (Err("Receiver is not currently a consumer - must have 'running' status!"), false) + } else if (length(currentState.providerState.outstandingPacketsToConsumer.get(receiver)) == 0) { + (Err("No outstanding packets to deliver"), false) + } else { + val packet = currentState.providerState.outstandingPacketsToConsumer.get(receiver).head() + // check if the consumer timed out + if (packet.sendingTime + CcvTimeout.get(PROVIDER_CHAIN) < currentState.consumerStates.get(receiver).chainState.lastTimestamp) { + // drop consumer + val result = stopConsumers( + currentState.providerState.consumerStatus, + Set(), + Set(receiver) + ) + + val newConsumerStatus = result._1 + val err = result._2 + if (err != "") { + (Err(err), false) + } else { + val newProviderState = currentState.providerState.with( + "consumerStatus", newConsumerStatus + ) + val newState = currentState.with( + "providerState", newProviderState + ) + (Ok(newState), true) // true because the packet timed out + } + } else { + // the packet has not timed out, so receive it on the consumer + val result = recvPacketOnConsumer(currentState, receiver, packet) + val tmpState = result.newState + if (result.hasError()) { + (result, false) + } else { + (Ok(removeOutstandingPacketFromProvider(tmpState, receiver)), false) // false because the packet did not time out + } + } + } + } + + + + /// Ends a block on the provider. This means that the current validator set is committed on chain, + /// packets are queued, and the next block is started. Also, consumers that have passed + /// the VscTimeout without responding to a pending vscpacket are dropped. + pure def endAndBeginBlockForProvider( + currentState: ProtocolState, + // by how much the timestamp should be advanced, + // i.e. the timestamp for the next block is oldTimestamp + timeAdvancement + timeAdvancement: Time, + // a set of consumers that were not consumers before, but should be set to running now. + consumersToStart: Set[Chain], + // a set of consumers that were running before, but should be set to stopped now. + // This argument only needs to contain "voluntary" stops - + // forced stops, e.g. because a consumer timed out, + // will be added automatically. + consumersToStop: Set[Chain]): Result = { + // commit the current running validator set on chain + val currentProviderState = currentState.providerState + val newChainState = currentProviderState.chainState.endAndBeginBlockShared(timeAdvancement) + val providerStateAfterTimeAdvancement = currentProviderState.with( + "chainState", newChainState + ) + + val tmpState = currentState.with( + "providerState", providerStateAfterTimeAdvancement + ) + + // check for Vsc timeouts + val timedOutConsumers = getRunningConsumers(providerStateAfterTimeAdvancement).filter( + consumer => + val res = TimeoutDueToVscTimeout(tmpState, consumer) + res._1 + ) + + + // start/stop chains + val res = providerStateAfterTimeAdvancement.consumerStatus.StartStopConsumers( + consumersToStart, + consumersToStop, + timedOutConsumers + ) + val newConsumerStatus = res._1 + val err = res._2 + val providerStateAfterConsumerAdvancement = providerStateAfterTimeAdvancement.with( + "consumerStatus", newConsumerStatus + ) + + // for each consumer we just set to running, set its initial validator set to be the current one on the provider. + val newConsumerStateMap = + tmpState.consumerStates.keys().mapBy( + (consumer) => + if (consumersToStart.contains(consumer)) { + val currentConsumerState = tmpState.consumerStates.get(consumer) + val newConsumerState = currentConsumerState.with( + "chainState", currentConsumerState.chainState.with( + "currentValidatorSet", providerStateAfterConsumerAdvancement.chainState.currentValidatorSet + ) + ) + newConsumerState + } else { + currentState.consumerStates.get(consumer) + } + ) + val newState = tmpState.with( + "providerState", providerStateAfterConsumerAdvancement + ).with( + "consumerStates", newConsumerStateMap + ) + + if (err != "") { + Err(err) + } else { + val providerStateAfterSending = + if (currentProviderState.providerValidatorSetChangedInThisBlock and + // important: check this on the provider state after the consumer advancement, not on the current state. + getRunningConsumers(providerStateAfterConsumerAdvancement).size() > 0) { + providerStateAfterConsumerAdvancement.sendVscPackets() + } else { + providerStateAfterConsumerAdvancement + } + val finalState = newState.with( + "providerState", providerStateAfterSending + ) + Ok(finalState) + } + } + + pure def endAndBeginBlockForConsumer( + currentState: ProtocolState, + chain: Chain, + // by how much the timestamp of the chain should be advanced for the next block + timeAdvancement: Time): Result = { + if (not(currentState.consumerStates.keys().contains(chain))) { + // if the chain is not a consumer, return an error + Err("chain is not a consumer") + } else { + val currentConsumerState = currentState.consumerStates.get(chain) + val newChainState = currentConsumerState.chainState.endAndBeginBlockShared(timeAdvancement) + val newConsumerState = currentConsumerState.with( + "chainState", newChainState + ) + val maturedPackets = newConsumerState.maturationTimes.keys().filter( + packet => + val maturationTime = newConsumerState.maturationTimes.get(packet) + maturationTime <= newChainState.lastTimestamp + ) + val newMaturationTimes = newConsumerState.maturationTimes.mapRemoveAll(maturedPackets) + val newOutstandingPackets = newConsumerState.outstandingPacketsToProvider.concat( + maturedPackets.map( + packet => { + id: packet.id, + sendingTime: newConsumerState.chainState.lastTimestamp + } + ).toList() + ) + val newConsumerState2 = newConsumerState.with( + "maturationTimes", newMaturationTimes + ).with( + "outstandingPacketsToProvider", newOutstandingPackets + ) + val newConsumerStates = currentState.consumerStates.set(chain, newConsumerState2) + val newState = currentState.with( + "consumerStates", newConsumerStates + ) + Ok(newState) + } + } + + // =================== + // UTILITY FUNCTIONS + // which do not hold the core logic of the protocol, but are still part of it + // =================== + + // Returns the new ConsumerStatusMap according to the consumers to stop + // and the consumers to time out. + // If a consumer is both stopped and timed out, it will be timed out. + // The second return is an error string: If it is not equal to "", + // it contains an error message, and the first return should be ignored. + pure def stopConsumers( + currentConsumerStatusMap: Chain -> str, + consumersToStop: Set[Chain], + consumersToTimeout: Set[Chain]): (Chain -> str, str) = { + val runningConsumers = currentConsumerStatusMap.keys().filter( + chain => currentConsumerStatusMap.get(chain) == RUNNING + ) + // all consumers to stop must be running right now, else we have an error + if (consumersToStop.exclude(runningConsumers).size() > 0) { + (currentConsumerStatusMap, "Cannot stop a consumer that is not running") + } else { + val newConsumerStatusMap = currentConsumerStatusMap.keys().mapBy( + (chain) => + if (consumersToTimeout.contains(chain)) { + TIMEDOUT + } else if (consumersToStop.contains(chain)) { + STOPPED + } else { + currentConsumerStatusMap.get(chain) + } + ) + (newConsumerStatusMap, "") + } + } + + // Returns the new ConsumerStatusMap according to the consumers to start. + // The second return is an error string: If it is not equal to "", + // it contains an error message, and the first return should be ignored. + pure def startConsumers( + currentConsumerStatusMap: Chain -> str, + consumersToStart: Set[Chain]): (Chain -> str, str) = { + val nonConsumers = currentConsumerStatusMap.keys().filter( + chain => currentConsumerStatusMap.get(chain) == NOT_CONSUMER + ) + // all consumers to start must be nonConsumers right now, otherwise we have an error + if (consumersToStart.exclude(nonConsumers).size() > 0) { + (currentConsumerStatusMap, "cannot start a consumer that is stopped or already a consumer") + } else { + val newConsumerStatusMap = currentConsumerStatusMap.keys().mapBy( + (chain) => + if (consumersToStart.contains(chain)) { + RUNNING + } else { + currentConsumerStatusMap.get(chain) + } + ) + (newConsumerStatusMap, "") + } + } + + pure def StartStopConsumers( + currentConsumerStatusMap: Chain -> str, + consumersToStart: Set[Chain], + consumersToStop: Set[Chain], + consumersToTimeout: Set[Chain] + ): (Chain -> str, str) = { + // check if any consumer is both started and stopped + if (consumersToStart.intersect(consumersToStop).size() > 0) { + (currentConsumerStatusMap, "Cannot start and stop a consumer at the same time") + } else { + val res1 = currentConsumerStatusMap.startConsumers(consumersToStart) + val newConsumerStatus = res1._1 + val err1 = res1._2 + val res2 = newConsumerStatus.stopConsumers(consumersToStop, consumersToTimeout) + val err2 = res2._2 + if (err1 != "") { + (currentConsumerStatusMap, err1) + } else if (err2 != "") { + (currentConsumerStatusMap, err2) + } else { + (res2._1, "") + } + } + } + + + // Takes the currentValidatorSet and puts it as the newest set of the voting history + pure def enterCurValSetIntoBlock(chainState: ChainState): ChainState = { + chainState.with( + "votingPowerHistory", chainState.votingPowerHistory.prepend( + chainState.currentValidatorSet + ) + ) + } + + // Advances the timestamp in the chainState by timeAdvancement + pure def advanceTime(chainState: ChainState, timeAdvancement: Time): ChainState = { + chainState.with( + "lastTimestamp", chainState.lastTimestamp + timeAdvancement + ) + } + + // common logic to update the chain state, used by both provider and consumers. + pure def endAndBeginBlockShared(chainState: ChainState, timeAdvancement: Time): ChainState = { + chainState.enterCurValSetIntoBlock().advanceTime(timeAdvancement) + } + + // returns the providerState with the following modifications: + // * sends VscPackets to all running consumers + // * increments the runningVscId + // This should only be called when the provider chain is ending a block, + // and only when the running validator set is considered to have changed + // and there is a consumer to send a packet to. + pure def sendVscPackets(providerState: ProviderState): ProviderState = { + val newSentPacketsPerConsumer = ConsumerChains.mapBy( + (consumer) => + // if validator set changed and the consumer is running, send a packet + if (providerState.providerValidatorSetChangedInThisBlock and + isRunningConsumer(consumer, providerState)) { + List({ + id: providerState.runningVscId, + validatorSet: providerState.chainState.currentValidatorSet, + sendingTime: providerState.chainState.lastTimestamp + }) + } else { + List() + } + ) + val newOutstandingPacketsToConsumer = ConsumerChains.mapBy( + (consumer) => + providerState.outstandingPacketsToConsumer.get(consumer).concat( + newSentPacketsPerConsumer.get(consumer) + ) + ) + val newSentVscPackets = ConsumerChains.mapBy( + (consumer) => + providerState.sentVscPacketsToConsumer.get(consumer).concat( + newSentPacketsPerConsumer.get(consumer) + ) + ) + { + ...providerState, + outstandingPacketsToConsumer: newOutstandingPacketsToConsumer, + sentVscPacketsToConsumer: newSentVscPackets, + providerValidatorSetChangedInThisBlock: false, + runningVscId: providerState.runningVscId + 1, + } + } + + // receives a given packet (sent by the provider) on the consumer. The arguments are the consumer chain that is receiving the packet, and the packet itself. + // To receive a packet, modify the running validator set (not the one entered into the block yet, + // but the candidate that would be put into the block if it ended now) + // and store the maturation time for the packet. + pure def recvPacketOnConsumer(currentState: ProtocolState, receiver: Chain, packet: VscPacket): Result = { + if(not(isRunningConsumer(receiver, currentState.providerState))) { + Err("Receiver is not currently a consumer - must have 'running' status!") + } else { + // update the running validator set, but not the history yet, + // as that only happens when the next block is started + val currentConsumerState = currentState.consumerStates.get(receiver) + val newConsumerState = + { + ...currentConsumerState, + chainState: currentConsumerState.chainState.with( + "currentValidatorSet", packet.validatorSet + ), + maturationTimes: currentConsumerState.maturationTimes.put( + packet, + currentConsumerState.chainState.lastTimestamp + UnbondingPeriodPerChain.get(receiver) + ), + receivedVscPackets: currentConsumerState.receivedVscPackets.prepend(packet) + } + val newConsumerStates = currentState.consumerStates.set(receiver, newConsumerState) + val newState = currentState.with( + "consumerStates", newConsumerStates + ) + Ok(newState) + } + } + + // receives a given packet on the provider. The arguments are the consumer chain that sent the packet, and the packet itself. + // To receive a packet, add it to the list of received maturations. + pure def recvPacketOnProvider(currentState: ProtocolState, sender: Chain, packet: VscMaturedPacket): Result = { + if (not(isRunningConsumer(sender, currentState.providerState))) { + Err("Sender is not currently a consumer - must have 'running' status!") + } else if (currentState.providerState.sentVscPacketsToConsumer.get(sender).head().id != packet.id) { + // the packet is not the oldest sentVscPacket, something went wrong + Err("Received maturation is not for the oldest sentVscPacket") + } else { + val currentReceivedMaturations = currentState.providerState.receivedMaturations + val newReceivedMaturations = currentReceivedMaturations.union(Set(packet)) + val newProviderState = currentState.providerState.with( + "receivedMaturations", newReceivedMaturations + ) + // prune the sentVscPacket + val newSentVscPacket = currentState.providerState.sentVscPacketsToConsumer.get(sender).tail() + val newState = currentState.with( + "providerState", newProviderState + ) + Ok(newState) + } + } + + // removes the oldest outstanding packet from the consumer. on-chain, this would happen when the packet is acknowledged. + // only the oldest packet can be removed, since we model ordered channels. + pure def removeOutstandingPacketFromConsumer(currentState: ProtocolState, sender: Chain): ProtocolState = { + val currentOutstandingPackets = currentState.consumerStates.get(sender).outstandingPacketsToProvider + val newOutstandingPackets = currentOutstandingPackets.tail() + val newConsumerState = currentState.consumerStates.get(sender).with( + "outstandingPacketsToProvider", newOutstandingPackets + ) + val newConsumerStates = currentState.consumerStates.set(sender, newConsumerState) + val newState = currentState.with( + "consumerStates", newConsumerStates + ) + newState + } + + // removes the oldest outstanding packet (to the given consumer) from the provider. + // on-chain, this would happen when the packet is acknowledged. + // only the oldest packet can be removed, since we model ordered channels. + pure def removeOutstandingPacketFromProvider(currentState: ProtocolState, receiver: Chain): ProtocolState = { + val currentOutstandingPackets = currentState.providerState.outstandingPacketsToConsumer.get(receiver) + val newOutstandingPackets = currentOutstandingPackets.tail() + val newProviderState = currentState.providerState.with( + "outstandingPacketsToConsumer", + currentState.providerState.outstandingPacketsToConsumer.set(receiver, newOutstandingPackets) + ) + val newState = currentState.with( + "providerState", newProviderState + ) + newState + } + + // Returns a ProtocolState where the current validator set on the provider is set to + // newValidatorSet. + pure def setProviderValidatorSet(currentState: ProtocolState, newValidatorSet: ValidatorSet): ProtocolState = { + pure val newChainState = currentState.providerState.chainState.with( + "currentValidatorSet", newValidatorSet + ) + currentState.with( + "providerState", + currentState.providerState.with( + "chainState", newChainState + ) + ) + } + + // Returns true if the given chain is currently a running consumer, false otherwise. + pure def isRunningConsumer(chain: Chain, providerState: ProviderState): bool = { + val status = providerState.consumerStatus.get(chain) + status == RUNNING + } + + // Returns the set of all consumer chains that currently have the status RUNNING. + pure def getRunningConsumers(providerState: ProviderState): Set[Chain] = { + providerState.consumerStatus.keys().filter( + chain => providerState.consumerStatus.get(chain) == RUNNING + ) + } + + // Returns the set of all consumer chains that currently have the status NOT_CONSUMER. + pure def getNonConsumers(providerState: ProviderState): Set[Chain] = { + providerState.consumerStatus.keys().filter( + chain => providerState.consumerStatus.get(chain) == NOT_CONSUMER + ) + } + + // Returns whether the consumer has timed out due to the VscTimeout, and an error message. + // If the second return is not equal to "", the first return should be ignored. + // If it is equal to "", the first return will be true if the consumer has timed out and should be dropped, + // or false otherwise. + pure def TimeoutDueToVscTimeout(currentState: ProtocolState, consumer: Chain): (bool, str) = + // check for errors: the consumer is not running + if (not(isRunningConsumer(consumer, currentState.providerState))) { + (false, "Consumer is not currently a consumer - must have 'running' status!") + } else { + val providerState = currentState.providerState + val consumerState = currentState.consumerStates.get(consumer) + + // has a packet been sent on the provider more than VscTimeout ago, but we have not received an answer since then? + val sentVscPacketsToConsumer = providerState.sentVscPacketsToConsumer.get(consumer) + if(sentVscPacketsToConsumer.length() > 0) { + val oldestSentVscPacket = sentVscPacketsToConsumer.head() // if length is 0, this is undefined, but we check for this before we use it + if(oldestSentVscPacket.sendingTime + VscTimeout < providerState.chainState.lastTimestamp) { + (true, "") + } else { + // no timeout yet, it has not been VscTimeout since that packet was sent + (false, "") + } + } else { + // no packet has been sent yet, so no timeout + (false, "") + } + } + + // =================== + // ASSUMPTIONS ON MODEL PARAMETERS + // =================== + + run UnbondingPeriodPositiveTest = + UnbondingPeriodPerChain.keys().forall(chain => UnbondingPeriodPerChain.get(chain) > 0) + + run VscTimeoutPositiveTest = + VscTimeout > 0 + + run CcvTimeoutPositiveTest = + CcvTimeout.keys().forall(chain => CcvTimeout.get(chain) > 0) + + run CcvTimeoutLargerThanUnbondingPeriodTest = + CcvTimeout.get(PROVIDER_CHAIN) > UnbondingPeriodPerChain.values().max() + + run ProviderIsNotAConsumerTest = + not(ConsumerChains.contains(PROVIDER_CHAIN)) + + // ccv timeout contains exactly consumers and provider, no other chains + run CcvTimeoutKeysTest = + CcvTimeout.keys() == ConsumerChains.union(Set(PROVIDER_CHAIN)) + + // unbonding period contains exactly consumers and provider, no other chains + run UnbondingPeriodKeysTest = + UnbondingPeriodPerChain.keys() == ConsumerChains.union(Set(PROVIDER_CHAIN)) +} diff --git a/tests/difference/core/quint_model/ccv_model.qnt b/tests/difference/core/quint_model/ccv_model.qnt new file mode 100644 index 0000000000..f886fe9e85 --- /dev/null +++ b/tests/difference/core/quint_model/ccv_model.qnt @@ -0,0 +1,494 @@ +// -*- mode: Bluespec; -*- +module ccv_model { + // A basic stateful model that utilizes the CCV protocol. + import ccv_types.* from "./ccv" + import Time.* from "./libraries/Time" + import extraSpells.* from "./libraries/extraSpells" + + pure val consumerChains = Set("consumer1", "consumer2", "consumer3") + pure val chains = consumerChains.union(Set(PROVIDER_CHAIN)) + pure val unbondingPeriods = chains.mapBy(chain => 2 * Week) + pure val ccvTimeouts = chains.mapBy(chain => 3 * Week) + + pure val nodes = Set("node1", "node2", "node3", "node4", "node5", "node6", "node7", "node8", "node9", "node10") + pure val InitialValidatorSet = nodes.mapBy(node => 100) + + import ccv(VscTimeout = 5 * Week, CcvTimeout = ccvTimeouts, UnbondingPeriodPerChain = unbondingPeriods, ConsumerChains = consumerChains).* from "./ccv" + + + var currentState: ProtocolState + + // a type storing the parameters used in actions. + // this is used in the trace to store + // the name of the last action, plus the parameters we passed to it. + // Note: This type holds ALL parameters that are used in ANY action, + // so not all of these fields are relevant to each action. + type Action = + { + kind: str, + consumerChain: Chain, + timeAdvancement: Time, + consumersToStart: Set[Chain], + consumersToStop: Set[Chain], + validator: Node, + newVotingPower: int, + } + + + var trace: List[Action] + + // a few different values for time advancements. + // to keep the number of possible steps small, we only have a few different values. + // Roughly, 1s for very small advances (like between blocks), + // and then longer values for increasingly severe downtime scenarios. + // Note that these can still be combined, so in effect we can get all time advancements by any amount of seconds. + pure val timeAdvancements = Set(1 * Second, 1 * Day, 1 * Week, 4 * Week) + + pure def emptyAction = + { + kind: "", + consumerChain: "", + timeAdvancement: 0 * Second, + consumersToStart: Set(), + consumersToStop: Set(), + validator: "", + newVotingPower: 0, + } + + // step allows the most generic nondeterminism, in particular it becomes relatively likely + // that over a long enough runtime, all consumers would time out by mismatching their time advancements, + // and each endblock has a good chance to stop consumers, ... + // step is thus suited to test also unhappy paths. + action step = any { + all { + runningConsumers.size() > 0, // ensure there is a running consumer, otherwise this action does not make sense + nondet chain = oneOf(runningConsumers) + nondet timeAdvancement = oneOf(timeAdvancements) + EndAndBeginBlockForConsumer(chain, timeAdvancement), + }, + + val consumerStatus = currentState.providerState.consumerStatus + nondet consumersToStart = oneOf(nonConsumers.powerset()) + nondet consumersToStop = oneOf(runningConsumers.powerset()) + nondet timeAdvancement = oneOf(timeAdvancements) + EndAndBeginBlockForProvider(timeAdvancement, consumersToStart, consumersToStop), + + nondet node = oneOf(nodes) + // very restricted set of voting powers. exact values are not important, + // and this keeps the state space smaller. + nondet newVotingPower = oneOf(Set(0, 50, 100)) + 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. + all { + runningConsumers.size() > 0, // ensure there is a running consumer, otherwise this action does not make sense + nondet sender = oneOf(runningConsumers) + DeliverVscMaturedPacket(sender), + }, + + // again, we could filter by chains that can actually receive, + // but it's probably not much faster than just trying and failing. + all { + runningConsumers.size() > 0, // ensure there is a running consumer, otherwise this action does not make sense + nondet recciver = oneOf(runningConsumers) + DeliverVscPacket(recciver), + }, + } + + // some utility stateful vals to make invariants easier to define + val providerValidatorHistory = currentState.providerState.chainState.votingPowerHistory + val runningConsumers = getRunningConsumers(currentState.providerState) + val nonConsumers = getNonConsumers(currentState.providerState) + + action init: bool = all { + val providerState = GetEmptyProviderState + val consumerStates = ConsumerChains.mapBy(chain => GetEmptyConsumerState) + val providerStateWithConsumers = providerState.with( + "consumerStatus", + ConsumerChains.mapBy(chain => NOT_CONSUMER) + ).with( + "outstandingPacketsToConsumer", + ConsumerChains.mapBy(chain => List()) + ).with( + "sentVscPacketsToConsumer", + ConsumerChains.mapBy(chain => List()) + ).with( + // set the validator set to be the initial validator set in the history + "chainState", providerState.chainState.with( + "votingPowerHistory", List(InitialValidatorSet) + ).with( + "currentValidatorSet", InitialValidatorSet + ) + ) + currentState' = { + providerState: providerStateWithConsumers, + consumerStates: consumerStates + }, + trace' = List(emptyAction.with("kind", "init")), + } + + action VotingPowerChange(validator: Node, newVotingPower: int): bool = + val result = votingPowerChange(currentState, validator, newVotingPower) + all { + result.hasError() == false, + currentState' = result.newState, + trace' = trace.append(emptyAction.with("kind", "VotingPowerChange").with("validator", validator).with("newVotingPower", newVotingPower)) + } + + // The receiver receives the next outstanding VscPacket from the provider. + // This will time out the consumer if the packet timeout has passed on the receiver. + action DeliverVscPacket(receiver: Chain): bool = + val resultAndTimeout = deliverPacketToConsumer(currentState, receiver) + val result = resultAndTimeout._1 + all { + result.hasError() == false, + currentState' = result.newState, + trace' = trace.append(emptyAction.with("kind", "DeliverVscPacket").with("consumerChain", receiver)) + } + + // The provider receives the next outstanding VscMaturedPacket from the sender. + // This will time out the consumer if the packet timeout has passed on the provider. + action DeliverVscMaturedPacket(sender: Chain): bool = + val resultAndTimeout = deliverPacketToProvider(currentState, sender) + val result = resultAndTimeout._1 + all { + result.hasError() == false, + currentState' = result.newState, + trace' = trace.append(emptyAction.with("kind", "DeliverVscMaturedPacket").with("consumerChain", sender)) + } + + action EndAndBeginBlockForProvider( + timeAdvancement: Time, + consumersToStart: Set[Chain], + consumersToStop: Set[Chain]): bool = + val result = endAndBeginBlockForProvider(currentState, timeAdvancement, consumersToStart, consumersToStop) + all { + result.hasError() == false, + currentState' = result.newState, + trace' = trace.append(emptyAction.with("kind", "EndAndBeginBlockForProvider").with("timeAdvancement", timeAdvancement).with("consumersToStart", consumersToStart).with("consumersToStop", consumersToStop)) + } + + action EndAndBeginBlockForConsumer( + chain: Chain, + timeAdvancement: Time): bool = + val result = endAndBeginBlockForConsumer(currentState, chain, timeAdvancement) + all { + result.hasError() == false, + currentState' = result.newState, + trace' = trace.append(emptyAction.with("kind", "EndAndBeginBlockForConsumer").with("consumerChain", chain).with("timeAdvancement", timeAdvancement)) + } + + // ================== + // INVARIANT CHECKS + // ================== + + + // Every validator set on any consumer chain MUST either be or have been + // a validator set on the provider chain. + val ValidatorSetHasExistedInv = + runningConsumers.forall(chain => + currentState.consumerStates.get(chain).chainState.votingPowerHistory.toSet().forall( + validatorSet => providerValidatorHistory.toSet().contains(validatorSet) + ) + ) + + // Any update in the power of a validator on the provider + // MUST be present in a ValidatorSetChangePacket that is sent to all registered consumer chains + val ValUpdatePrecondition = trace[trace.length()-1].kind == "EndAndBeginBlockForProvider" + val ValidatorUpdatesArePropagatedInv = + // when the provider has just entered a validator set into a block... + ValUpdatePrecondition and currentState.providerState.providerValidatorSetChangedInThisBlock + implies + val providerValSetInCurBlock = providerValidatorHistory.head() + // ... for each consumer that is running then ... + runningConsumers.forall( + // ...the validator set is in a sent packet + consumer => currentState.providerState.sentVscPacketsToConsumer.get(consumer).toSet().exists( + packet => packet.validatorSet == providerValSetInCurBlock + ) + ) + + // Every consumer chain receives the same sequence of + // ValidatorSetChangePackets in the same order. + // NOTE: since not all consumer chains are running all the time, + // we need a slightly weaker invariant: + // For consumer chains c1, c2, if both c1 and c2 received a packet p1 sent at t1 and a packet p2 sent at t2, + // then both have received ALL packets that were sent between t1 and t2. + val SameVscPacketsInv = + runningConsumers.forall( + consumer1 => runningConsumers.forall( + consumer2 => { + val packets1 = currentState.consumerStates.get(consumer1).receivedVscPackets + val packets2 = currentState.consumerStates.get(consumer2).receivedVscPackets + val commonPackets = packets1.toSet().intersect(packets2.toSet()) + if (commonPackets.size() == 0) { + true // they don't share any packets, so nothing to check + } else { + val newestCommonPacket = commonPackets.maxBy(packet => packet.sendingTime) + val oldestCommonPacket = commonPackets.minBy(packet => packet.sendingTime) + // get all packets sent between the oldest and newest common packet + val packetsBetween1 = packets1.select( + packet => packet.sendingTime >= oldestCommonPacket.sendingTime and packet.sendingTime <= newestCommonPacket.sendingTime + ) + val packetsBetween2 = packets2.select( + packet => packet.sendingTime >= oldestCommonPacket.sendingTime and packet.sendingTime <= newestCommonPacket.sendingTime + ) + // these should be the same on both chains + packetsBetween1 == packetsBetween2 + } + } + ) + ) + + // For every ValidatorSetChangePacket received by a consumer chain at + // time t, a MaturedVscPacket is sent back to the provider in the first block + // with a timestamp >= t + UnbondingPeriod + // NOTE: because we remove the maturationTimes entry when we send the packets, + // it suffices to check that there is never an entry in maturationTimes + // that has already matured, i.e. where the maturationTime is smaller-or-equal than the lastTimestamp + val MatureOnTimeInv = + runningConsumers.forall( + consumer => { + val maturationTimes = currentState.consumerStates.get(consumer).maturationTimes + maturationTimes.keys().forall( + // check that the maturation time is in the future + packet => maturationTimes.get(packet) >= currentState.consumerStates.get(consumer).chainState.lastTimestamp + ) + } + ) + + // If we send a VscPacket, this is eventually responded to by all consumers + // that were running at the time the packet was sent (and are still running). + // Since we remove sentVscPacketsToConsumer when we receive responses for them, + // we just check that if a sentVscPacket has been sent more than + // VscTimeout ago, the consumer must have been dropped. + // In practice, when this is true, a pending unbonding can mature. + val EventuallyMatureOnProviderInv = + runningConsumers.forall( + consumer => { + val sentPackets = currentState.providerState.sentVscPacketsToConsumer.get(consumer).toSet() + sentPackets.forall( + packet => + // consumer still has time to respond + not(packet.sendingTime + VscTimeout < currentState.providerState.chainState.lastTimestamp) or + // consumer was dropped + currentState.providerState.consumerStatus.get(consumer) == STOPPED or + currentState.providerState.consumerStatus.get(consumer) == TIMEDOUT + ) + } + ) + + // ================= + // SANITY CHECKS + // ================= + // some invariants that should fail, + // to check that certain behaviours can be exhibited. + // The name of the invariants is the name of the behaviour + // we want to see, and its definition will *negate* that behaviour, so + // we expect these to fail when checked as invariants. + + // We can run consumers. + val CanRunConsumer = + not(ConsumerChains.exists( + consumer => + currentState.providerState.consumerStatus.get(consumer) == RUNNING + )) + + val CanStopConsumer = + not(ConsumerChains.exists( + consumer => + currentState.providerState.consumerStatus.get(consumer) == STOPPED + )) + + val CanTimeoutConsumer = + not(ConsumerChains.exists( + consumer => + currentState.providerState.consumerStatus.get(consumer) == TIMEDOUT + )) + + val CanSendVscPackets = + not(ConsumerChains.exists( + consumer => + currentState.providerState.outstandingPacketsToConsumer.get(consumer).length() > 0 + )) + + val CanSendVscMaturedPackets = + not(ConsumerChains.exists( + consumer => + currentState.consumerStates.get(consumer).outstandingPacketsToProvider.length() > 0 + )) + + val CanReceiveMaturations = + not(ConsumerChains.exists( + consumer => + currentState.providerState.receivedMaturations.size() > 0 + )) + + // ================== + // MANUAL TEST CASES + // ================== + // Manually written test cases to get confidence in the base operation of the protocol. + + /// Test a simple happy path where: + /// * the consumer chain is set to running + /// * a validator set change happens + /// * a block is ended on the provider, i.e. a packet is sent to the consumer + /// * the consumer receives the packet + /// * the chains wait until the unbonding period is over + /// * the consumer sends a VscMaturedPacket to the provider + /// * the provider receives the VscMaturedPacket + run HappyPathTest: bool = { + init.then( + all { + assert(currentState.providerState.consumerStatus == Map( + "consumer1" -> NOT_CONSUMER, + "consumer2" -> NOT_CONSUMER, + "consumer3" -> NOT_CONSUMER + )), + assert(currentState.providerState.outstandingPacketsToConsumer == Map( + "consumer1" -> List(), + "consumer2" -> List(), + "consumer3" -> List() + )), + assert(currentState.providerState.sentVscPacketsToConsumer == Map( + "consumer1" -> List(), + "consumer2" -> List(), + "consumer3" -> List() + )), + assert(currentState.consumerStates.keys() == consumerChains), + assert(currentState.providerState.chainState.votingPowerHistory == List(InitialValidatorSet)), + assert(currentState.providerState.chainState.currentValidatorSet == InitialValidatorSet), + assert(currentState.providerState.chainState.lastTimestamp == 0), + VotingPowerChange("node1", 50) + }) + .then( + all { + // the validator set has changed + assert(currentState.providerState.chainState.currentValidatorSet == InitialValidatorSet.put("node1", 50)), + // start consumer1 + EndAndBeginBlockForProvider(1 * Second, Set("consumer1"), Set()) + }) + .then( + all { + // consumer1 was started + assert(currentState.providerState.consumerStatus.get("consumer1") == RUNNING), + // a packet was sent to consumer1 + assert(currentState.providerState.outstandingPacketsToConsumer.get("consumer1").length() == 1), + // the validator set on the provider was entered into the history + assert(currentState.providerState.chainState.votingPowerHistory == List(InitialValidatorSet.put("node1", 50), InitialValidatorSet)), + // deliver the packet + DeliverVscPacket("consumer1") + } + ) + .then( + all { + // make sure the packet was removed from the provider + assert(currentState.providerState.outstandingPacketsToConsumer.get("consumer1").length() == 0), + // ensure the maturation time was entered on the consumer + assert(currentState.consumerStates.get("consumer1").maturationTimes.keys().size() == 1), + // the validator set was put as the current validator set + assert(currentState.consumerStates.get("consumer1").chainState.currentValidatorSet == InitialValidatorSet.put("node1", 50)), + // advance time on provider until the unbonding period is over + EndAndBeginBlockForProvider(UnbondingPeriodPerChain.get("consumer1"), Set(), Set()), + } + ) + .then( + // advance time on consumer until the unbonding period is over + EndAndBeginBlockForConsumer("consumer1", UnbondingPeriodPerChain.get("consumer1")) + ) + .then( + all { + // the packet has matured, so it was sent by the consumer + assert(currentState.consumerStates.get("consumer1").outstandingPacketsToProvider.length() == 1), + // it was removed from the maturationTimes + assert(currentState.consumerStates.get("consumer1").maturationTimes.keys().size() == 0), + // receive the packet on the provider + DeliverVscMaturedPacket("consumer1") + } + ) + .then( + all { + // the packet was received on the provider + assert(currentState.providerState.receivedMaturations.size() == 1), + // the packet was removed from the consumer + assert(currentState.consumerStates.get("consumer1").outstandingPacketsToProvider.length() == 0), + VotingPowerChange("node1", 50) // just so this still has an effect + } + ) + } + + /// a manual test case for the SameVscPacketsInv, since it needs very specific behaviour to even apply. + run SameVscPacketsManualTest = + init.then( + // start all consumers except for consumer3 + EndAndBeginBlockForProvider(1 * Second, Set("consumer1", "consumer2"), Set()) + ).then( + // change voting power + VotingPowerChange("node1", 50) + ).then( + // send packet to consumer1 and consumer2 + EndAndBeginBlockForProvider(1 * Second, Set(), Set()) + ).then( + // deliver the packets + DeliverVscPacket("consumer1") + ).then( + // deliver to consumer2 + DeliverVscPacket("consumer2") + ).then( + // start consumer3 + EndAndBeginBlockForProvider(1 * Second, Set("consumer3"), Set()) + ).then( + // do another voting power change + VotingPowerChange("node2", 50) + ).then( + // send packets + EndAndBeginBlockForProvider(1 * Second, Set(), Set()) + ).then( + //deliver to consumer1 + DeliverVscPacket("consumer1") + ).then( + // deliver to consumer2 + DeliverVscPacket("consumer2") + ).then( + // deliver to consumer3 + DeliverVscPacket("consumer3") + ) + .then( + // the SameVscPacketInv should hold here + all { + assert(SameVscPacketsInv), + // action does not matter, but needed to have uniform effect + VotingPowerChange("node1", 50) + } + ) + + // a manual test for the EventuallyMatureOnProvider invariant + run VscTimeoutManualTest = + init + .then( + // start all consumer chains + EndAndBeginBlockForProvider(1 * Second, ConsumerChains, Set()) + ) + .then( + // change voting power + VotingPowerChange("node1", 50) + ) + .then( + // send packets + EndAndBeginBlockForProvider(1 * Second, Set(), Set()) + ) + .then( + // advance time on provider by VscTimeout + 1 Second + EndAndBeginBlockForProvider(VscTimeout + 1 * Second, Set(), Set()) + ) + .then( + all { + // the consumer chains should have timed out + assert(ConsumerChains.forall( + chain => currentState.providerState.consumerStatus.get(chain) == TIMEDOUT + )), + VotingPowerChange("node1", 50) // action needs to be there but does not matter what it is + } + ) +} \ No newline at end of file diff --git a/tests/difference/core/quint_model/ccv_test.qnt b/tests/difference/core/quint_model/ccv_test.qnt new file mode 100644 index 0000000000..6bbe884d52 --- /dev/null +++ b/tests/difference/core/quint_model/ccv_test.qnt @@ -0,0 +1,253 @@ +// -*- mode: Bluespec; -*- + +// contains test logic for the stateless functions in the CCV module +module ccv_test { + import ccv_types.* from "./ccv" + import Time.* from "./libraries/Time" + import extraSpells.* from "./libraries/extraSpells" + + pure val consumerChains = Set("sender", "receiver") + pure val chains = consumerChains.union(Set(PROVIDER_CHAIN)) + pure val unbondingPeriods = chains.mapBy(chain => 2 * Week) + pure val ccvTimeouts = chains.mapBy(chain => 3 * Week) + + import ccv(VscTimeout = 5 * Week, CcvTimeout = ccvTimeouts, UnbondingPeriodPerChain = unbondingPeriods, ConsumerChains = consumerChains).* from "./ccv" + + // negative voting powers give an error + run VotingPowerNegativeTest = + { + votingPowerChange( + GetEmptyProtocolState, + "validator", + -1 + ).hasError() + } + + run VotingPowerOkTest = + { + val result = votingPowerChange( + GetEmptyProtocolState, + "validator", + 5 + ) + not(result.hasError()) and + result.newState.providerState.chainState.currentValidatorSet.keys().contains("validator") and + result.newState.providerState.chainState.currentValidatorSet.get("validator") == 5 + } + + // voting power of 0 is allowed and applied as usual + run VotingPowerZeroTest = + { + val tmpResult = votingPowerChange( + GetEmptyProtocolState, + "validator", + 5 + ) + val finalResult = votingPowerChange( + tmpResult.newState, + "validator", + 0 + ) + not(finalResult.hasError()) and + finalResult.newState.providerState.chainState.currentValidatorSet.get("validator") == 0 + } + + run VotingPowerSetsFlagTest = + { + // change voting power + val tmpResult = votingPowerChange( + GetEmptyProtocolState, + "validator", + 5 + ) + // but then set it back to the initial value + val finalResult = votingPowerChange( + tmpResult.newState, + "validator", + 0 + ) + // still should set the flag + not(finalResult.hasError()) and + finalResult.newState.providerState.providerValidatorSetChangedInThisBlock + } + + + // make sure that VotingPowerChange ONLY changes the current validator set, not the history + run VotingPowerChangeDoesNotChangeHistoryTest = + { + val result = votingPowerChange( + GetEmptyProtocolState, + "validator", + 0 + ) + not(result.hasError()) and + result.newState.providerState.chainState.votingPowerHistory == List() + } + + // Defines a test state to test the deliverPacketToProvider function against. + pure val _DeliverPacketToProvider_TestState = + val currentState = GetEmptyProtocolState + val sender = "sender" + val providerState = currentState.providerState + val consumerState = GetEmptyConsumerState + // add the consumer to the consumerStates + val consumerStates = currentState.consumerStates.put(sender, consumerState) + val providerState2 = providerState.with( + "consumerStatus", providerState.consumerStatus.put(sender, RUNNING) + ) + val providerState3 = providerState2.with( + "outstandingPacketsToConsumer", providerState2.outstandingPacketsToConsumer.put(sender, List({ + id: 0, + validatorSet: Map(), + sendingTime: 0 + })) + ) + currentState.with( + "providerState", providerState3 + ).with( + "consumerStates", consumerStates + ) + + // add a packet on the consumer + pure val DeliverPacketToProviderHappyPathTest_testState = _DeliverPacketToProvider_TestState.with( + "consumerStates", _DeliverPacketToProvider_TestState.consumerStates.put( + "sender", _DeliverPacketToProvider_TestState.consumerStates.get("sender").with( + "outstandingPacketsToProvider", List({ + id: 0, + sendingTime: 0 + }) + ) + ) + ).with( + // put an entry into sentVscPacket on the provider that corresponds to the packet we put on the consumer + "providerState", _DeliverPacketToProvider_TestState.providerState.with( + "sentVscPacketsToConsumer", _DeliverPacketToProvider_TestState.providerState.sentVscPacketsToConsumer.put( + "sender", List({ + id: 0, + validatorSet: _DeliverPacketToProvider_TestState.providerState.chainState.currentValidatorSet, + sendingTime: 0 + }) + ) + ) + ) + + pure val DeliverPacketToProviderHappyPathTest_resultAndTimeout = deliverPacketToProvider(DeliverPacketToProviderHappyPathTest_testState, "sender") + + // test is split to be easier to pinpoint which assertion failed + run DidNotTimeOut_DeliverPacketToProviderHappyPathTest = + { + val result = DeliverPacketToProviderHappyPathTest_resultAndTimeout._1 + val timeout = DeliverPacketToProviderHappyPathTest_resultAndTimeout._2 + not(result.hasError()) and + not(timeout) + } + + run StateModificationOK_DeliverPacketToProviderHappyPathTest = + { + val result = DeliverPacketToProviderHappyPathTest_resultAndTimeout._1 + val newProviderState = result.newState.providerState + val newConsumerState = result.newState.consumerStates.get("sender") + not(result.hasError()) and + newProviderState.receivedMaturations.size() == 1 and + newConsumerState.outstandingPacketsToProvider.length() == 0 + } + + // add a packet on the consumer + pure val DeliverPacketToProviderTimeoutTest_testState = DeliverPacketToProviderHappyPathTest_testState.with( + "providerState", DeliverPacketToProviderHappyPathTest_testState.providerState.with( + "chainState", DeliverPacketToProviderHappyPathTest_testState.providerState.chainState.with( + // set the timestamp to be after the timeout + "lastTimestamp", CcvTimeout.get("sender") + 1 + ) + ) + ) + + pure val DeliverPacketToProviderTimeoutTest_resultAndTimeout = deliverPacketToProvider(DeliverPacketToProviderTimeoutTest_testState, "sender") + + run DidTimeOut_DeliverPacketToProviderTimeoutTest = + { + val result = DeliverPacketToProviderTimeoutTest_resultAndTimeout._1 + val timeout = DeliverPacketToProviderTimeoutTest_resultAndTimeout._2 + val newProviderState = result.newState.providerState + val newConsumerState = result.newState.consumerStates.get("sender") + not(result.hasError()) and + timeout + } + + run StateModificationOK_DeliverPacketToProviderTimeoutTest = + { + val result = DeliverPacketToProviderTimeoutTest_resultAndTimeout._1 + val newProviderState = result.newState.providerState + val newConsumerState = result.newState.consumerStates.get("sender") + not(result.hasError()) and + newProviderState.receivedMaturations.size() == 0 and + newProviderState.consumerStatus.get("sender") == TIMEDOUT + } + + run ConsumerStatusMapHappyPathTest = + { + val currentConsumerStatusMap = Map( + "chain1" -> NOT_CONSUMER, + "chain2" -> RUNNING, + "chain3" -> STOPPED + ) + val res = StartStopConsumers( + currentConsumerStatusMap, + Set("chain1"), + Set("chain2"), + Set() + ) + res._2 == "" and + res._1.get("chain1") == RUNNING and + res._1.get("chain2") == STOPPED and + res._1.get("chain3") == STOPPED + } + + run ConsumerStatusMapAlreadyRunningTest = + { + val currentConsumerStatusMap = Map( + "chain1" -> NOT_CONSUMER, + "chain2" -> RUNNING, + "chain3" -> STOPPED + ) + val res = StartStopConsumers( + currentConsumerStatusMap, + Set("chain2"), + Set("chain3"), + Set() + ) + res._2 == "cannot start a consumer that is stopped or already a consumer" + } + + run ConsumerStatusMapAlreadyStoppedTest = + { + val currentConsumerStatusMap = Map( + "chain1" -> NOT_CONSUMER, + "chain2" -> RUNNING, + "chain3" -> STOPPED + ) + val res = StartStopConsumers( + currentConsumerStatusMap, + Set("chain1"), + Set("chain3"), + Set() + ) + res._2 == "Cannot stop a consumer that is not running" + } + + run ChainBothInStartAndStopTest = + { + val currentConsumerStatusMap = Map( + "chain1" -> NOT_CONSUMER, + "chain2" -> RUNNING, + "chain3" -> STOPPED + ) + val res = StartStopConsumers( + currentConsumerStatusMap, + Set("chain1"), + Set("chain1"), + Set() + ) + res._2 == "Cannot start and stop a consumer at the same time" + } +} \ No newline at end of file diff --git a/tests/difference/core/quint_model/libraries/Time.qnt b/tests/difference/core/quint_model/libraries/Time.qnt new file mode 100644 index 0000000000..a85d97697d --- /dev/null +++ b/tests/difference/core/quint_model/libraries/Time.qnt @@ -0,0 +1,14 @@ +// -*- mode: Bluespec; -*- +// A simple module for time that makes timings more readable, +// e.g. 5 * Minute. +// The base unit are seconds, i.e. to get the number of seconds in a time value, just treat it as an int. +module Time { + type Time = int + + pure val Second = 1 + pure val Minute = 60 * Second + pure val Hour = 60 * Minute + pure val Day = 24 * Hour + pure val Week = 7 * Day + pure val Year = 365 * Day +} \ No newline at end of file diff --git a/tests/difference/core/quint_model/libraries/extraSpells.qnt b/tests/difference/core/quint_model/libraries/extraSpells.qnt new file mode 100644 index 0000000000..cc20c17aef --- /dev/null +++ b/tests/difference/core/quint_model/libraries/extraSpells.qnt @@ -0,0 +1,213 @@ +// -*- mode: Bluespec; -*- + +// This module is just a library with utility functions (sometimes called spells in Quint). +module extraSpells { + + pure def prepend(__list: List[a], __elem: a): List[a] = { + List(__elem).concat(__list) + } + + run prependTest = all { + assert(List(2,3,4).prepend(1) == List(1,2,3,4)), + assert(List().prepend(1) == List(1)), + } + + /// An annotation for writing preconditions. + /// - @param __cond condition to check + /// - @returns true if and only if __cond evaluates to true + pure def require(__cond: bool): bool = __cond + + run requireTest = all { + assert(require(4 > 3)), + assert(not(require(false))), + } + + /// A convenience operator that returns a string error code, + /// if the condition does not hold true. + /// + /// - @param __cond condition to check + /// - @param __error a non-empty error message + /// - @returns "", when __cond holds true; otherwise __error + pure def requires(__cond: bool, __error: str): str = { + if (__cond) "" else __error + } + + run requiresTest = all { + assert(requires(4 > 3, "4 > 3") == ""), + assert(requires(4 < 3, "false: 4 < 3") == "false: 4 < 3"), + } + + /// Compute the absolute value of an integer + /// + /// - @param __i : an integer whose absolute value we are interested in + /// - @returns |__i|, the absolute value of __i + pure def abs(__i: int): int = { + if (__i < 0) -__i else __i + } + + run absTest = all { + assert(abs(3) == 3), + assert(abs(-3) == 3), + assert(abs(0) == 0), + } + + /// Remove a set element. + /// + /// - @param __set a set to remove an element from + /// - @param __elem an element to remove + /// - @returns a new set that contains all elements of __set but __elem + pure def setRemove(__set: Set[a], __elem: a): Set[a] = { + __set.exclude(Set(__elem)) + } + + run setRemoveTest = all { + assert(Set(2, 4) == Set(2, 3, 4).setRemove(3)), + assert(Set() == Set().setRemove(3)), + } + + /// Test whether a key is present in a map + /// + /// - @param __map a map to query + /// - @param __key the key to look for + /// - @returns true if and only __map has an entry associated with __key + pure def has(__map: a -> b, __key: a): bool = { + __map.keys().contains(__key) + } + + run hasTest = all { + assert(Map(2 -> 3, 4 -> 5).has(2)), + assert(not(Map(2 -> 3, 4 -> 5).has(6))), + } + + /// Get the map value associated with a key, or the default, + /// if the key is not present. + /// + /// - @param __map the map to query + /// - @param __key the key to search for + /// - @returns the value associated with the key, if __key is + /// present in the map, and __default otherwise + pure def getOrElse(__map: a -> b, __key: a, __default: b): b = { + if (__map.has(__key)) { + __map.get(__key) + } else { + __default + } + } + + run getOrElseTest = all { + assert(Map(2 -> 3, 4 -> 5).getOrElse(2, 0) == 3), + assert(Map(2 -> 3, 4 -> 5).getOrElse(7, 11) == 11), + } + + /// Remove a map entry. + /// + /// - @param __map a map to remove an entry from + /// - @param __key the key of an entry to remove + /// - @returns a new map that contains all entries of __map + /// that do not have the key __key + pure def mapRemove(__map: a -> b, __key: a): a -> b = { + __map.keys().setRemove(__key).mapBy(__k => __map.get(__k)) + } + + run mapRemoveTest = all { + assert(Map(3 -> 4, 7 -> 8) == Map(3 -> 4, 5 -> 6, 7 -> 8).mapRemove(5)), + assert(Map() == Map().mapRemove(3)), + } + + /// Removes a set of map entry. + /// + /// - @param __map a map to remove an entry from + /// - @param __keys a set of keys to remove from the map + /// - @returns a new map that contains all entries of __map + /// that do not have a key in __keys + pure def mapRemoveAll(__map: a -> b, __keys: Set[a]): a -> b = { + __map.keys().exclude(__keys).mapBy(__k => __map.get(__k)) + } + + run mapRemoveAllTest = + val m = Map(3 -> 4, 5 -> 6, 7 -> 8) + all { + assert(m.mapRemoveAll(Set(5, 7)) == Map(3 -> 4)), + assert(m.mapRemoveAll(Set(5, 99999)) == Map(3 -> 4, 7 -> 8)), + } + + //// Returns a list of all elements of a set. + //// + //// - @param __set a set + //// - @returns a list of all elements of __set + pure def toList(__set: Set[a]): List[a] = { + __set.fold(List(), (__l, __e) => __l.append(__e)) + } + + //// Returns a set of the elements in the list. + //// + //// - @param __list a list + //// - @returns a set of the elements in __list + pure def toSet(__list: List[a]): Set[a] = { + __list.foldl(Set(), (__s, __e) => __s.union(Set(__e))) + } + + run toListAndSetTest = + all { + assert(Set(3, 2, 1).toList().toSet() == Set(1, 2, 3)), + assert(List(2,3,1).toSet() == Set(1, 2, 3)), + assert(List(2,3,1).toSet() == List(3,2,1).toSet()), + assert(toList(Set()) == List()), + assert(toSet(List()) == Set()) + } + + pure def add(__set: Set[a], elem: a): Set[a] = { + __set.union(Set(elem)) + } + + pure def values(__map: a -> b): Set[b] = { + __map.keys().fold(Set(), (__s, __k) => __s.add(__map.get(__k))) + } + run valuesTest = + all { + assert(values(Map(1 -> 2, 3 -> 4)) == Set(2, 4)), + assert(values(Map()) == Set()) + } + + // Returns the maximal element of the set. + // If the set is empty, the function call will fail at runtime. + pure def max(__set: Set[int]): int = maxBy(__set, __a => __a) + + run maxTest = + all { + assert(max(Set(1, 2, 3)) == 3), + } + + // Returns the minimal element of the set. + // If the set is empty, the function call will fail at runtime. + pure def min(__set: Set[int]): int = minBy(__set, __a => __a) + + run minTest = + all { + assert(min(Set(1, 2, 3)) == 1), + } + + // Returns the maximum element of a set, according to a given function. + // If two elements are equally large, an arbitrary one will be returned. + // If the set is empty, the function call will fail at runtime. + pure def maxBy(__set: Set[a], __f: a => int): a = { + __set.fold( + oneOf(__set), + (__m, __e) => if(__f(__m) > __f(__e)) {__m } else {__e} + ) + } + + run maxByTest = + all { + assert(maxBy(Set(1, 2, 3), __x => __x) == 3), + assert(maxBy(Set(1, 2, 3), __x => -__x) == 1), + } + + // Like maxBy, but returns the minimum element. + pure def minBy(__set: Set[a], __f: a => int): a = { + __set.fold( + oneOf(__set), + (__m, __e) => if(__f(__m) < __f(__e)) {__m } else {__e} + ) + } +} diff --git a/tests/difference/core/quint_model/run_invariants.sh b/tests/difference/core/quint_model/run_invariants.sh new file mode 100755 index 0000000000..4c65693cc0 --- /dev/null +++ b/tests/difference/core/quint_model/run_invariants.sh @@ -0,0 +1,4 @@ +#! /bin/sh + +quint test ccv_model.qnt +quint run --invariant "all{ValidatorUpdatesArePropagatedInv,ValidatorSetHasExistedInv,SameVscPacketsInv,MatureOnTimeInv,EventuallyMatureOnProviderInv}" ccv_model.qnt --max-steps 500 --max-samples 200 \ No newline at end of file diff --git a/tests/e2e/README.md b/tests/e2e/README.md index ee9c962651..4fb3e721e8 100644 --- a/tests/e2e/README.md +++ b/tests/e2e/README.md @@ -10,4 +10,15 @@ If the chain state from `state.go` is modified, the `ChainStateWithProposalTypes When adding a new proposal type: * add a case for your proposal type to `json_utils.go/UnmarshalProposalWithType` -* add a generator for your proposal type in `state_rapid_test.go` and add it to the `GetProposalGen` function \ No newline at end of file +* add a generator for your proposal type in `state_rapid_test.go` and add it to the `GetProposalGen` function + +## Regenerating Traces + +The traces in `tracehandler_testdata` are generated by the test `trace_handlers_test.go/TestWriteExamples`. + +You can regenerate them by running `make e2e-traces` in the root of the repo. + +## Running against traces + +To run a test trace in the e2e tests, run `go run . --test-file $TRACEFILE::$TESTCONFIG`. +See `--help` for more details. diff --git a/tests/e2e/action_rapid_test.go b/tests/e2e/action_rapid_test.go index 005f52610d..871b78dc24 100644 --- a/tests/e2e/action_rapid_test.go +++ b/tests/e2e/action_rapid_test.go @@ -66,7 +66,6 @@ func GetActionGen() *rapid.Generator[any] { GetSubmitConsumerAdditionProposalActionGen().AsAny(), GetSubmitConsumerRemovalProposalActionGen().AsAny(), GetSubmitParamChangeProposalActionGen().AsAny(), - GetSubmitEquivocationProposalActionGen().AsAny(), GetVoteGovProposalActionGen().AsAny(), GetStartConsumerChainActionGen().AsAny(), GetAddChainToRelayerActionGen().AsAny(), @@ -84,12 +83,16 @@ func GetActionGen() *rapid.Generator[any] { GetRegisterRepresentativeActionGen().AsAny(), GetDoublesignSlashActionGen().AsAny(), GetAssignConsumerPubKeyActionGen().AsAny(), - GetSlashThrottleDequeueActionGen().AsAny(), GetCreateIbcClientsActionGen().AsAny(), + GetSlashMeterReplenishmentAction().AsAny(), + GetWaitTimeAction().AsAny(), CreateCancelUnbondTokensActionGen().AsAny(), CreateLightClientEquivocationAttackActionGen().AsAny(), CreateLightClientAmnesiaAttackActionGen().AsAny(), CreateLightClientLunaticAttackActionGen().AsAny(), + GetStartConsumerEvidenceDetectorActionGen().AsAny(), + GetForkConsumerChainActionGen().AsAny(), + GetUpdateLightClientActionGen().AsAny(), ) } @@ -208,7 +211,7 @@ func GetStartChainActionGen() *rapid.Generator[StartChainAction] { Chain: GetChainIDGen().Draw(t, "Chain"), Validators: GetStartChainValidatorsGen().Draw(t, "Validators"), GenesisChanges: rapid.String().Draw(t, "GenesisChanges"), - SkipGentx: rapid.Bool().Draw(t, "SkipGentx"), + IsConsumer: rapid.Bool().Draw(t, "IsConsumer"), } }) } @@ -279,19 +282,6 @@ func GetSubmitParamChangeProposalActionGen() *rapid.Generator[submitParamChangeL }) } -func GetSubmitEquivocationProposalActionGen() *rapid.Generator[submitEquivocationProposalAction] { - return rapid.Custom(func(t *rapid.T) submitEquivocationProposalAction { - return submitEquivocationProposalAction{ - Chain: GetChainIDGen().Draw(t, "Chain"), - From: GetValidatorIDGen().Draw(t, "From"), - Deposit: rapid.Uint().Draw(t, "Deposit"), - Height: rapid.Int64().Draw(t, "Height"), - Time: GetTimeGen().Draw(t, "Time"), - Power: rapid.Int64().Draw(t, "Power"), - } - }) -} - func TestMarshalAndUnmarshalTime(t *testing.T) { rapid.Check(t, func(t *rapid.T) { time1 := GetTimeGen().Draw(t, "time") @@ -489,13 +479,49 @@ func GetAssignConsumerPubKeyActionGen() *rapid.Generator[assignConsumerPubKeyAct }) } -func GetSlashThrottleDequeueActionGen() *rapid.Generator[slashThrottleDequeueAction] { - return rapid.Custom(func(t *rapid.T) slashThrottleDequeueAction { - return slashThrottleDequeueAction{ - Chain: GetChainIDGen().Draw(t, "Chain"), - CurrentQueueSize: rapid.Int().Draw(t, "CurrentQueueSize"), - NextQueueSize: rapid.Int().Draw(t, "NextQueueSize"), - Timeout: time.Duration(rapid.Int().Draw(t, "Timeout")) * time.Millisecond, +func GetSlashMeterReplenishmentAction() *rapid.Generator[slashMeterReplenishmentAction] { + return rapid.Custom(func(t *rapid.T) slashMeterReplenishmentAction { + return slashMeterReplenishmentAction{ + TargetValue: rapid.Int64().Draw(t, "TargetValue"), + Timeout: time.Duration(rapid.Int().Draw(t, "Timeout")) * time.Millisecond, + } + }) +} + +func GetWaitTimeAction() *rapid.Generator[waitTimeAction] { + return rapid.Custom(func(t *rapid.T) waitTimeAction { + return waitTimeAction{ + WaitTime: time.Duration(rapid.Int().Draw(t, "Timeout")) * time.Millisecond, + } + }) +} + +func GetForkConsumerChainActionGen() *rapid.Generator[forkConsumerChainAction] { + return rapid.Custom(func(t *rapid.T) forkConsumerChainAction { + return forkConsumerChainAction{ + ConsumerChain: GetChainIDGen().Draw(t, "ConsumerChain"), + ProviderChain: GetChainIDGen().Draw(t, "ProviderChain"), + Validator: GetValidatorIDGen().Draw(t, "Validator"), + RelayerConfig: rapid.String().Draw(t, "RelayerConfig"), + } + }) +} + +func GetStartConsumerEvidenceDetectorActionGen() *rapid.Generator[startConsumerEvidenceDetectorAction] { + return rapid.Custom(func(t *rapid.T) startConsumerEvidenceDetectorAction { + return startConsumerEvidenceDetectorAction{ + Chain: GetChainIDGen().Draw(t, "Chain"), + } + }) +} + +func GetUpdateLightClientActionGen() *rapid.Generator[updateLightClientAction] { + return rapid.Custom(func(t *rapid.T) updateLightClientAction { + return updateLightClientAction{ + Chain: GetChainIDGen().Draw(t, "Chain"), + HostChain: GetChainIDGen().Draw(t, "HostChain"), + RelayerConfig: rapid.String().Draw(t, "RelayerConfig"), + ClientID: rapid.String().Draw(t, "ClientID"), } }) } diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index 386404baaa..b95be90d12 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -15,8 +15,6 @@ import ( clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" "github.com/tidwall/gjson" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" - "github.com/cosmos/interchain-security/v3/x/ccv/provider/client" "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" ccvtypes "github.com/cosmos/interchain-security/v3/x/ccv/types" @@ -67,7 +65,7 @@ type StartChainAction struct { Validators []StartChainValidator // Genesis changes specific to this action, appended to genesis changes defined in chain config GenesisChanges string - SkipGentx bool + IsConsumer bool } type StartChainValidator struct { @@ -137,7 +135,7 @@ func (tr *TestConfig) startChain( cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, "/bin/bash", "/testnet-scripts/start-chain.sh", chainConfig.BinaryName, string(vals), string(chainConfig.ChainId), chainConfig.IpPrefix, genesisChanges, - fmt.Sprint(action.SkipGentx), + fmt.Sprint(action.IsConsumer), // override config/config.toml for each node on chain // 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 @@ -172,8 +170,9 @@ func (tr *TestConfig) startChain( } tr.addChainToRelayer(addChainToRelayerAction{ - Chain: action.Chain, - Validator: action.Validators[0].Id, + Chain: action.Chain, + Validator: action.Validators[0].Id, + IsConsumer: action.IsConsumer, }, verbose) // store the fact that we started the chain @@ -431,78 +430,6 @@ func (tr TestConfig) submitParamChangeProposal( tr.waitBlocks(action.Chain, 2, 60*time.Second) } -type submitEquivocationProposalAction struct { - Chain ChainID - Height int64 - Time time.Time - Power int64 - Validator ValidatorID - Deposit uint - From ValidatorID -} - -func (tr TestConfig) submitEquivocationProposal(action submitEquivocationProposalAction, verbose bool) { - val := tr.validatorConfigs[action.Validator] - providerChain := tr.chainConfigs[ChainID("provi")] - - prop := client.EquivocationProposalJSON{ - Summary: "Validator equivocation!", - EquivocationProposal: types.EquivocationProposal{ - Title: "Validator equivocation!", - Description: fmt.Sprintf("Validator: %s has committed an equivocation infraction on ChainID: %s", action.Validator, action.Chain), - Equivocations: []*evidencetypes.Equivocation{ - { - Height: action.Height, - Time: action.Time, - Power: action.Power, - ConsensusAddress: val.ValconsAddress, - }, - }, - }, - 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") - } - - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - bz, err = exec.Command("docker", "exec", tr.containerConfig.InstanceName, - "/bin/bash", "-c", fmt.Sprintf(`echo '%s' > %s`, jsonStr, "/equivocation-proposal.json")).CombinedOutput() - - if err != nil { - log.Fatal(err, "\n", string(bz)) - } - - //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - // EQUIVOCATION PROPOSAL - bz, err = exec.Command("docker", "exec", tr.containerConfig.InstanceName, providerChain.BinaryName, - - "tx", "gov", "submit-legacy-proposal", "equivocation", "/equivocation-proposal.json", - - `--from`, `validator`+fmt.Sprint(action.From), - `--chain-id`, string(providerChain.ChainId), - `--home`, tr.getValidatorHome(providerChain.ChainId, action.From), - `--node`, tr.getValidatorNode(providerChain.ChainId, action.From), - `--gas`, "9000000", - `--keyring-backend`, `test`, - `-y`, - ).CombinedOutput() - - 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) -} - type voteGovProposalAction struct { Chain ChainID From []ValidatorID @@ -586,7 +513,7 @@ func (tr *TestConfig) startConsumerChain( Chain: action.ConsumerChain, Validators: action.Validators, GenesisChanges: consumerGenesis, - SkipGentx: true, + IsConsumer: true, }, verbose) } @@ -718,8 +645,9 @@ func (tr TestConfig) startChangeover( } type addChainToRelayerAction struct { - Chain ChainID - Validator ValidatorID + Chain ChainID + Validator ValidatorID + IsConsumer bool } const hermesChainConfigTemplate = ` @@ -736,7 +664,8 @@ rpc_addr = "%s" rpc_timeout = "10s" store_prefix = "ibc" trusting_period = "14days" -websocket_addr = "%s" +event_source = { mode = "push", url = "%s", batch_delay = "50ms" } +ccv_consumer_chain = %v [chains.gas_price] denom = "stake" @@ -835,7 +764,7 @@ func (tr TestConfig) addChainToHermes( keyName, rpcAddr, wsAddr, - // action.consumer, + action.IsConsumer, ) bashCommand := fmt.Sprintf(`echo '%s' >> %s`, chainConfig, "/root/.hermes/config.toml") @@ -849,7 +778,15 @@ func (tr TestConfig) addChainToHermes( } // Save mnemonic to file within container - saveMnemonicCommand := fmt.Sprintf(`echo '%s' > %s`, tr.validatorConfigs[action.Validator].Mnemonic, "/root/.hermes/mnemonic.txt") + var mnemonic string + if tr.validatorConfigs[action.Validator].UseConsumerKey && action.IsConsumer { + mnemonic = tr.validatorConfigs[action.Validator].ConsumerMnemonic + } else { + mnemonic = tr.validatorConfigs[action.Validator].Mnemonic + } + + saveMnemonicCommand := fmt.Sprintf(`echo '%s' > %s`, mnemonic, "/root/.hermes/mnemonic.txt") + fmt.Println("Add to hermes", action.Validator) //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. bz, err = exec.Command("docker", "exec", tr.containerConfig.InstanceName, "bash", "-c", saveMnemonicCommand, @@ -2045,50 +1982,52 @@ func (tr TestConfig) assignConsumerPubKey(action assignConsumerPubKeyAction, ver tr.waitBlocks(ChainID("provi"), 2, 30*time.Second) } -// slashThrottleDequeueAction polls slash queue sizes until nextQueueSize is achieved -type slashThrottleDequeueAction struct { - Chain ChainID - CurrentQueueSize int - NextQueueSize int - // panic if Timeout is exceeded +// slashMeterReplenishmentAction polls the slash meter on provider until value is achieved +type slashMeterReplenishmentAction struct { + TargetValue int64 + // panic if timeout is exceeded Timeout time.Duration } -func (tr TestConfig) waitForSlashThrottleDequeue( - action slashThrottleDequeueAction, +func (tr TestConfig) waitForSlashMeterReplenishment( + action slashMeterReplenishmentAction, verbose bool, ) { timeout := time.Now().Add(action.Timeout) - initialGlobalQueueSize := int(tr.getGlobalSlashQueueSize()) + initialSlashMeter := tr.getSlashMeter() - if initialGlobalQueueSize != action.CurrentQueueSize { - panic(fmt.Sprintf("wrong initial queue size: %d - expected global queue: %d\n", initialGlobalQueueSize, action.CurrentQueueSize)) + if initialSlashMeter >= 0 { + panic(fmt.Sprintf("No need to wait for slash meter replenishment, current value: %d", initialSlashMeter)) } + for { - globalQueueSize := int(tr.getGlobalSlashQueueSize()) - chainQueueSize := int(tr.getConsumerChainPacketQueueSize(action.Chain)) + slashMeter := tr.getSlashMeter() if verbose { - fmt.Printf("waiting for packed queue size to reach: %d - current: %d\n", action.NextQueueSize, globalQueueSize) + fmt.Printf("waiting for slash meter to be replenished, current value: %d\n", slashMeter) } - // check if global queue size is equal to chain queue size - if globalQueueSize == chainQueueSize && globalQueueSize == action.NextQueueSize { //nolint:gocritic // this is the comparison that we want here. + // check if meter has reached target value + if slashMeter >= action.TargetValue { break } if time.Now().After(timeout) { - panic(fmt.Sprintf("\n\n\nwaitForSlashThrottleDequeue method has timed out after: %s\n\n", action.Timeout)) + panic(fmt.Sprintf("\n\nwaitForSlashMeterReplenishment has timed out after: %s\n\n", action.Timeout)) } - time.Sleep(500 * time.Millisecond) + tr.WaitTime(5 * time.Second) } - // wair for 2 blocks to be created - // allowing the jailing to be incorporated into voting power - tr.waitBlocks(action.Chain, 2, time.Minute) } -func uintPointer(i uint) *uint { - return &i +type waitTimeAction struct { + WaitTime time.Duration +} + +func (tr TestConfig) waitForTime( + action waitTimeAction, + verbose bool, +) { + tr.WaitTime(action.WaitTime) } // GetPathNameForGorelayer returns the name of the path between two given chains used by Gorelayer. @@ -2105,6 +2044,29 @@ func (tr TestConfig) GetPathNameForGorelayer(chainA, chainB ChainID) string { return pathName } +// Run an instance of the Hermes relayer using the "evidence" command, +// which detects evidences committed to the blocks of a consumer chain. +// Each infraction detected is reported to the provider chain using +// either a SubmitConsumerDoubleVoting or a SubmitConsumerMisbehaviour message. +type startConsumerEvidenceDetectorAction struct { + Chain ChainID +} + +func (tc TestConfig) startConsumerEvidenceDetector( + action startConsumerEvidenceDetectorAction, + verbose bool, +) { + chainConfig := tc.chainConfigs[action.Chain] + // run in detached mode so it will keep running in the background + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. + bz, err := exec.Command("docker", "exec", "-d", tc.containerConfig.InstanceName, + "hermes", "evidence", "--chain", string(chainConfig.ChainId)).CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + tc.waitBlocks("provi", 10, 2*time.Minute) +} + // 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/actions_consumer_misbehaviour.go b/tests/e2e/actions_consumer_misbehaviour.go new file mode 100644 index 0000000000..7d71d58d1d --- /dev/null +++ b/tests/e2e/actions_consumer_misbehaviour.go @@ -0,0 +1,98 @@ +package main + +import ( + "bufio" + "log" + "os/exec" + "strconv" + "time" +) + +// forkConsumerChainAction forks the consumer chain by cloning of a validator node +// Note that the chain fork is running in an different network +type forkConsumerChainAction struct { + ConsumerChain ChainID + ProviderChain ChainID + Validator ValidatorID + 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, + string(action.Validator), string(action.ConsumerChain), + tc.chainConfigs[action.ConsumerChain].IpPrefix, + tc.chainConfigs[action.ProviderChain].IpPrefix, + valCfg.Mnemonic, + action.RelayerConfig, + ) + + if verbose { + log.Println("forkConsumerChain - reconfigure node cmd:", configureNodeCmd.String()) + } + + 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) + + for scanner.Scan() { + out := scanner.Text() + if verbose { + log.Println("fork consumer validator : " + out) + } + if out == done { + break + } + } + if err := scanner.Err(); err != nil { + log.Fatal(err) + } + + time.Sleep(5 * time.Second) +} + +type updateLightClientAction struct { + Chain ChainID + HostChain ChainID + RelayerConfig string + ClientID string +} + +func (tc TestConfig) updateLightClient( + action updateLightClientAction, + verbose bool, +) { + // retrieve a trusted height of the consumer light client + trustedHeight := tc.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", + "--config", action.RelayerConfig, + "update", + "client", + "--client", action.ClientID, + "--host-chain", string(action.HostChain), + "--trusted-height", strconv.Itoa(int(trustedHeight.RevisionHeight)), + ) + if verbose { + log.Println("updateLightClientAction cmd:", cmd.String()) + } + + bz, err := cmd.CombinedOutput() + if err != nil { + log.Fatal(err, "\n", string(bz)) + } + + tc.waitBlocks(action.HostChain, 5, 30*time.Second) +} diff --git a/tests/e2e/config.go b/tests/e2e/config.go index 0a164c2cec..311ee67c89 100644 --- a/tests/e2e/config.go +++ b/tests/e2e/config.go @@ -186,7 +186,8 @@ func SlashThrottleTestConfig() TestConfig { ".app_state.slashing.params.signed_blocks_window = \"15\" | " + ".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.slashing.params.slash_fraction_downtime = \"0.010000000000000000\" | " + + ".app_state.ccvconsumer.params.retry_delay_period = \"30s\"", }, }, tendermintConfigOverride: `s/timeout_commit = "5s"/timeout_commit = "1s"/;` + @@ -243,11 +244,12 @@ func DefaultTestConfig() TestConfig { func DemocracyTestConfig(allowReward bool) TestConfig { consumerGenChanges := ".app_state.ccvconsumer.params.blocks_per_distribution_transmission = \"20\" | " + - ".app_state.gov.voting_params.voting_period = \"10s\" | " + + ".app_state.gov.params.voting_period = \"10s\" | " + ".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.slashing.params.slash_fraction_downtime = \"0.010000000000000000\" | " + + ".app_state.transfer.params.send_enabled = false" if allowReward { // This allows the consumer chain to send rewards in the stake denom @@ -395,6 +397,92 @@ func ChangeoverTestConfig() TestConfig { return tr } +func ConsumerMisbehaviourTestConfig() TestConfig { + tc := TestConfig{ + name: "consumer-misbehaviour", + containerConfig: ContainerConfig{ + ContainerName: "interchain-security-container", + InstanceName: "interchain-security-instance", + CcvVersion: "1", + Now: time.Now(), + }, + validatorConfigs: 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", + DelAddress: "cosmos19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddwhu7lm", + ValoperAddress: "cosmosvaloper19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddtrgtng", + ValconsAddress: "cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq", + PrivValidatorKey: `{"address":"06C0F3E47CC5C748269088DC2F36411D3AAA27C6","pub_key":{"type":"tendermint/PubKeyEd25519","value":"RrclQz9bIhkIy/gfL485g3PYMeiIku4qeo495787X10="},"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"uX+ZpDMg89a6gtqs/+MQpCTSqlkZ0nJQJOhLlCJvwvdGtyVDP1siGQjL+B8vjzmDc9gx6IiS7ip6jj3nvztfXQ=="}}`, + NodeKey: `{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"fjw4/DAhyRPnwKgXns5SV7QfswRSXMWJpHS7TyULDmJ8ofUc5poQP8dgr8bZRbCV5RV8cPqDq3FPdqwpmUbmdA=="}}`, + IpSuffix: "4", + + // consumer chain assigned key + ConsumerMnemonic: "exile install vapor thing little toss immune notable lounge december final easy strike title end program interest quote cloth forget forward job october twenty", + ConsumerDelAddress: "cosmos1eeeggku6dzk3mv7wph3zq035rhtd890sjswszd", + ConsumerValoperAddress: "cosmosvaloper1eeeggku6dzk3mv7wph3zq035rhtd890shy69w7", + ConsumerValconsAddress: "cosmosvalcons1muys5jyqk4xd27e208nym85kn0t4zjcfeu63fe", + ConsumerValPubKey: `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"ujY14AgopV907IYgPAk/5x8c9267S4fQf89nyeCPTes="}`, + ConsumerPrivValidatorKey: `{"address":"DF090A4880B54CD57B2A79E64D9E969BD7514B09","pub_key":{"type":"tendermint/PubKeyEd25519","value":"ujY14AgopV907IYgPAk/5x8c9267S4fQf89nyeCPTes="},"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"TRJgf7lkTjs/sj43pyweEOanyV7H7fhnVivOi0A4yjW6NjXgCCilX3TshiA8CT/nHxz3brtLh9B/z2fJ4I9N6w=="}}`, + ConsumerNodeKey: `{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"F966RL9pi20aXRzEBe4D0xRQJtZt696Xxz44XUON52cFc83FMn1WXJbP6arvA2JPyn2LA3DLKCFHSgALrCGXGA=="}}`, + UseConsumerKey: true, + }, + ValidatorID("bob"): { + Mnemonic: "glass trip produce surprise diamond spin excess gaze wash drum human solve dress minor artefact canoe hard ivory orange dinner hybrid moral potato jewel", + DelAddress: "cosmos1dkas8mu4kyhl5jrh4nzvm65qz588hy9qcz08la", + ValoperAddress: "cosmosvaloper1dkas8mu4kyhl5jrh4nzvm65qz588hy9qakmjnw", + ValconsAddress: "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39", + PrivValidatorKey: `{"address":"99BD3A72EF12CD024E7584B3AC900AE3743C6ADF","pub_key":{"type":"tendermint/PubKeyEd25519","value":"mAN6RXYxSM4MNGSIriYiS7pHuwAcOHDQAy9/wnlSzOI="},"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"QePcwfWtOavNK7pBJrtoLMzarHKn6iBWfWPFeyV+IdmYA3pFdjFIzgw0ZIiuJiJLuke7ABw4cNADL3/CeVLM4g=="}}`, + NodeKey: `{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"TQ4vHcO/vKdzGtWpelkX53WdMQd4kTsWGFrdcatdXFvWyO215Rewn5IRP0FszPLWr2DqPzmuH8WvxYGk5aeOXw=="}}`, + IpSuffix: "5", + + // consumer chain assigned key + ConsumerMnemonic: "grunt list hour endless observe better spoil penalty lab duck only layer vague fantasy satoshi record demise topple space shaft solar practice donor sphere", + ConsumerDelAddress: "cosmos1q90l6j6lzzgt460ehjj56azknlt5yrd4s38n97", + ConsumerValoperAddress: "cosmosvaloper1q90l6j6lzzgt460ehjj56azknlt5yrd449nxfd", + ConsumerValconsAddress: "cosmosvalcons1uuec3cjxajv5te08p220usrjhkfhg9wyvqn0tm", + ConsumerValPubKey: `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"QlG+iYe6AyYpvY1z9RNJKCVlH14Q/qSz4EjGdGCru3o="}`, + ConsumerPrivValidatorKey: `{"address":"E73388E246EC9945E5E70A94FE4072BD937415C4","pub_key":{"type":"tendermint/PubKeyEd25519","value":"QlG+iYe6AyYpvY1z9RNJKCVlH14Q/qSz4EjGdGCru3o="},"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"OFR4w+FC6EMw5fAGTrHVexyPrjzQ7QfqgZOMgVf0izlCUb6Jh7oDJim9jXP1E0koJWUfXhD+pLPgSMZ0YKu7eg=="}}`, + ConsumerNodeKey: `{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"uhPCqnL2KE8m/8OFNLQ5bN3CJr6mds+xfBi0E4umT/s2uWiJhet+vbYx88DHSdof3gGFNTIzAIxSppscBKX96w=="}}`, + UseConsumerKey: false, + }, + }, + chainConfigs: map[ChainID]ChainConfig{ + ChainID("provi"): { + ChainId: ChainID("provi"), + 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\"", + }, + ChainID("consu"): { + ChainId: ChainID("consu"), + 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 = \"15\" | " + + ".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\"", + }, + }, + tendermintConfigOverride: `s/timeout_commit = "5s"/timeout_commit = "1s"/;` + + `s/peer_gossip_sleep_duration = "100ms"/peer_gossip_sleep_duration = "50ms"/;` + + // Required to start consumer chain by running a single big validator + `s/block_sync = true/block_sync = false/;`, + } + tc.Initialize() + return tc +} + func (s *TestConfig) SetDockerConfig(localSdkPath string, useGaia bool, gaiaTag string) { if localSdkPath != "" { fmt.Println("USING LOCAL SDK", localSdkPath) @@ -417,7 +505,7 @@ func (s *TestConfig) SetRelayerConfig(useRly bool) { } // validateStringLiterals enforces that configs follow the constraints -// necessary to to execute the tests +// necessary to execute the tests // // Note: Network interfaces (name of virtual ethernet interfaces for ip link) // within the container will be named as "$CHAIN_ID-$VAL_ID-out" etc. @@ -425,7 +513,6 @@ func (s *TestConfig) SetRelayerConfig(useRly bool) { // used as a validatorID or chainID needs to be 5 char or less. func (s *TestConfig) validateStringLiterals() { for valID, valConfig := range s.validatorConfigs { - if len(valID) > 5 { panic("validator id string literal must be 5 char or less") } diff --git a/tests/e2e/json_utils.go b/tests/e2e/json_utils.go index 692c34a14f..3155bba069 100644 --- a/tests/e2e/json_utils.go +++ b/tests/e2e/json_utils.go @@ -95,12 +95,6 @@ func UnmarshalMapToActionType(rawAction json.RawMessage, actionTypeString string if err == nil { return a, nil } - case "main.submitEquivocationProposalAction": - var a submitEquivocationProposalAction - err := json.Unmarshal(rawAction, &a) - if err == nil { - return a, nil - } case "main.submitParamChangeLegacyProposalAction": var a submitParamChangeLegacyProposalAction err := json.Unmarshal(rawAction, &a) @@ -221,8 +215,14 @@ func UnmarshalMapToActionType(rawAction json.RawMessage, actionTypeString string if err == nil { return a, nil } - case "main.slashThrottleDequeueAction": - var a slashThrottleDequeueAction + case "main.slashMeterReplenishmentAction": + var a slashMeterReplenishmentAction + err := json.Unmarshal(rawAction, &a) + if err == nil { + return a, nil + } + case "main.waitTimeAction": + var a waitTimeAction err := json.Unmarshal(rawAction, &a) if err == nil { return a, nil @@ -275,6 +275,24 @@ func UnmarshalMapToActionType(rawAction json.RawMessage, actionTypeString string if err == nil { return a, nil } + case "main.forkConsumerChainAction": + var a forkConsumerChainAction + err := json.Unmarshal(rawAction, &a) + if err == nil { + return a, nil + } + case "main.startConsumerEvidenceDetectorAction": + var a startConsumerEvidenceDetectorAction + err := json.Unmarshal(rawAction, &a) + if err == nil { + return a, nil + } + case "main.updateLightClientAction": + var a updateLightClientAction + err := json.Unmarshal(rawAction, &a) + if err == nil { + return a, nil + } default: return nil, fmt.Errorf("unknown action type: %s", actionTypeString) } @@ -354,12 +372,6 @@ func UnmarshalProposalWithType(inputMap json.RawMessage, proposalType string) (P if err == nil { return prop, nil } - case "main.EquivocationProposal": - prop := EquivocationProposal{} - err := json.Unmarshal(inputMap, &prop) - if err == nil { - return prop, nil - } case "main.ParamsProposal": prop := ParamsProposal{} err := json.Unmarshal(inputMap, &prop) diff --git a/tests/e2e/main.go b/tests/e2e/main.go index 87c617be18..7261dd2ea6 100644 --- a/tests/e2e/main.go +++ b/tests/e2e/main.go @@ -54,12 +54,14 @@ var ( // map the test config names to their structs to allow for easy selection of test configs, // and also to programatically set parameters, i.e. see DemocracyTestConfig testConfigs = map[string]TestConfig{ - "default": DefaultTestConfig(), - "changeover": ChangeoverTestConfig(), - "democracy": DemocracyTestConfig(false), - "democracy-reward": DemocracyTestConfig(true), - "slash-throttle": SlashThrottleTestConfig(), - "multiconsumer": MultiConsumerTestConfig(), + "default": DefaultTestConfig(), + "changeover": ChangeoverTestConfig(), + "democracy": DemocracyTestConfig(false), + "democracy-reward": DemocracyTestConfig(true), + "slash-throttle": SlashThrottleTestConfig(), + "multiconsumer": MultiConsumerTestConfig(), + "consumer-misbehaviour": ConsumerMisbehaviourTestConfig(), + "consumer-double-sign": DefaultTestConfig(), } ) @@ -114,6 +116,18 @@ var stepChoices = map[string]StepChoice{ description: "multi consumer tests", testConfig: MultiConsumerTestConfig(), }, + "consumer-misbehaviour": { + name: "consumer-misbehaviour", + steps: consumerMisbehaviourSteps, + description: "consumer light client misbehaviour tests", + testConfig: ConsumerMisbehaviourTestConfig(), + }, + "consumer-double-sign": { + name: "consumer-double-sign", + steps: consumerDoubleSignSteps, + description: "consumer double signing tests", + testConfig: DefaultTestConfig(), + }, } func executeTests(tests []testStepsWithConfig) (err error) { @@ -173,8 +187,12 @@ func getTestFileUsageString() string { // Test runner selection builder.WriteString("Test runner selection:\nSelection of test runners to be executed:\n") + testConfigSet := map[string]struct{}{} for _, testConfig := range testConfigs { - builder.WriteString(fmt.Sprintf("- %s\n", testConfig.name)) + if _, ok := testConfigSet[testConfig.name]; !ok { + builder.WriteString(fmt.Sprintf("- %s\n", testConfig.name)) + testConfigSet[testConfig.name] = struct{}{} + } } builder.WriteString("\n") @@ -212,7 +230,8 @@ func getTestCases(selectedPredefinedTests, selectedTestFiles TestSet) (tests []t if len(selectedPredefinedTests) == 0 && len(selectedTestFiles) == 0 { selectedPredefinedTests = TestSet{ "changeover", "happy-path", - "democracy-reward", "democracy", "slash-throttle", + "democracy-reward", "democracy", + "slash-throttle", "consumer-double-sign", "consumer-misbehaviour", } if includeMultiConsumer != nil && *includeMultiConsumer { selectedPredefinedTests = append(selectedPredefinedTests, "multiconsumer") @@ -327,8 +346,6 @@ func (tr *TestConfig) runStep(step Step, verbose bool) { tr.submitConsumerAdditionProposal(action, verbose) case submitConsumerRemovalProposalAction: tr.submitConsumerRemovalProposal(action, verbose) - case submitEquivocationProposalAction: - tr.submitEquivocationProposal(action, verbose) case submitParamChangeLegacyProposalAction: tr.submitParamChangeProposal(action, verbose) case voteGovProposalAction: @@ -373,10 +390,18 @@ func (tr *TestConfig) runStep(step Step, verbose bool) { tr.registerRepresentative(action, verbose) case assignConsumerPubKeyAction: tr.assignConsumerPubKey(action, verbose) - case slashThrottleDequeueAction: - tr.waitForSlashThrottleDequeue(action, verbose) + case slashMeterReplenishmentAction: + tr.waitForSlashMeterReplenishment(action, verbose) + case waitTimeAction: + tr.waitForTime(action, verbose) case startRelayerAction: tr.startRelayer(action, verbose) + case forkConsumerChainAction: + tr.forkConsumerChain(action, verbose) + case updateLightClientAction: + tr.updateLightClient(action, verbose) + case startConsumerEvidenceDetectorAction: + tr.startConsumerEvidenceDetector(action, verbose) case submitChangeRewardDenomsProposalAction: tr.submitChangeRewardDenomsProposal(action, verbose) default: diff --git a/tests/e2e/state.go b/tests/e2e/state.go index 0febed41f7..563ce1ff30 100644 --- a/tests/e2e/state.go +++ b/tests/e2e/state.go @@ -1,6 +1,7 @@ package main import ( + "bufio" "fmt" "log" "os/exec" @@ -19,6 +20,7 @@ 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 Params *[]Param @@ -26,9 +28,9 @@ type ChainState struct { ConsumerChains *map[ChainID]bool AssignedKeys *map[ValidatorID]string ProviderKeys *map[ValidatorID]string // validatorID: validator provider key - ConsumerChainQueueSizes *map[ChainID]uint - GlobalSlashQueueSize *uint + ConsumerPendingPacketQueueSize *uint // Only relevant to consumer chains RegisteredConsumerRewardDenoms *[]string + ClientsFrozenHeights *map[string]clienttypes.Height } type Proposal interface { @@ -73,16 +75,6 @@ type ConsumerRemovalProposal struct { func (p ConsumerRemovalProposal) isProposal() {} -type EquivocationProposal struct { - Height uint - Power uint - ConsensusAddress string - Deposit uint - Status string -} - -func (p EquivocationProposal) isProposal() {} - type Rewards struct { IsRewarded map[ValidatorID]bool // if true it will calculate if the validator/delegator is rewarded between 2 successive blocks, @@ -132,6 +124,11 @@ func (tr TestConfig) getChainState(chain ChainID, modelState ChainState) ChainSt chainState.Proposals = &proposals } + if modelState.ProposedConsumerChains != nil { + proposedConsumerChains := tr.getProposedConsumerChains(chain) + chainState.ProposedConsumerChains = &proposedConsumerChains + } + if modelState.ValPowers != nil { tr.waitBlocks(chain, 1, 10*time.Second) powers := tr.getValPowers(chain, *modelState.ValPowers) @@ -168,22 +165,22 @@ func (tr TestConfig) getChainState(chain ChainID, modelState ChainState) ChainSt chainState.ProviderKeys = &providerKeys } - if modelState.GlobalSlashQueueSize != nil { - globalQueueSize := tr.getGlobalSlashQueueSize() - chainState.GlobalSlashQueueSize = &globalQueueSize + if modelState.RegisteredConsumerRewardDenoms != nil { + registeredConsumerRewardDenoms := tr.getRegisteredConsumerRewardDenoms(chain) + chainState.RegisteredConsumerRewardDenoms = ®isteredConsumerRewardDenoms } - if modelState.ConsumerChainQueueSizes != nil { - consumerChainQueueSizes := map[ChainID]uint{} - for c := range *modelState.ConsumerChainQueueSizes { - consumerChainQueueSizes[c] = tr.getConsumerChainPacketQueueSize(c) + if modelState.ClientsFrozenHeights != nil { + chainClientsFrozenHeights := map[string]clienttypes.Height{} + for id := range *modelState.ClientsFrozenHeights { + chainClientsFrozenHeights[id] = tr.getClientFrozenHeight(chain, id) } - chainState.ConsumerChainQueueSizes = &consumerChainQueueSizes + chainState.ClientsFrozenHeights = &chainClientsFrozenHeights } - if modelState.RegisteredConsumerRewardDenoms != nil { - registeredConsumerRewardDenoms := tr.getRegisteredConsumerRewardDenoms(chain) - chainState.RegisteredConsumerRewardDenoms = ®isteredConsumerRewardDenoms + if modelState.ConsumerPendingPacketQueueSize != nil { + pendingPacketQueueSize := tr.getPendingPacketQueueSize(chain) + chainState.ConsumerPendingPacketQueueSize = &pendingPacketQueueSize } if *verbose { @@ -323,6 +320,7 @@ func (tr TestConfig) getReward(chain ChainID, validator ValidatorID, blockHeight if chain != ChainID("provi") && tr.validatorConfigs[validator].UseConsumerKey { delAddresss = tr.validatorConfigs[validator].ConsumerDelAddress } + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. bz, err := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, @@ -459,16 +457,6 @@ func (tr TestConfig) getProposal(chain ChainID, proposal uint) Proposal { Chain: chain, StopTime: int(stopTime.Milliseconds()), } - - case "/interchain_security.ccv.provider.v1.EquivocationProposal": - return EquivocationProposal{ - Deposit: uint(deposit), - Status: status, - Height: uint(gjson.Get(string(bz), `messages.0.content.equivocations.0.height`).Uint()), - Power: uint(gjson.Get(string(bz), `messages.0.content.equivocations.0.power`).Uint()), - ConsensusAddress: gjson.Get(string(bz), `messages.0.content.equivocations.0.consensus_address`).String(), - } - case "/cosmos.params.v1beta1.ParameterChangeProposal": return ParamsProposal{ Deposit: uint(deposit), @@ -667,9 +655,10 @@ func (tr TestConfig) getProviderAddressFromConsumer(consumerChain ChainID, valid return addr } -func (tr TestConfig) getGlobalSlashQueueSize() uint { +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, + cmd := exec.Command("docker", "exec", + tr.containerConfig.InstanceName, tr.chainConfigs[ChainID("provi")].BinaryName, "query", "provider", "throttle-state", `--node`, tr.getQueryNode(ChainID("provi")), @@ -680,17 +669,16 @@ func (tr TestConfig) getGlobalSlashQueueSize() uint { log.Fatal(err, "\n", string(bz)) } - packets := gjson.Get(string(bz), "packets").Array() - return uint(len(packets)) + slashMeter := gjson.Get(string(bz), "slash_meter") + return slashMeter.Int() } -func (tr TestConfig) getConsumerChainPacketQueueSize(consumerChain ChainID) uint { +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[ChainID("provi")].BinaryName, + cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[chain].BinaryName, - "query", "provider", "throttled-consumer-packet-data", - string(consumerChain), - `--node`, tr.getQueryNode(ChainID("provi")), + "query", "provider", "registered-consumer-reward-denoms", + `--node`, tr.getQueryNode(chain), `-o`, `json`, ) bz, err := cmd.CombinedOutput() @@ -698,15 +686,20 @@ func (tr TestConfig) getConsumerChainPacketQueueSize(consumerChain ChainID) uint log.Fatal(err, "\n", string(bz)) } - size := gjson.Get(string(bz), "size").Uint() - return uint(size) + 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 TestConfig) getRegisteredConsumerRewardDenoms(chain ChainID) []string { +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, - "query", "provider", "registered-consumer-reward-denoms", + "query", "ccvconsumer", "throttle-state", `--node`, tr.getQueryNode(chain), `-o`, `json`, ) @@ -715,13 +708,12 @@ func (tr TestConfig) getRegisteredConsumerRewardDenoms(chain ChainID) []string { 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() + if !gjson.ValidBytes(bz) { + panic("invalid json response from query ccvconsumer throttle-state: " + string(bz)) } - return rewardDenoms + packetData := gjson.Get(string(bz), "packet_data_queue").Array() + return uint(len(packetData)) } func (tr TestConfig) getValidatorNode(chain ChainID, validator ValidatorID) string { @@ -772,3 +764,106 @@ func (tr TestConfig) curlJsonRPCRequest(method, params, address string) { verbosity := false 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 (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, + "query", "ibc", "client", "state", clientID, + `--node`, tc.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 clienttypes.Height{RevisionHeight: uint64(revHeight), RevisionNumber: uint64(revNumber)} +} + +func (tc TestConfig) 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", + "--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 clienttypes.Height{RevisionHeight: uint64(revHeight), RevisionNumber: 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, + "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 +} + +func uintPtr(i uint) *uint { + return &i +} diff --git a/tests/e2e/state_rapid_test.go b/tests/e2e/state_rapid_test.go index 313e4a68ba..3192662d27 100644 --- a/tests/e2e/state_rapid_test.go +++ b/tests/e2e/state_rapid_test.go @@ -45,8 +45,7 @@ func GetChainStateGen() *rapid.Generator[ChainState] { consumerChains := GetConsumerChainsGen().Draw(t, "ConsumerChains") assignedKeys := GetAssignedKeysGen().Draw(t, "AssignedKeys") providerKeys := GetProviderKeysGen().Draw(t, "ProviderKeys") - consumerChainQueueSizes := GetConsumerChainQueueSizesGen().Draw(t, "ConsumerChainQueueSizes") - globalSlashQueueSize := rapid.Uint().Draw(t, "GlobalSlashQueueSize") + consumerPacketQueueSize := GetConsumerChainQueueSizesGen().Draw(t, "ConsumerChainQueueSizes") registeredConsumerRewardDenoms := GetRegisteredConsumerRewardDenomsGen().Draw(t, "RegisteredConsumerRewardDenoms") return ChainState{ @@ -59,8 +58,7 @@ func GetChainStateGen() *rapid.Generator[ChainState] { ConsumerChains: &consumerChains, AssignedKeys: &assignedKeys, ProviderKeys: &providerKeys, - ConsumerChainQueueSizes: &consumerChainQueueSizes, - GlobalSlashQueueSize: &globalSlashQueueSize, + ConsumerPendingPacketQueueSize: &consumerPacketQueueSize, RegisteredConsumerRewardDenoms: ®isteredConsumerRewardDenoms, } }) @@ -72,9 +70,9 @@ func GetRegisteredConsumerRewardDenomsGen() *rapid.Generator[[]string] { }) } -func GetConsumerChainQueueSizesGen() *rapid.Generator[map[ChainID]uint] { - return rapid.Custom(func(t *rapid.T) map[ChainID]uint { - return rapid.MapOf(GetChainIDGen(), rapid.Uint()).Draw(t, "ConsumerChainQueueSizes") +func GetConsumerChainQueueSizesGen() *rapid.Generator[uint] { + return rapid.Custom(func(t *rapid.T) uint { + return rapid.Uint().Draw(t, "ConsumerChainQueueSizes") }) } @@ -174,7 +172,6 @@ func GetProposalGen() *rapid.Generator[Proposal] { gen := rapid.OneOf( GetConsumerAdditionProposalGen().AsAny(), GetConsumerRemovalProposalGen().AsAny(), - GetEquivocationProposalGen().AsAny(), GetTextProposalGen().AsAny(), GetParamsProposalGen().AsAny(), ) @@ -205,18 +202,6 @@ func GetConsumerRemovalProposalGen() *rapid.Generator[ConsumerRemovalProposal] { }) } -func GetEquivocationProposalGen() *rapid.Generator[EquivocationProposal] { - return rapid.Custom(func(t *rapid.T) EquivocationProposal { - return EquivocationProposal{ - Power: rapid.Uint().Draw(t, "Power"), - Height: rapid.Uint().Draw(t, "Height"), - ConsensusAddress: rapid.String().Draw(t, "ConesnsuAddress"), - Deposit: rapid.Uint().Draw(t, "Deposit"), - Status: rapid.String().Draw(t, "Status"), - } - }) -} - func GetTextProposalGen() *rapid.Generator[TextProposal] { return rapid.Custom(func(t *rapid.T) TextProposal { return TextProposal{ diff --git a/tests/e2e/steps.go b/tests/e2e/steps.go index 21db55e3b7..783d976a3a 100644 --- a/tests/e2e/steps.go +++ b/tests/e2e/steps.go @@ -23,12 +23,10 @@ var happyPathSteps = concatSteps( stepsDowntimeWithOptOut("consu"), stepsRedelegate("consu"), stepsDowntime("consu"), - stepsRejectEquivocationProposal("consu", 2), // prop to tombstone bob is rejected - stepsDoubleSignOnProviderAndConsumer("consu"), // carol double signs on provider, bob double signs on consumer - stepsSubmitEquivocationProposal("consu", 2), // now prop to tombstone bob is submitted and accepted + stepsDoubleSignOnProvider("consu"), // carol double signs on provider 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 shortHappyPathSteps = concatSteps( @@ -37,12 +35,10 @@ var shortHappyPathSteps = concatSteps( stepsUnbond("consu"), stepsRedelegateShort("consu"), stepsDowntime("consu"), - stepsRejectEquivocationProposal("consu", 2), // prop to tombstone bob is rejected - stepsDoubleSignOnProviderAndConsumer("consu"), // carol double signs on provider, bob double signs on consumer - stepsSubmitEquivocationProposal("consu", 2), // now prop to tombstone bob is submitted and accepted + stepsDoubleSignOnProvider("consu"), // carol double signs on provider 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 lightClientAttackSteps = concatSteps( @@ -51,9 +47,7 @@ var lightClientAttackSteps = concatSteps( stepsUnbond("consu"), stepsRedelegateShort("consu"), stepsDowntime("consu"), - stepsRejectEquivocationProposal("consu", 2), // prop to tombstone bob is rejected stepsLightClientAttackOnProviderAndConsumer("consu"), // carol double signs on provider, bob double signs on consumer - stepsSubmitEquivocationProposal("consu", 2), // now prop to tombstone bob is submitted and accepted stepsStartRelayer(), stepsConsumerRemovalPropNotPassing("consu", 3), // submit removal prop but vote no on it - chain should stay stepsStopChain("consu", 4), // stop chain @@ -106,3 +100,17 @@ var changeoverSteps = concatSteps( stepsPostChangeoverDelegate("sover"), ) + +var consumerMisbehaviourSteps = concatSteps( + // start provider and consumer chain + stepsStartChainsWithSoftOptOut("consu"), + // make a consumer validator to misbehave and get jailed + stepsCauseConsumerMisbehaviour("consu"), +) + +var consumerDoubleSignSteps = concatSteps( + // start provider and consumer chain + stepsStartChains([]string{"consu"}, false), + // make a consumer validator double sign and get jailed + stepsCauseDoubleSignOnConsumer("consu", "provi"), +) diff --git a/tests/e2e/steps_consumer_misbehaviour.go b/tests/e2e/steps_consumer_misbehaviour.go new file mode 100644 index 0000000000..01d05f658d --- /dev/null +++ b/tests/e2e/steps_consumer_misbehaviour.go @@ -0,0 +1,287 @@ +package main + +import ( + clienttypes "github.com/cosmos/ibc-go/v7/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 { + s := []Step{ + { + // Create a provider chain with two validators, where one validator holds 96% of the voting power + // and the other validator holds 4% of the voting power. + Action: StartChainAction{ + Chain: ChainID("provi"), + Validators: []StartChainValidator{ + {Id: ValidatorID("alice"), Stake: 500000000, Allocation: 10000000000}, + {Id: ValidatorID("bob"), Stake: 20000000, Allocation: 10000000000}, + }, + }, + State: State{ + ChainID("provi"): ChainState{ + ValBalances: &map[ValidatorID]uint{ + ValidatorID("alice"): 9500000000, + ValidatorID("bob"): 9980000000, + }, + }, + }, + }, + { + Action: submitConsumerAdditionProposalAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + Deposit: 10000001, + ConsumerChain: ChainID(consumerName), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + }, + State: State{ + ChainID("provi"): ChainState{ + ValBalances: &map[ValidatorID]uint{ + ValidatorID("alice"): 9489999999, + ValidatorID("bob"): 9980000000, + }, + Proposals: &map[uint]Proposal{ + 1: ConsumerAdditionProposal{ + Deposit: 10000001, + Chain: ChainID(consumerName), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: "PROPOSAL_STATUS_VOTING_PERIOD", + }, + }, + }, + }, + }, + // add a consumer key before the chain starts + // the key will be present in consumer genesis initial_val_set + { + Action: assignConsumerPubKeyAction{ + Chain: ChainID(consumerName), + Validator: ValidatorID("alice"), + ConsumerPubkey: `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"ujY14AgopV907IYgPAk/5x8c9267S4fQf89nyeCPTes="}`, + // consumer chain has not started + // we don't need to reconfigure the node + // since it will start with consumer key + ReconfigureNode: false, + }, + State: State{ + ChainID(consumerName): ChainState{ + AssignedKeys: &map[ValidatorID]string{ + ValidatorID("alice"): "cosmosvalcons1muys5jyqk4xd27e208nym85kn0t4zjcfeu63fe", + }, + ProviderKeys: &map[ValidatorID]string{ + ValidatorID("alice"): "cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq", + }, + }, + }, + }, + { + 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(consumerName), + SpawnTime: 0, + InitialHeight: clienttypes.Height{RevisionNumber: 0, RevisionHeight: 1}, + Status: "PROPOSAL_STATUS_PASSED", + }, + }, + ValBalances: &map[ValidatorID]uint{ + ValidatorID("alice"): 9500000000, + ValidatorID("bob"): 9980000000, + }, + }, + }, + }, + { + // 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{ + ValBalances: &map[ValidatorID]uint{ + ValidatorID("alice"): 9500000000, + ValidatorID("bob"): 9980000000, + }, + }, + ChainID(consumerName): ChainState{ + ValBalances: &map[ValidatorID]uint{ + ValidatorID("alice"): 10000000000, + }, + }, + }, + }, + { + Action: addIbcConnectionAction{ + ChainA: ChainID(consumerName), + ChainB: ChainID("provi"), + ClientA: 0, + ClientB: 0, + }, + State: State{}, + }, + { + Action: addIbcChannelAction{ + ChainA: ChainID(consumerName), + ChainB: ChainID("provi"), + ConnectionA: 0, + PortA: "consumer", // TODO: check port mapping + PortB: "provider", + Order: "ordered", + }, + State: State{}, + }, + // delegate some token and relay the resulting VSC packets + // in oder to initiates the CCV channel + { + Action: delegateTokensAction{ + Chain: ChainID("provi"), + From: ValidatorID("alice"), + To: ValidatorID("alice"), + Amount: 11000000, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 511, + ValidatorID("bob"): 20, + }, + }, + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 500, + ValidatorID("bob"): 20, + }, + }, + }, + }, + { + 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"): 20, + }, + }, + }, + }, + } + + return s +} + +// stepsCauseConsumerMisbehaviour causes a ICS misbehaviour by forking a consumer chain. +func stepsCauseConsumerMisbehaviour(consumerName string) []Step { + consumerClientID := "07-tendermint-0" + forkRelayerConfig := "/root/.hermes/config_fork.toml" + return []Step{ + { + // fork the consumer chain by cloning the alice validator node + Action: forkConsumerChainAction{ + ConsumerChain: ChainID(consumerName), + ProviderChain: ChainID("provi"), + Validator: ValidatorID("alice"), + RelayerConfig: forkRelayerConfig, + }, + State: State{}, + }, + // start relayer to detect IBC misbehaviour + { + Action: startRelayerAction{}, + State: State{}, + }, + // run Hermes relayer instance to detect the ICS misbehaviour + // and jail alice on the provider + { + Action: startConsumerEvidenceDetectorAction{ + Chain: ChainID(consumerName), + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 511, + ValidatorID("bob"): 20, + }, + StakedTokens: &map[ValidatorID]uint{ + ValidatorID("alice"): 511000000, + ValidatorID("bob"): 20000000, + }, + }, + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 511, + ValidatorID("bob"): 20, + }, + }, + }, + }, + { + // update the fork consumer client to create a light client attack + // which should trigger a ICS misbehaviour message + Action: updateLightClientAction{ + Chain: ChainID(consumerName), + ClientID: consumerClientID, + HostChain: ChainID("provi"), + RelayerConfig: forkRelayerConfig, // this relayer config uses the "forked" consumer + }, + State: State{ + ChainID("provi"): ChainState{ + // alice should be jailed on the provider + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 0, + ValidatorID("bob"): 20, + }, + // "alice" should be slashed on the provider, hence representative + // power is 511000000 - 0.05 * 511000000 = 485450000 + StakedTokens: &map[ValidatorID]uint{ + ValidatorID("alice"): 485450000, + ValidatorID("bob"): 20000000, + }, + // The consumer light client should be frozen on the provider + ClientsFrozenHeights: &map[string]clienttypes.Height{ + consumerClientID: { + RevisionNumber: 0, + RevisionHeight: 1, + }, + }, + }, + ChainID(consumerName): ChainState{ + // consumer should not have learned the jailing of alice + // since its light client is frozen on the provider + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 511, + ValidatorID("bob"): 20, + }, + }, + }, + }, + } +} diff --git a/tests/e2e/steps_democracy.go b/tests/e2e/steps_democracy.go index a264f868a7..9605f8698a 100644 --- a/tests/e2e/steps_democracy.go +++ b/tests/e2e/steps_democracy.go @@ -77,6 +77,8 @@ func stepsDemocracy(consumerName string) []Step { 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, @@ -99,10 +101,21 @@ func stepsDemocracy(consumerName string) []Step { }, State: State{ ChainID(consumerName): ChainState{ + // Check that alice gets the prop deposit refunded ValBalances: &map[ValidatorID]uint{ - ValidatorID("alice"): 9889999998, + 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"}}), }, diff --git a/tests/e2e/steps_double_sign.go b/tests/e2e/steps_double_sign.go index 4d69569b29..8039098f36 100644 --- a/tests/e2e/steps_double_sign.go +++ b/tests/e2e/steps_double_sign.go @@ -1,7 +1,7 @@ package main -// Steps that make carol double sign on the provider, and bob double sign on a single consumer -func stepsDoubleSignOnProviderAndConsumer(consumerName string) []Step { +// Steps that make carol double sign on the provider, and this power change propagates to consumer chain `consumerName` +func stepsDoubleSignOnProvider(consumerName string) []Step { return []Step{ { // provider double sign @@ -52,76 +52,95 @@ func stepsDoubleSignOnProviderAndConsumer(consumerName string) []Step { }, }, }, + } +} + +// Steps that make bob double sign on the consumer +func stepsCauseDoubleSignOnConsumer(consumerName, providerName string) []Step { + return []Step{ { - // consumer double sign - // provider will only log the double sign slash - // stepsSubmitEquivocationProposal will cause the double sign slash to be executed Action: doublesignSlashAction{ - Chain: ChainID("consu"), + Chain: ChainID(consumerName), Validator: ValidatorID("bob"), }, State: State{ - ChainID("provi"): ChainState{ + ChainID(providerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 500, ValidatorID("bob"): 500, - ValidatorID("carol"): 0, + ValidatorID("carol"): 500, + }, + StakedTokens: &map[ValidatorID]uint{ + ValidatorID("alice"): 500000000, + ValidatorID("bob"): 500000000, + ValidatorID("carol"): 500000000, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, + ValidatorID("alice"): 500, ValidatorID("bob"): 500, - ValidatorID("carol"): 0, + ValidatorID("carol"): 500, }, }, }, }, + // detect the double voting infraction + // and jail and slashing of bob on the provider { - Action: relayPacketsAction{ - ChainA: ChainID("provi"), - ChainB: ChainID(consumerName), - Port: "provider", - Channel: 0, + Action: startConsumerEvidenceDetectorAction{ + Chain: ChainID(consumerName), }, State: State{ - ChainID("provi"): ChainState{ + ChainID(providerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, - ValidatorID("bob"): 500, // not tombstoned - ValidatorID("carol"): 0, + ValidatorID("alice"): 500, + ValidatorID("bob"): 0, + ValidatorID("carol"): 500, + }, + // "bob" gets slashed on the provider chain, hence representative + // power is 500000000 - 0.05 * 500000000 = 475000000 + StakedTokens: &map[ValidatorID]uint{ + ValidatorID("alice"): 500000000, + ValidatorID("bob"): 475000000, + ValidatorID("carol"): 500000000, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, - ValidatorID("bob"): 500, // not tombstoned - ValidatorID("carol"): 0, + ValidatorID("alice"): 500, + ValidatorID("bob"): 500, + ValidatorID("carol"): 500, }, }, }, }, + // consumer learns about the jailing { - // consumer learns about the double sign Action: relayPacketsAction{ - ChainA: ChainID("provi"), + ChainA: ChainID(providerName), ChainB: ChainID(consumerName), Port: "provider", Channel: 0, }, State: State{ - ChainID("provi"): ChainState{ + ChainID(providerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, - ValidatorID("bob"): 500, - ValidatorID("carol"): 0, + ValidatorID("alice"): 500, + ValidatorID("bob"): 0, + ValidatorID("carol"): 500, + }, + StakedTokens: &map[ValidatorID]uint{ + ValidatorID("alice"): 500000000, + ValidatorID("bob"): 475000000, + ValidatorID("carol"): 500000000, }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, - ValidatorID("bob"): 500, // not tombstoned - ValidatorID("carol"): 0, + ValidatorID("alice"): 500, + ValidatorID("bob"): 0, + ValidatorID("carol"): 500, }, }, }, diff --git a/tests/e2e/steps_downtime.go b/tests/e2e/steps_downtime.go index 7b4152023b..f8a610052d 100644 --- a/tests/e2e/steps_downtime.go +++ b/tests/e2e/steps_downtime.go @@ -56,7 +56,8 @@ func stepsDowntime(consumerName string) []Step { ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 509, - ValidatorID("bob"): 500, + // 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, }, }, @@ -278,7 +279,7 @@ func stepsThrottledDowntime(consumerName string) []Step { Validator: ValidatorID("bob"), }, State: State{ - // slash packet queued on consumer, but powers not affected on either chain yet + // slash packet queued for bob on consumer, but powers not affected on either chain yet ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, @@ -292,6 +293,7 @@ func stepsThrottledDowntime(consumerName string) []Step { ValidatorID("bob"): 500, ValidatorID("carol"): 500, }, + ConsumerPendingPacketQueueSize: uintPtr(1), // bob's downtime slash packet is queued }, }, }, @@ -312,11 +314,6 @@ func stepsThrottledDowntime(consumerName string) []Step { ValidatorID("bob"): 0, // bob is jailed ValidatorID("carol"): 500, }, - // no provider throttling engaged yet - GlobalSlashQueueSize: uintPointer(0), - ConsumerChainQueueSizes: &map[ChainID]uint{ - ChainID(consumerName): uint(0), - }, }, ChainID(consumerName): ChainState{ // VSC packet applying jailing is not yet relayed to consumer @@ -325,16 +322,17 @@ func stepsThrottledDowntime(consumerName string) []Step { ValidatorID("bob"): 500, ValidatorID("carol"): 500, }, + ConsumerPendingPacketQueueSize: uintPtr(0), // slash packet handled ack clears consumer queue }, }, }, + // Invoke carol downtime slash on consumer { Action: downtimeSlashAction{ Chain: ChainID(consumerName), Validator: ValidatorID("carol"), }, State: State{ - // powers not affected on either chain yet ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, @@ -343,15 +341,16 @@ func stepsThrottledDowntime(consumerName string) []Step { }, }, ChainID(consumerName): ChainState{ - // VSC packet applying jailing is not yet relayed to consumer ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, - ValidatorID("bob"): 500, + ValidatorID("bob"): 500, // VSC packet jailing bob is not yet relayed to consumer ValidatorID("carol"): 500, }, + ConsumerPendingPacketQueueSize: uintPtr(1), // carol's downtime slash packet is queued }, }, }, + // Relay slash packet to provider, and ack back to consumer { Action: relayPacketsAction{ ChainA: ChainID("provi"), @@ -364,42 +363,34 @@ func stepsThrottledDowntime(consumerName string) []Step { ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, ValidatorID("bob"): 0, - ValidatorID("carol"): 500, // not slashed due to throttling - }, - GlobalSlashQueueSize: uintPointer(1), // carol's slash request is throttled - ConsumerChainQueueSizes: &map[ChainID]uint{ - ChainID(consumerName): uint(1), + ValidatorID("carol"): 500, // slash packet for carol recv by provider, carol not slashed due to throttling }, }, ChainID(consumerName): ChainState{ ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, - ValidatorID("bob"): 0, + ValidatorID("bob"): 0, // VSC packet applying bob jailing is also relayed and recv by consumer ValidatorID("carol"): 500, }, + ConsumerPendingPacketQueueSize: uintPtr(1), // slash packet bounced ack keeps carol's downtime slash packet queued }, }, }, { - Action: slashThrottleDequeueAction{ - Chain: ChainID(consumerName), - CurrentQueueSize: 1, - NextQueueSize: 0, + Action: slashMeterReplenishmentAction{ + TargetValue: 0, // We just want slash meter to be non-negative + // Slash meter replenish fraction is set to 10%, replenish period is 20 seconds, see config.go // Meter is initially at 10%, decremented to -23% from bob being jailed. It'll then take three replenishments - // for meter to become positive again. 3*20 = 60 seconds + buffer = 80 seconds - Timeout: 80 * time.Second, + // for meter to become positive again. 3*20 = 60 seconds + buffer = 100 seconds + Timeout: 100 * time.Second, }, State: State{ ChainID("provi"): ChainState{ ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, ValidatorID("bob"): 0, - ValidatorID("carol"): 0, // Carol is jailed upon packet being handled on provider - }, - GlobalSlashQueueSize: uintPointer(0), // slash packets dequeued - ConsumerChainQueueSizes: &map[ChainID]uint{ - ChainID(consumerName): 0, + ValidatorID("carol"): 500, // Carol still not slashed, packet must be retried }, }, ChainID(consumerName): ChainState{ @@ -409,11 +400,31 @@ func stepsThrottledDowntime(consumerName string) []Step { ValidatorID("bob"): 0, ValidatorID("carol"): 500, }, + ConsumerPendingPacketQueueSize: uintPtr(1), // packet still queued }, }, }, - // A block is incremented each action, hence why VSC is committed on provider, - // and can now be relayed as packet to consumer + // Wait for retry delay period to pass. + // Retry delay period is set to 30 seconds, see config.go, + // wait this amount of time to elapse the period. + { + Action: waitTimeAction{ + WaitTime: 30 * time.Second, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 511, + ValidatorID("bob"): 0, + ValidatorID("carol"): 500, + }, + }, + ChainID(consumerName): ChainState{ + ConsumerPendingPacketQueueSize: uintPtr(1), // packet still queued + }, + }, + }, + // Relay now that retry delay period has passed, confirm provider applies jailing { Action: relayPacketsAction{ ChainA: ChainID("provi"), @@ -426,20 +437,11 @@ func stepsThrottledDowntime(consumerName string) []Step { ValPowers: &map[ValidatorID]uint{ ValidatorID("alice"): 511, ValidatorID("bob"): 0, - ValidatorID("carol"): 0, - }, - GlobalSlashQueueSize: uintPointer(0), - ConsumerChainQueueSizes: &map[ChainID]uint{ - ChainID(consumerName): 0, + ValidatorID("carol"): 0, // jailed! }, }, ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 511, - // throttled update gets to consumer - ValidatorID("bob"): 0, - ValidatorID("carol"): 0, - }, + ConsumerPendingPacketQueueSize: uintPtr(0), // relayed slash packet handled ack clears consumer queue }, }, }, diff --git a/tests/e2e/steps_light_client_attack.go b/tests/e2e/steps_light_client_attack.go index 284b3fafea..1d9f484b5c 100644 --- a/tests/e2e/steps_light_client_attack.go +++ b/tests/e2e/steps_light_client_attack.go @@ -55,7 +55,6 @@ func stepsLightClientAttackOnProviderAndConsumer(consumerName string) []Step { { // Consumer double sign // Provider will only log the double sign slash - // stepsSubmitEquivocationProposal will cause the double sign slash to be executed Action: lightClientEquivocationAttackAction{ Chain: ChainID(consumerName), Validator: ValidatorID("bob"), diff --git a/tests/e2e/steps_reward_denom.go b/tests/e2e/steps_reward_denom.go index 1a47accd07..d5b524fbd9 100644 --- a/tests/e2e/steps_reward_denom.go +++ b/tests/e2e/steps_reward_denom.go @@ -75,6 +75,8 @@ func stepsRewardDenomConsumer(consumerName string) []Step { 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, @@ -97,10 +99,21 @@ func stepsRewardDenomConsumer(consumerName string) []Step { }, State: State{ ChainID(consumerName): ChainState{ + // Check that alice gets the prop deposit refunded ValBalances: &map[ValidatorID]uint{ - ValidatorID("alice"): 9889999998, + 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"}}), }, diff --git a/tests/e2e/steps_start_chains.go b/tests/e2e/steps_start_chains.go index ace3d6c255..58a5f75162 100644 --- a/tests/e2e/steps_start_chains.go +++ b/tests/e2e/steps_start_chains.go @@ -54,6 +54,7 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint Status: "PROPOSAL_STATUS_VOTING_PERIOD", }, }, + ProposedConsumerChains: &[]string{consumerName}, }, }, }, @@ -163,6 +164,7 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint ValidatorID("bob"): 9500000000, ValidatorID("carol"): 9500000000, }, + ProposedConsumerChains: &[]string{}, }, ChainID(consumerName): ChainState{ ValBalances: &map[ValidatorID]uint{ diff --git a/tests/e2e/steps_submit_equivocation_proposal.go b/tests/e2e/steps_submit_equivocation_proposal.go deleted file mode 100644 index 243c01f04d..0000000000 --- a/tests/e2e/steps_submit_equivocation_proposal.go +++ /dev/null @@ -1,150 +0,0 @@ -package main - -import "time" - -// submits an invalid equivocation proposal which should be rejected -func stepsRejectEquivocationProposal(consumerName string, propNumber uint) []Step { - return []Step{ - { - // bob submits a proposal to slash himself - Action: submitEquivocationProposalAction{ - Chain: ChainID("consu"), - From: ValidatorID("bob"), - Deposit: 10000001, - Height: 10, - Time: time.Now(), - Power: 500, - Validator: ValidatorID("bob"), - }, - State: State{ - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, - ValidatorID("bob"): 500, - ValidatorID("carol"): 495, - }, - ValBalances: &map[ValidatorID]uint{ - ValidatorID("bob"): 9500000000, - }, - Proposals: &map[uint]Proposal{ - // proposal does not exist - propNumber: TextProposal{}, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, - ValidatorID("bob"): 500, - ValidatorID("carol"): 495, - }, - }, - }, - }, - } -} - -// submits an equivocation proposal, votes on it, and tomstones the equivocating validator -func stepsSubmitEquivocationProposal(consumerName string, propNumber uint) []Step { - s := []Step{ - { - // bob submits a proposal to slash himself - Action: submitEquivocationProposalAction{ - Chain: ChainID("consu"), - From: ValidatorID("bob"), - Deposit: 10000001, - Height: 10, - Time: time.Now(), // not sure what time in equivocations means - Power: 500, - Validator: ValidatorID("bob"), - }, - State: State{ - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, - ValidatorID("bob"): 500, - ValidatorID("carol"): 0, - }, - ValBalances: &map[ValidatorID]uint{ - ValidatorID("bob"): 9489999999, - }, - Proposals: &map[uint]Proposal{ - propNumber: EquivocationProposal{ - Deposit: 10000001, - Status: "PROPOSAL_STATUS_VOTING_PERIOD", - ConsensusAddress: "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39", - Power: 500, - Height: 10, - }, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, - ValidatorID("bob"): 500, - ValidatorID("carol"): 0, - }, - }, - }, - }, - { - Action: voteGovProposalAction{ - Chain: ChainID("provi"), - From: []ValidatorID{ValidatorID("alice"), ValidatorID("bob"), ValidatorID("carol")}, - Vote: []string{"yes", "yes", "yes"}, - PropNumber: propNumber, - }, - State: State{ - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, - ValidatorID("bob"): 0, // bob is tombstoned after proposal passes - ValidatorID("carol"): 0, - }, - Proposals: &map[uint]Proposal{ - propNumber: EquivocationProposal{ - Deposit: 10000001, - Status: "PROPOSAL_STATUS_PASSED", - ConsensusAddress: "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39", - Power: 500, - Height: 10, - }, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, - ValidatorID("bob"): 500, // slash not reflected in consumer chain - ValidatorID("carol"): 0, - }, - }, - }, - }, - { - // relay power change to consumer1 - Action: relayPacketsAction{ - ChainA: ChainID("provi"), - ChainB: ChainID(consumerName), - Port: "provider", - Channel: 0, - }, - State: State{ - ChainID("provi"): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, - ValidatorID("bob"): 0, - ValidatorID("carol"): 0, - }, - }, - ChainID(consumerName): ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, - ValidatorID("bob"): 0, // slash relayed to consumer chain - ValidatorID("carol"): 0, - }, - }, - }, - }, - } - - return s -} diff --git a/tests/e2e/testnet-scripts/fork-consumer.sh b/tests/e2e/testnet-scripts/fork-consumer.sh new file mode 100644 index 0000000000..7c12438b71 --- /dev/null +++ b/tests/e2e/testnet-scripts/fork-consumer.sh @@ -0,0 +1,114 @@ +#!/bin/bash +set -eux + +# The gaiad binary +BIN=$1 + +# the validator ID used to perform the fork +VAL_ID=$2 + +# The consumer chain ID +CHAIN_ID=$3 + +# chain's IP address prefix; $PROV_CHAIN_PREFIX, $CONS_CHAIN_PREFIX... +# see chain config for details +CONS_CHAIN_PREFIX=$4 + +PROV_CHAIN_PREFIX=$5 + +VAL_MNEMONIC=$6 + +FORK_HERMES_CONFIG=$7 + +FORK_NODE_DIR=/$CHAIN_ID/validatorfork + +# create directory for forking/double-signing node +mkdir $FORK_NODE_DIR +cp -r /$CHAIN_ID/validator$VAL_ID/* $FORK_NODE_DIR + +# remove persistent peers +rm -f $FORK_NODE_DIR/addrbook.json + +# add fork to hermes relayer +tee $FORK_HERMES_CONFIG< mnemonic.txt + +# Start the validator forking the consumer chain +# using the sybil IP allocation +ip netns exec $CHAIN_ID-sybil $BIN \ + --home $FORK_NODE_DIR \ + --address tcp://$CONS_CHAIN_PREFIX.252:26655 \ + --rpc.laddr tcp://$CONS_CHAIN_PREFIX.252:26658 \ + --grpc.address $CONS_CHAIN_PREFIX.252:9091 \ + --log_level info \ + --p2p.laddr tcp://$CONS_CHAIN_PREFIX.252:26656 \ + --grpc-web.enable=false start &> /consu/validatorfork/logs & + diff --git a/tests/e2e/testnet-scripts/hermes-config.toml b/tests/e2e/testnet-scripts/hermes-config.toml index eb8154d95b..89c1f0a0bb 100644 --- a/tests/e2e/testnet-scripts/hermes-config.toml +++ b/tests/e2e/testnet-scripts/hermes-config.toml @@ -1,2 +1,18 @@ [global] - log_level = "info" \ No newline at end of file +log_level = "debug" + +[mode] + +[mode.clients] +enabled = true +refresh = true +misbehaviour = true + +[mode.connections] +enabled = false + +[mode.channels] +enabled = false + +[mode.packets] +enabled = true \ 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 88c8455e51..e3e6b6054f 100644 --- a/tests/e2e/testnet-scripts/start-chain.sh +++ b/tests/e2e/testnet-scripts/start-chain.sh @@ -257,8 +257,12 @@ do fi done - # Remove leading comma and concat to flag - PERSISTENT_PEERS="--p2p.persistent_peers ${PERSISTENT_PEERS:1}" + + if [ "$PERSISTENT_PEERS" != "" ]; then + # Remove leading comma and concat to flag + PERSISTENT_PEERS="--p2p.persistent_peers ${PERSISTENT_PEERS:1}" + fi + ARGS="$GAIA_HOME $LISTEN_ADDRESS $RPC_ADDRESS $GRPC_ADDRESS $LOG_LEVEL $P2P_ADDRESS $ENABLE_WEBGRPC $PERSISTENT_PEERS" if [[ "$USE_COMETMOCK" == "true" ]]; then diff --git a/tests/e2e/trace_handlers_test.go b/tests/e2e/trace_handlers_test.go index 725496c51f..024daae450 100644 --- a/tests/e2e/trace_handlers_test.go +++ b/tests/e2e/trace_handlers_test.go @@ -82,6 +82,8 @@ func TestWriteExamples(t *testing.T) { "shorthappy": {shortHappyPathSteps}, "democracyRewardsSteps": {democracyRewardsSteps}, "changeover": {changeoverSteps}, + "consumer-misbehaviour": {consumerMisbehaviourSteps}, + "consumer-double-sign": {consumerDoubleSignSteps}, } dir := "tracehandler_testdata" @@ -131,7 +133,7 @@ func TestMarshalAndUnmarshalChainState(t *testing.T) { }, }, }}, - "consuemr removal proposal": {ChainState{ + "consumer removal proposal": {ChainState{ Proposals: &map[uint]Proposal{ 5: ConsumerRemovalProposal{ Deposit: 10000001, @@ -159,25 +161,6 @@ func TestMarshalAndUnmarshalChainState(t *testing.T) { 10: TextProposal{}, }, }}, - "equivocation-proposal": {ChainState{ - ValPowers: &map[ValidatorID]uint{ - ValidatorID("alice"): 509, - ValidatorID("bob"): 500, - ValidatorID("carol"): 0, - }, - ValBalances: &map[ValidatorID]uint{ - ValidatorID("bob"): 9489999999, - }, - Proposals: &map[uint]Proposal{ - 5: EquivocationProposal{ - Deposit: 10000001, - Status: "PROPOSAL_STATUS_VOTING_PERIOD", - ConsensusAddress: "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39", - Power: 500, - Height: 10, - }, - }, - }}, } for name, tc := range tests { diff --git a/tests/e2e/tracehandler_testdata/changeover.json b/tests/e2e/tracehandler_testdata/changeover.json index d973b46fe4..cafe8aa69e 100644 --- a/tests/e2e/tracehandler_testdata/changeover.json +++ b/tests/e2e/tracehandler_testdata/changeover.json @@ -24,9 +24,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -53,9 +53,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -82,7 +82,7 @@ } ], "GenesisChanges": "", - "SkipGentx": false + "IsConsumer": false }, "State": { "provi": { @@ -98,9 +98,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -144,9 +144,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -185,9 +185,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -239,9 +239,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -288,9 +288,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -346,9 +346,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "sover": { @@ -364,9 +364,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -414,9 +414,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -443,9 +443,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "sover": { @@ -461,9 +461,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -490,9 +490,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -517,9 +517,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -546,9 +546,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "sover": { @@ -564,9 +564,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -593,9 +593,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } diff --git a/tests/e2e/tracehandler_testdata/consumer-double-sign.json b/tests/e2e/tracehandler_testdata/consumer-double-sign.json new file mode 100644 index 0000000000..d6d1fc7086 --- /dev/null +++ b/tests/e2e/tracehandler_testdata/consumer-double-sign.json @@ -0,0 +1,452 @@ +[ + { + "ActionType": "main.StartChainAction", + "Action": { + "Chain": "provi", + "Validators": [ + { + "Id": "bob", + "Allocation": 10000000000, + "Stake": 500000000 + }, + { + "Id": "alice", + "Allocation": 10000000000, + "Stake": 500000000 + }, + { + "Id": "carol", + "Allocation": 10000000000, + "Stake": 500000000 + } + ], + "GenesisChanges": "", + "IsConsumer": false + }, + "State": { + "provi": { + "ValBalances": { + "alice": 9500000000, + "bob": 9500000000, + "carol": 9500000000 + }, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.submitConsumerAdditionProposalAction", + "Action": { + "PreCCV": false, + "Chain": "provi", + "From": "alice", + "Deposit": 10000001, + "ConsumerChain": "consu", + "SpawnTime": 0, + "InitialHeight": { + "revision_height": 1 + }, + "DistributionChannel": "" + }, + "State": { + "provi": { + "ValBalances": { + "alice": 9489999999, + "bob": 9500000000 + }, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": { + "1": { + "RawProposal": { + "Deposit": 10000001, + "Chain": "consu", + "SpawnTime": 0, + "InitialHeight": { + "revision_height": 1 + }, + "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + }, + "Type": "main.ConsumerAdditionProposal" + } + } + } + } + }, + { + "ActionType": "main.assignConsumerPubKeyAction", + "Action": { + "Chain": "consu", + "Validator": "carol", + "ConsumerPubkey": "{\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is=\"}", + "ReconfigureNode": false, + "ExpectError": false, + "ExpectedError": "" + }, + "State": { + "consu": { + "ValBalances": null, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": { + "carol": "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk" + }, + "ProviderKeys": { + "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" + }, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.assignConsumerPubKeyAction", + "Action": { + "Chain": "consu", + "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" + }, + "State": {} + }, + { + "ActionType": "main.assignConsumerPubKeyAction", + "Action": { + "Chain": "consu", + "Validator": "bob", + "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" + }, + "State": { + "consu": { + "ValBalances": null, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": { + "bob": "", + "carol": "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk" + }, + "ProviderKeys": { + "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" + }, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.voteGovProposalAction", + "Action": { + "Chain": "provi", + "From": [ + "alice", + "bob", + "carol" + ], + "Vote": [ + "yes", + "yes", + "yes" + ], + "PropNumber": 1 + }, + "State": { + "provi": { + "ValBalances": { + "alice": 9500000000, + "bob": 9500000000 + }, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": { + "1": { + "RawProposal": { + "Deposit": 10000001, + "Chain": "consu", + "SpawnTime": 0, + "InitialHeight": { + "revision_height": 1 + }, + "Status": "PROPOSAL_STATUS_PASSED" + }, + "Type": "main.ConsumerAdditionProposal" + } + } + } + } + }, + { + "ActionType": "main.startConsumerChainAction", + "Action": { + "ConsumerChain": "consu", + "ProviderChain": "provi", + "Validators": [ + { + "Id": "bob", + "Allocation": 10000000000, + "Stake": 500000000 + }, + { + "Id": "alice", + "Allocation": 10000000000, + "Stake": 500000000 + }, + { + "Id": "carol", + "Allocation": 10000000000, + "Stake": 500000000 + } + ], + "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" + }, + "State": { + "consu": { + "ValBalances": { + "alice": 10000000000, + "bob": 10000000000, + "carol": 10000000000 + }, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + }, + "provi": { + "ValBalances": { + "alice": 9500000000, + "bob": 9500000000, + "carol": 9500000000 + }, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.addIbcConnectionAction", + "Action": { + "ChainA": "consu", + "ChainB": "provi", + "ClientA": 0, + "ClientB": 0 + }, + "State": {} + }, + { + "ActionType": "main.addIbcChannelAction", + "Action": { + "ChainA": "consu", + "ChainB": "provi", + "ConnectionA": 0, + "PortA": "consumer", + "PortB": "provider", + "Order": "ordered", + "Version": "" + }, + "State": {} + }, + { + "ActionType": "main.doublesignSlashAction", + "Action": { + "Validator": "bob", + "Chain": "consu" + }, + "State": { + "consu": { + "ValBalances": null, + "ValPowers": { + "alice": 500, + "bob": 500, + "carol": 500 + }, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + }, + "provi": { + "ValBalances": null, + "ValPowers": { + "alice": 500, + "bob": 500, + "carol": 500 + }, + "StakedTokens": { + "alice": 500000000, + "bob": 500000000, + "carol": 500000000 + }, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.startConsumerEvidenceDetectorAction", + "Action": { + "Chain": "consu" + }, + "State": { + "consu": { + "ValBalances": null, + "ValPowers": { + "alice": 500, + "bob": 500, + "carol": 500 + }, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + }, + "provi": { + "ValBalances": null, + "ValPowers": { + "alice": 500, + "bob": 0, + "carol": 500 + }, + "StakedTokens": { + "alice": 500000000, + "bob": 475000000, + "carol": 500000000 + }, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.relayPacketsAction", + "Action": { + "ChainA": "provi", + "ChainB": "consu", + "Port": "provider", + "Channel": 0 + }, + "State": { + "consu": { + "ValBalances": null, + "ValPowers": { + "alice": 500, + "bob": 0, + "carol": 500 + }, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + }, + "provi": { + "ValBalances": null, + "ValPowers": { + "alice": 500, + "bob": 0, + "carol": 500 + }, + "StakedTokens": { + "alice": 500000000, + "bob": 475000000, + "carol": 500000000 + }, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + } + } + } +] \ No newline at end of file diff --git a/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json b/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json new file mode 100644 index 0000000000..028637934f --- /dev/null +++ b/tests/e2e/tracehandler_testdata/consumer-misbehaviour.json @@ -0,0 +1,424 @@ +[ + { + "ActionType": "main.StartChainAction", + "Action": { + "Chain": "provi", + "Validators": [ + { + "Id": "alice", + "Allocation": 10000000000, + "Stake": 500000000 + }, + { + "Id": "bob", + "Allocation": 10000000000, + "Stake": 20000000 + } + ], + "GenesisChanges": "", + "IsConsumer": false + }, + "State": { + "provi": { + "ValBalances": { + "alice": 9500000000, + "bob": 9980000000 + }, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.submitConsumerAdditionProposalAction", + "Action": { + "PreCCV": false, + "Chain": "provi", + "From": "alice", + "Deposit": 10000001, + "ConsumerChain": "consu", + "SpawnTime": 0, + "InitialHeight": { + "revision_height": 1 + }, + "DistributionChannel": "" + }, + "State": { + "provi": { + "ValBalances": { + "alice": 9489999999, + "bob": 9980000000 + }, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": { + "1": { + "RawProposal": { + "Deposit": 10000001, + "Chain": "consu", + "SpawnTime": 0, + "InitialHeight": { + "revision_height": 1 + }, + "Status": "PROPOSAL_STATUS_VOTING_PERIOD" + }, + "Type": "main.ConsumerAdditionProposal" + } + } + } + } + }, + { + "ActionType": "main.assignConsumerPubKeyAction", + "Action": { + "Chain": "consu", + "Validator": "alice", + "ConsumerPubkey": "{\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"ujY14AgopV907IYgPAk/5x8c9267S4fQf89nyeCPTes=\"}", + "ReconfigureNode": false, + "ExpectError": false, + "ExpectedError": "" + }, + "State": { + "consu": { + "ValBalances": null, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": { + "alice": "cosmosvalcons1muys5jyqk4xd27e208nym85kn0t4zjcfeu63fe" + }, + "ProviderKeys": { + "alice": "cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq" + }, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.voteGovProposalAction", + "Action": { + "Chain": "provi", + "From": [ + "alice", + "bob" + ], + "Vote": [ + "yes", + "yes" + ], + "PropNumber": 1 + }, + "State": { + "provi": { + "ValBalances": { + "alice": 9500000000, + "bob": 9980000000 + }, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": { + "1": { + "RawProposal": { + "Deposit": 10000001, + "Chain": "consu", + "SpawnTime": 0, + "InitialHeight": { + "revision_height": 1 + }, + "Status": "PROPOSAL_STATUS_PASSED" + }, + "Type": "main.ConsumerAdditionProposal" + } + } + } + } + }, + { + "ActionType": "main.startConsumerChainAction", + "Action": { + "ConsumerChain": "consu", + "ProviderChain": "provi", + "Validators": [ + { + "Id": "alice", + "Allocation": 10000000000, + "Stake": 500000000 + } + ], + "GenesisChanges": ".app_state.ccvconsumer.params.soft_opt_out_threshold = \"0.05\"" + }, + "State": { + "consu": { + "ValBalances": { + "alice": 10000000000 + }, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + }, + "provi": { + "ValBalances": { + "alice": 9500000000, + "bob": 9980000000 + }, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.addIbcConnectionAction", + "Action": { + "ChainA": "consu", + "ChainB": "provi", + "ClientA": 0, + "ClientB": 0 + }, + "State": {} + }, + { + "ActionType": "main.addIbcChannelAction", + "Action": { + "ChainA": "consu", + "ChainB": "provi", + "ConnectionA": 0, + "PortA": "consumer", + "PortB": "provider", + "Order": "ordered", + "Version": "" + }, + "State": {} + }, + { + "ActionType": "main.delegateTokensAction", + "Action": { + "Chain": "provi", + "From": "alice", + "To": "alice", + "Amount": 11000000 + }, + "State": { + "consu": { + "ValBalances": null, + "ValPowers": { + "alice": 500, + "bob": 20 + }, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + }, + "provi": { + "ValBalances": null, + "ValPowers": { + "alice": 511, + "bob": 20 + }, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.relayPacketsAction", + "Action": { + "ChainA": "provi", + "ChainB": "consu", + "Port": "provider", + "Channel": 0 + }, + "State": { + "consu": { + "ValBalances": null, + "ValPowers": { + "alice": 511, + "bob": 20 + }, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.forkConsumerChainAction", + "Action": { + "ConsumerChain": "consu", + "ProviderChain": "provi", + "Validator": "alice", + "RelayerConfig": "/root/.hermes/config_fork.toml" + }, + "State": {} + }, + { + "ActionType": "main.startRelayerAction", + "Action": {}, + "State": {} + }, + { + "ActionType": "main.startConsumerEvidenceDetectorAction", + "Action": { + "Chain": "consu" + }, + "State": { + "consu": { + "ValBalances": null, + "ValPowers": { + "alice": 511, + "bob": 20 + }, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + }, + "provi": { + "ValBalances": null, + "ValPowers": { + "alice": 511, + "bob": 20 + }, + "StakedTokens": { + "alice": 511000000, + "bob": 20000000 + }, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.updateLightClientAction", + "Action": { + "Chain": "consu", + "HostChain": "provi", + "RelayerConfig": "/root/.hermes/config_fork.toml", + "ClientID": "07-tendermint-0" + }, + "State": { + "consu": { + "ValBalances": null, + "ValPowers": { + "alice": 511, + "bob": 20 + }, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + }, + "provi": { + "ValBalances": null, + "ValPowers": { + "alice": 0, + "bob": 20 + }, + "StakedTokens": { + "alice": 485450000, + "bob": 20000000 + }, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": { + "07-tendermint-0": { + "revision_height": 1 + } + }, + "Proposals": null + } + } + } +] \ No newline at end of file diff --git a/tests/e2e/tracehandler_testdata/democracy.json b/tests/e2e/tracehandler_testdata/democracy.json index 9a435b3a0b..3a9ab84a96 100644 --- a/tests/e2e/tracehandler_testdata/democracy.json +++ b/tests/e2e/tracehandler_testdata/democracy.json @@ -1,4 +1,3 @@ - [ { "ActionType": "main.StartChainAction", @@ -22,7 +21,7 @@ } ], "GenesisChanges": "", - "SkipGentx": false + "IsConsumer": false }, "State": { "provi": { @@ -38,9 +37,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -72,9 +71,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -116,9 +115,9 @@ "ProviderKeys": { "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -160,9 +159,9 @@ "ProviderKeys": { "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -196,9 +195,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -254,9 +253,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -272,9 +271,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -338,9 +337,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -356,9 +355,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -384,9 +383,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -413,9 +412,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -441,9 +440,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -482,9 +481,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -522,9 +521,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -547,14 +546,20 @@ }, "ValPowers": null, "StakedTokens": null, - "Params": null, + "Params": [ + { + "Subspace": "transfer", + "Key": "SendEnabled", + "Value": "false" + } + ], "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -587,7 +592,7 @@ "State": { "democ": { "ValBalances": { - "alice": 9889999998, + "alice": 9899999999, "bob": 9960000001 }, "ValPowers": null, @@ -603,10 +608,21 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, - "Proposals": null + "ClientsFrozenHeights": null, + "Proposals": { + "1": { + "RawProposal": { + "Deposit": 10000001, + "Status": "PROPOSAL_STATUS_PASSED", + "Subspace": "transfer", + "Key": "SendEnabled", + "Value": "true" + }, + "Type": "main.ParamsProposal" + } + } } } }, @@ -636,9 +652,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": [], + "ClientsFrozenHeights": null, "Proposals": null } } @@ -660,9 +676,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": [], + "ClientsFrozenHeights": null, "Proposals": null } } @@ -693,11 +709,11 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": [ "ibc/3C3D7B3BE4ECC85A0E5B52A3AEC3B7DFC2AA9CA47C37821E57020D6807043BE9" ], + "ClientsFrozenHeights": null, "Proposals": null } } @@ -728,9 +744,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -755,9 +771,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -773,9 +789,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -802,9 +818,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -820,9 +836,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -849,9 +865,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -876,9 +892,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -894,9 +910,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -926,9 +942,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } diff --git a/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json b/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json index 355ff1fbb8..74df5293b9 100644 --- a/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json +++ b/tests/e2e/tracehandler_testdata/democracyRewardsSteps.json @@ -21,7 +21,7 @@ } ], "GenesisChanges": "", - "SkipGentx": false + "IsConsumer": false }, "State": { "provi": { @@ -37,9 +37,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -71,9 +71,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -115,9 +115,9 @@ "ProviderKeys": { "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -159,9 +159,9 @@ "ProviderKeys": { "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -195,9 +195,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -253,9 +253,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -271,9 +271,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -337,9 +337,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -355,9 +355,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -383,9 +383,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -412,9 +412,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -440,9 +440,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -481,9 +481,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -521,9 +521,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -546,14 +546,20 @@ }, "ValPowers": null, "StakedTokens": null, - "Params": null, + "Params": [ + { + "Subspace": "transfer", + "Key": "SendEnabled", + "Value": "false" + } + ], "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -586,7 +592,7 @@ "State": { "democ": { "ValBalances": { - "alice": 9889999998, + "alice": 9899999999, "bob": 9960000001 }, "ValPowers": null, @@ -602,10 +608,21 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, - "Proposals": null + "ClientsFrozenHeights": null, + "Proposals": { + "1": { + "RawProposal": { + "Deposit": 10000001, + "Status": "PROPOSAL_STATUS_PASSED", + "Subspace": "transfer", + "Key": "SendEnabled", + "Value": "true" + }, + "Type": "main.ParamsProposal" + } + } } } }, @@ -635,9 +652,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": [], + "ClientsFrozenHeights": null, "Proposals": null } } @@ -659,9 +676,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": [], + "ClientsFrozenHeights": null, "Proposals": null } } @@ -692,11 +709,11 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": [ "ibc/3C3D7B3BE4ECC85A0E5B52A3AEC3B7DFC2AA9CA47C37821E57020D6807043BE9" ], + "ClientsFrozenHeights": null, "Proposals": null } } @@ -727,9 +744,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -754,9 +771,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -772,9 +789,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -801,9 +818,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -819,9 +836,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -848,9 +865,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -875,9 +892,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -893,9 +910,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -925,9 +942,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } diff --git a/tests/e2e/tracehandler_testdata/happyPath.json b/tests/e2e/tracehandler_testdata/happyPath.json index f46a4e983b..7c26f5c274 100644 --- a/tests/e2e/tracehandler_testdata/happyPath.json +++ b/tests/e2e/tracehandler_testdata/happyPath.json @@ -21,7 +21,7 @@ } ], "GenesisChanges": "", - "SkipGentx": false + "IsConsumer": false }, "State": { "provi": { @@ -37,9 +37,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -71,9 +71,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -115,9 +115,9 @@ "ProviderKeys": { "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -159,9 +159,9 @@ "ProviderKeys": { "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -195,9 +195,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -253,9 +253,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -271,9 +271,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -323,9 +323,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -341,9 +341,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -369,9 +369,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -398,9 +398,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -426,9 +426,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -463,9 +463,9 @@ "bob": "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39", "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -481,9 +481,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -516,9 +516,9 @@ "bob": "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39", "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -534,9 +534,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -563,9 +563,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -581,9 +581,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -610,9 +610,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -639,9 +639,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -657,9 +657,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -686,9 +686,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -715,9 +715,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -733,9 +733,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -762,9 +762,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -792,9 +792,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -810,9 +810,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -839,9 +839,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -866,9 +866,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -884,9 +884,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -913,9 +913,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -931,9 +931,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -961,9 +961,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -979,9 +979,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1008,9 +1008,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1035,9 +1035,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1053,9 +1053,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1073,7 +1073,6 @@ "ValBalances": null, "ValPowers": { "alice": 509, - "bob": 500, "carol": 501 }, "StakedTokens": null, @@ -1082,9 +1081,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1100,9 +1099,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1129,9 +1128,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1156,9 +1155,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1174,9 +1173,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1203,9 +1202,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1230,9 +1229,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1248,9 +1247,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1277,9 +1276,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1304,9 +1303,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1322,9 +1321,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1351,72 +1350,10 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.submitEquivocationProposalAction", - "Action": { - "Chain": "consu", - "Height": 10, - "Time": "2023-09-20T18:24:51.823193+02:00", - "Power": 500, - "Validator": "bob", - "Deposit": 10000001, - "From": "bob" - }, - "State": { - "consu": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 495 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null - }, - "provi": { - "ValBalances": { - "bob": 9500000000 - }, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 495 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": { - "2": { - "RawProposal": { - "Title": "", - "Description": "", - "Deposit": 0, - "Status": "" - }, - "Type": "main.TextProposal" - } - } } } }, @@ -1440,101 +1377,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - }, - "provi": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.relayPacketsAction", - "Action": { - "ChainA": "provi", - "ChainB": "consu", - "Port": "provider", - "Channel": 0 - }, - "State": { - "consu": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - }, - "provi": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.doublesignSlashAction", - "Action": { - "Validator": "bob", - "Chain": "consu" - }, - "State": { - "consu": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1550,9 +1395,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1579,9 +1424,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1597,232 +1442,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.relayPacketsAction", - "Action": { - "ChainA": "provi", - "ChainB": "consu", - "Port": "provider", - "Channel": 0 - }, - "State": { - "consu": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - }, - "provi": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.submitEquivocationProposalAction", - "Action": { - "Chain": "consu", - "Height": 10, - "Time": "2023-09-20T18:24:51.823197+02:00", - "Power": 500, - "Validator": "bob", - "Deposit": 10000001, - "From": "bob" - }, - "State": { - "consu": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - }, - "provi": { - "ValBalances": { - "bob": 9489999999 - }, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": { - "2": { - "RawProposal": { - "Height": 10, - "Power": 500, - "ConsensusAddress": "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39", - "Deposit": 10000001, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" - }, - "Type": "main.EquivocationProposal" - } - } - } - } - }, - { - "ActionType": "main.voteGovProposalAction", - "Action": { - "Chain": "provi", - "From": [ - "alice", - "bob", - "carol" - ], - "Vote": [ - "yes", - "yes", - "yes" - ], - "PropNumber": 2 - }, - "State": { - "consu": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - }, - "provi": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 0, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": { - "2": { - "RawProposal": { - "Height": 10, - "Power": 500, - "ConsensusAddress": "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39", - "Deposit": 10000001, - "Status": "PROPOSAL_STATUS_PASSED" - }, - "Type": "main.EquivocationProposal" - } - } - } - } - }, - { - "ActionType": "main.relayPacketsAction", - "Action": { - "ChainA": "provi", - "ChainB": "consu", - "Port": "provider", - "Channel": 0 - }, - "State": { - "consu": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 0, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - }, - "provi": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 0, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1855,11 +1477,11 @@ }, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { - "3": { + "2": { "RawProposal": { "Deposit": 10000001, "Chain": "consu", @@ -1886,7 +1508,7 @@ "no", "no" ], - "PropNumber": 3 + "PropNumber": 2 }, "State": { "provi": { @@ -1902,11 +1524,11 @@ }, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { - "3": { + "2": { "RawProposal": { "Deposit": 10000001, "Chain": "consu", @@ -1942,11 +1564,11 @@ }, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { - "4": { + "3": { "RawProposal": { "Deposit": 10000001, "Chain": "consu", @@ -1973,7 +1595,7 @@ "yes", "yes" ], - "PropNumber": 4 + "PropNumber": 3 }, "State": { "provi": { @@ -1987,11 +1609,11 @@ "ConsumerChains": {}, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { - "4": { + "3": { "RawProposal": { "Deposit": 10000001, "Chain": "consu", diff --git a/tests/e2e/tracehandler_testdata/multipleConsumers.json b/tests/e2e/tracehandler_testdata/multipleConsumers.json index 4774a94ad8..a6b31d15e8 100644 --- a/tests/e2e/tracehandler_testdata/multipleConsumers.json +++ b/tests/e2e/tracehandler_testdata/multipleConsumers.json @@ -21,7 +21,7 @@ } ], "GenesisChanges": "", - "SkipGentx": false + "IsConsumer": false }, "State": { "provi": { @@ -37,9 +37,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -71,9 +71,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -115,9 +115,9 @@ "ProviderKeys": { "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -159,9 +159,9 @@ "ProviderKeys": { "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -195,9 +195,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -253,9 +253,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -271,9 +271,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -328,9 +328,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "2": { "RawProposal": { @@ -372,9 +372,9 @@ "ProviderKeys": { "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -416,9 +416,9 @@ "ProviderKeys": { "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -452,9 +452,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "2": { "RawProposal": { @@ -510,9 +510,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -528,9 +528,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -580,9 +580,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -598,9 +598,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -616,9 +616,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -645,9 +645,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -663,9 +663,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -681,9 +681,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -710,9 +710,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -728,9 +728,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -746,9 +746,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -775,9 +775,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -793,9 +793,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -811,9 +811,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -840,9 +840,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -858,9 +858,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -876,9 +876,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -905,9 +905,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -923,9 +923,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -941,9 +941,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -971,9 +971,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -989,9 +989,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1007,9 +1007,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1036,9 +1036,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1054,9 +1054,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1072,9 +1072,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1101,9 +1101,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1119,9 +1119,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1137,9 +1137,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1164,9 +1164,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1182,9 +1182,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1200,9 +1200,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1229,9 +1229,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1247,9 +1247,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1265,9 +1265,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1294,9 +1294,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1312,9 +1312,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1341,9 +1341,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1359,9 +1359,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1386,9 +1386,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1404,9 +1404,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1422,9 +1422,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1451,9 +1451,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1469,9 +1469,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1487,9 +1487,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1516,9 +1516,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1534,9 +1534,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1552,9 +1552,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1579,9 +1579,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1597,9 +1597,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1615,9 +1615,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1644,9 +1644,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1662,9 +1662,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1680,9 +1680,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1709,9 +1709,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1727,9 +1727,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1745,9 +1745,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1772,9 +1772,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1790,9 +1790,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1808,9 +1808,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1837,9 +1837,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1855,9 +1855,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1873,9 +1873,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1902,9 +1902,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1920,9 +1920,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1938,9 +1938,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1965,9 +1965,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -1983,9 +1983,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -2001,9 +2001,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -2030,9 +2030,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -2048,9 +2048,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -2066,9 +2066,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -2095,9 +2095,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -2113,9 +2113,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -2131,9 +2131,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -2158,9 +2158,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -2176,9 +2176,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -2194,9 +2194,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -2223,9 +2223,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -2241,9 +2241,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -2259,9 +2259,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -2288,9 +2288,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -2306,9 +2306,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -2324,9 +2324,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -2353,9 +2353,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "densu": { @@ -2371,9 +2371,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } diff --git a/tests/e2e/tracehandler_testdata/shorthappy.json b/tests/e2e/tracehandler_testdata/shorthappy.json index ee82bf619f..85e96aeed1 100644 --- a/tests/e2e/tracehandler_testdata/shorthappy.json +++ b/tests/e2e/tracehandler_testdata/shorthappy.json @@ -21,7 +21,7 @@ } ], "GenesisChanges": "", - "SkipGentx": false + "IsConsumer": false }, "State": { "provi": { @@ -37,9 +37,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -71,9 +71,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -115,9 +115,9 @@ "ProviderKeys": { "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -159,9 +159,9 @@ "ProviderKeys": { "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -195,9 +195,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -253,9 +253,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -271,9 +271,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -323,9 +323,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -341,9 +341,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -369,9 +369,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -398,9 +398,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -426,9 +426,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -455,9 +455,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -473,9 +473,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -502,9 +502,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -532,9 +532,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -550,9 +550,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -579,9 +579,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -606,9 +606,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -624,9 +624,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -644,7 +644,6 @@ "ValBalances": null, "ValPowers": { "alice": 509, - "bob": 500, "carol": 501 }, "StakedTokens": null, @@ -653,9 +652,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -671,9 +670,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -700,9 +699,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -727,9 +726,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -745,9 +744,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -774,9 +773,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -801,9 +800,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -819,9 +818,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -848,9 +847,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -875,9 +874,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -893,9 +892,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -922,72 +921,10 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.submitEquivocationProposalAction", - "Action": { - "Chain": "consu", - "Height": 10, - "Time": "2023-09-20T18:24:51.823231+02:00", - "Power": 500, - "Validator": "bob", - "Deposit": 10000001, - "From": "bob" - }, - "State": { - "consu": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 495 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null - }, - "provi": { - "ValBalances": { - "bob": 9500000000 - }, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 495 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": { - "2": { - "RawProposal": { - "Title": "", - "Description": "", - "Deposit": 0, - "Status": "" - }, - "Type": "main.TextProposal" - } - } } } }, @@ -1011,101 +948,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - }, - "provi": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.relayPacketsAction", - "Action": { - "ChainA": "provi", - "ChainB": "consu", - "Port": "provider", - "Channel": 0 - }, - "State": { - "consu": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - }, - "provi": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.doublesignSlashAction", - "Action": { - "Validator": "bob", - "Chain": "consu" - }, - "State": { - "consu": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1121,9 +966,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1150,9 +995,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -1168,232 +1013,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.relayPacketsAction", - "Action": { - "ChainA": "provi", - "ChainB": "consu", - "Port": "provider", - "Channel": 0 - }, - "State": { - "consu": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - }, - "provi": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - } - } - }, - { - "ActionType": "main.submitEquivocationProposalAction", - "Action": { - "Chain": "consu", - "Height": 10, - "Time": "2023-09-20T18:24:51.823235+02:00", - "Power": 500, - "Validator": "bob", - "Deposit": 10000001, - "From": "bob" - }, - "State": { - "consu": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - }, - "provi": { - "ValBalances": { - "bob": 9489999999 - }, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": { - "2": { - "RawProposal": { - "Height": 10, - "Power": 500, - "ConsensusAddress": "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39", - "Deposit": 10000001, - "Status": "PROPOSAL_STATUS_VOTING_PERIOD" - }, - "Type": "main.EquivocationProposal" - } - } - } - } - }, - { - "ActionType": "main.voteGovProposalAction", - "Action": { - "Chain": "provi", - "From": [ - "alice", - "bob", - "carol" - ], - "Vote": [ - "yes", - "yes", - "yes" - ], - "PropNumber": 2 - }, - "State": { - "consu": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 500, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - }, - "provi": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 0, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": { - "2": { - "RawProposal": { - "Height": 10, - "Power": 500, - "ConsensusAddress": "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39", - "Deposit": 10000001, - "Status": "PROPOSAL_STATUS_PASSED" - }, - "Type": "main.EquivocationProposal" - } - } - } - } - }, - { - "ActionType": "main.relayPacketsAction", - "Action": { - "ChainA": "provi", - "ChainB": "consu", - "Port": "provider", - "Channel": 0 - }, - "State": { - "consu": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 0, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, - "RegisteredConsumerRewardDenoms": null, - "Proposals": null - }, - "provi": { - "ValBalances": null, - "ValPowers": { - "alice": 509, - "bob": 0, - "carol": 0 - }, - "StakedTokens": null, - "Params": null, - "Rewards": null, - "ConsumerChains": null, - "AssignedKeys": null, - "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -1426,11 +1048,11 @@ }, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { - "3": { + "2": { "RawProposal": { "Deposit": 10000001, "Chain": "consu", @@ -1457,7 +1079,7 @@ "no", "no" ], - "PropNumber": 3 + "PropNumber": 2 }, "State": { "provi": { @@ -1473,11 +1095,11 @@ }, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { - "3": { + "2": { "RawProposal": { "Deposit": 10000001, "Chain": "consu", @@ -1513,11 +1135,11 @@ }, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { - "4": { + "3": { "RawProposal": { "Deposit": 10000001, "Chain": "consu", @@ -1544,7 +1166,7 @@ "yes", "yes" ], - "PropNumber": 4 + "PropNumber": 3 }, "State": { "provi": { @@ -1558,11 +1180,11 @@ "ConsumerChains": {}, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { - "4": { + "3": { "RawProposal": { "Deposit": 10000001, "Chain": "consu", diff --git a/tests/e2e/tracehandler_testdata/slashThrottle.json b/tests/e2e/tracehandler_testdata/slashThrottle.json index ea8306fd4c..dbca351d49 100644 --- a/tests/e2e/tracehandler_testdata/slashThrottle.json +++ b/tests/e2e/tracehandler_testdata/slashThrottle.json @@ -21,7 +21,7 @@ } ], "GenesisChanges": "", - "SkipGentx": false + "IsConsumer": false }, "State": { "provi": { @@ -37,9 +37,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -71,9 +71,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -115,9 +115,9 @@ "ProviderKeys": { "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -159,9 +159,9 @@ "ProviderKeys": { "carol": "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6" }, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -195,9 +195,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "1": { "RawProposal": { @@ -253,9 +253,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -271,9 +271,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -323,9 +323,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -341,9 +341,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -369,9 +369,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -398,9 +398,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -426,9 +426,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -453,9 +453,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": 1, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -471,9 +471,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -500,9 +500,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": 0, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -518,11 +518,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": { - "consu": 0 - }, - "GlobalSlashQueueSize": 0, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -547,9 +545,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": 1, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -565,9 +563,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -594,9 +592,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": 1, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -612,22 +610,18 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": { - "consu": 1 - }, - "GlobalSlashQueueSize": 1, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } }, { - "ActionType": "main.slashThrottleDequeueAction", + "ActionType": "main.slashMeterReplenishmentAction", "Action": { - "Chain": "consu", - "CurrentQueueSize": 1, - "NextQueueSize": 0, - "Timeout": 80000000000 + "TargetValue": 0, + "Timeout": 100000000000 }, "State": { "consu": { @@ -643,9 +637,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": 1, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -653,7 +647,7 @@ "ValPowers": { "alice": 511, "bob": 0, - "carol": 0 + "carol": 500 }, "StakedTokens": null, "Params": null, @@ -661,11 +655,49 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": { - "consu": 0 + "ConsumerPendingPacketQueueSize": null, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + } + } + }, + { + "ActionType": "main.waitTimeAction", + "Action": { + "WaitTime": 30000000000 + }, + "State": { + "consu": { + "ValBalances": null, + "ValPowers": null, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": 1, + "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, + "Proposals": null + }, + "provi": { + "ValBalances": null, + "ValPowers": { + "alice": 511, + "bob": 0, + "carol": 500 }, - "GlobalSlashQueueSize": 0, + "StakedTokens": null, + "Params": null, + "Rewards": null, + "ConsumerChains": null, + "AssignedKeys": null, + "ProviderKeys": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -681,20 +713,16 @@ "State": { "consu": { "ValBalances": null, - "ValPowers": { - "alice": 511, - "bob": 0, - "carol": 0 - }, + "ValPowers": null, "StakedTokens": null, "Params": null, "Rewards": null, "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": 0, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null }, "provi": { @@ -710,11 +738,9 @@ "ConsumerChains": null, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": { - "consu": 0 - }, - "GlobalSlashQueueSize": 0, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": null } } @@ -742,9 +768,9 @@ }, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "2": { "RawProposal": { @@ -787,9 +813,9 @@ "ConsumerChains": {}, "AssignedKeys": null, "ProviderKeys": null, - "ConsumerChainQueueSizes": null, - "GlobalSlashQueueSize": null, + "ConsumerPendingPacketQueueSize": null, "RegisteredConsumerRewardDenoms": null, + "ClientsFrozenHeights": null, "Proposals": { "2": { "RawProposal": { diff --git a/tests/integration/common.go b/tests/integration/common.go index a638c73fc2..413cdaa810 100644 --- a/tests/integration/common.go +++ b/tests/integration/common.go @@ -426,38 +426,43 @@ func (suite *CCVTestSuite) commitConsumerPacket(ctx sdk.Context, packetData ccv. // constructSlashPacketFromConsumer constructs an IBC packet embedding // slash packet data to be sent from consumer to provider func (s *CCVTestSuite) constructSlashPacketFromConsumer(bundle icstestingutils.ConsumerBundle, - tmVal tmtypes.Validator, infractionType stakingtypes.Infraction, -) ccv.ConsumerPacketData { + tmVal tmtypes.Validator, infractionType stakingtypes.Infraction, ibcSeqNum uint64, +) channeltypes.Packet { + packet, _ := s.constructSlashPacketFromConsumerWithData(bundle, tmVal, infractionType, ibcSeqNum) + return packet +} + +func (s *CCVTestSuite) constructSlashPacketFromConsumerWithData(bundle icstestingutils.ConsumerBundle, + tmVal tmtypes.Validator, infractionType stakingtypes.Infraction, ibcSeqNum uint64, +) (channeltypes.Packet, ccv.SlashPacketData) { valsetUpdateId := bundle.GetKeeper().GetHeightValsetUpdateID( bundle.GetCtx(), uint64(bundle.GetCtx().BlockHeight())) - return ccv.ConsumerPacketData{ - Type: ccv.SlashPacket, - Data: &ccv.ConsumerPacketData_SlashPacketData{ - SlashPacketData: &ccv.SlashPacketData{ - Validator: abci.Validator{ - Address: tmVal.Address, - Power: tmVal.VotingPower, - }, - ValsetUpdateId: valsetUpdateId, - Infraction: infractionType, - }, + spdData := ccv.SlashPacketData{ + Validator: abci.Validator{ + Address: tmVal.Address, + Power: tmVal.VotingPower, }, + ValsetUpdateId: valsetUpdateId, + Infraction: infractionType, } -} -// constructVSCMaturedPacketFromConsumer constructs an IBC packet embedding -// VSC Matured packet data to be sent from consumer to provider -func (s *CCVTestSuite) constructVSCMaturedPacketFromConsumer(bundle icstestingutils.ConsumerBundle) ccv.ConsumerPacketData { - valsetUpdateId := bundle.GetKeeper().GetHeightValsetUpdateID( - bundle.GetCtx(), uint64(bundle.GetCtx().BlockHeight())) - - return ccv.ConsumerPacketData{ - Type: ccv.VscMaturedPacket, - Data: &ccv.ConsumerPacketData_VscMaturedPacketData{ - VscMaturedPacketData: &ccv.VSCMaturedPacketData{ValsetUpdateId: valsetUpdateId}, + cpdData := ccv.ConsumerPacketData{ + Type: ccv.SlashPacket, + Data: &ccv.ConsumerPacketData_SlashPacketData{ + SlashPacketData: &spdData, }, } + + return channeltypes.NewPacket(cpdData.GetBytes(), + ibcSeqNum, + ccv.ConsumerPortID, // Src port + bundle.Path.EndpointA.ChannelID, // Src channel + ccv.ProviderPortID, // Dst port + bundle.Path.EndpointB.ChannelID, // Dst channel + clienttypes.Height{}, + uint64(bundle.GetCtx().BlockTime().Add(ccv.DefaultCCVTimeoutPeriod).UnixNano()), + ), spdData } // incrementTime increments the overall time by jumpPeriod @@ -607,3 +612,11 @@ func (s *CCVTestSuite) setupValidatorPowers() { } s.Require().Equal(int64(4000), stakingKeeper.GetLastTotalPower(s.providerCtx()).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) + return stakingVal +} diff --git a/tests/integration/double_vote.go b/tests/integration/double_vote.go new file mode 100644 index 0000000000..af05c745df --- /dev/null +++ b/tests/integration/double_vote.go @@ -0,0 +1,395 @@ +package integration + +import ( + 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/v3/testutil/crypto" + "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" +) + +// TestHandleConsumerDoubleVoting verifies that handling a double voting evidence +// of a consumer chain results in the expected tombstoning, jailing, and slashing of the misbehaved validator +func (s *CCVTestSuite) TestHandleConsumerDoubleVoting() { + s.SetupCCVChannel(s.path) + // required to have the consumer client revision height greater than 0 + s.SendEmptyVSCPacket() + + // create signing info for all validators + for _, v := range s.providerChain.Vals.Validators { + s.setDefaultValSigningInfo(*v) + } + + consuValSet, err := tmtypes.ValidatorSetFromProto(s.consumerChain.LastHeader.ValidatorSet) + s.Require().NoError(err) + consuVal := consuValSet.Validators[0] + consuSigner := s.consumerChain.Signers[consuVal.Address.String()] + + provValSet, err := tmtypes.ValidatorSetFromProto(s.providerChain.LastHeader.ValidatorSet) + s.Require().NoError(err) + + provVal := provValSet.Validators[0] + provSigner := s.providerChain.Signers[provVal.Address.String()] + + blockID1 := testutil.MakeBlockID([]byte("blockhash"), 1000, []byte("partshash")) + blockID2 := testutil.MakeBlockID([]byte("blockhash2"), 1000, []byte("partshash")) + + // Set the equivocation evidence min height to the previous block height + equivocationEvidenceMinHeight := uint64(s.consumerCtx().BlockHeight() - 1) + s.providerApp.GetProviderKeeper().SetEquivocationEvidenceMinHeight( + s.providerCtx(), + s.consumerChain.ChainID, + equivocationEvidenceMinHeight, + ) + + // Note that votes are signed along with the chain ID + // see VoteSignBytes in https://github.com/cometbft/cometbft/blob/v0.37.2/types/vote.go#L93 + + // create two votes using the consumer validator key + consuVote := testutil.MakeAndSignVote( + blockID1, + s.consumerCtx().BlockHeight(), + s.consumerCtx().BlockTime(), + consuValSet, + consuSigner, + s.consumerChain.ChainID, + ) + + consuBadVote := testutil.MakeAndSignVote( + blockID2, + s.consumerCtx().BlockHeight(), + s.consumerCtx().BlockTime(), + consuValSet, + consuSigner, + s.consumerChain.ChainID, + ) + + // create two votes using the provider validator key + provVote := testutil.MakeAndSignVote( + blockID1, + s.consumerCtx().BlockHeight(), + s.consumerCtx().BlockTime(), + provValSet, + provSigner, + s.consumerChain.ChainID, + ) + + provBadVote := testutil.MakeAndSignVote( + blockID2, + s.consumerCtx().BlockHeight(), + s.consumerCtx().BlockTime(), + provValSet, + provSigner, + s.consumerChain.ChainID, + ) + + // create a vote using the consumer validator key + // with block height that is smaller than the equivocation evidence min height + consuVoteOld := testutil.MakeAndSignVote( + blockID1, + int64(equivocationEvidenceMinHeight-1), + s.consumerCtx().BlockTime(), + consuValSet, + consuSigner, + s.consumerChain.ChainID, + ) + + testCases := []struct { + name string + ev *tmtypes.DuplicateVoteEvidence + chainID string + pubkey tmcrypto.PubKey + expPass bool + }{ + { + "cannot find consumer chain for the given chain ID - shouldn't pass", + &tmtypes.DuplicateVoteEvidence{ + VoteA: consuVote, + VoteB: consuBadVote, + ValidatorPower: consuVal.VotingPower, + TotalVotingPower: consuVal.VotingPower, + Timestamp: s.consumerCtx().BlockTime(), + }, + "chainID", + consuVal.PubKey, + false, + }, + { + "evidence is older than equivocation evidence min height - shouldn't pass", + &tmtypes.DuplicateVoteEvidence{ + VoteA: consuVoteOld, + VoteB: consuBadVote, + ValidatorPower: consuVal.VotingPower, + TotalVotingPower: consuVal.VotingPower, + Timestamp: s.consumerCtx().BlockTime(), + }, + s.consumerChain.ChainID, + consuVal.PubKey, + false, + }, + { + "the votes in the evidence are for different height - shouldn't pass", + &tmtypes.DuplicateVoteEvidence{ + VoteA: consuVote, + VoteB: consuVoteOld, + ValidatorPower: consuVal.VotingPower, + TotalVotingPower: consuVal.VotingPower, + Timestamp: s.consumerCtx().BlockTime(), + }, + s.consumerChain.ChainID, + consuVal.PubKey, + false, + }, + { + "wrong public key - shouldn't pass", + &tmtypes.DuplicateVoteEvidence{ + VoteA: consuVote, + VoteB: consuVote, + ValidatorPower: consuVal.VotingPower, + TotalVotingPower: consuVal.VotingPower, + Timestamp: s.consumerCtx().BlockTime(), + }, + s.consumerChain.ChainID, + provVal.PubKey, + false, + }, + { + // create an invalid evidence containing two identical votes + "invalid double voting evidence with identical votes - shouldn't pass", + &tmtypes.DuplicateVoteEvidence{ + VoteA: consuVote, + VoteB: consuVote, + ValidatorPower: consuVal.VotingPower, + TotalVotingPower: consuVal.VotingPower, + Timestamp: s.consumerCtx().BlockTime(), + }, + s.consumerChain.ChainID, + consuVal.PubKey, + false, + }, + { + // In order to create an evidence for a consumer chain, + // we create two votes that only differ by their Block IDs and + // signed them using the same validator private key and chain ID + // of the consumer chain + "valid double voting evidence 1 - should pass", + &tmtypes.DuplicateVoteEvidence{ + VoteA: consuVote, + VoteB: consuBadVote, + ValidatorPower: consuVal.VotingPower, + TotalVotingPower: consuVal.VotingPower, + Timestamp: s.consumerCtx().BlockTime(), + }, + s.consumerChain.ChainID, + consuVal.PubKey, + true, + }, + { + // create a double voting evidence using the provider validator key + "valid double voting evidence 2 - should pass", + &tmtypes.DuplicateVoteEvidence{ + VoteA: provVote, + VoteB: provBadVote, + ValidatorPower: consuVal.VotingPower, + TotalVotingPower: consuVal.VotingPower, + Timestamp: s.consumerCtx().BlockTime(), + }, + s.consumerChain.ChainID, + provVal.PubKey, + true, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + consuAddr := types.NewConsumerConsAddress(sdk.ConsAddress(tc.ev.VoteA.ValidatorAddress.Bytes())) + 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()) + + // reset context for each run + provCtx, _ := s.providerCtx().CacheContext() + + // if the evidence was built using the validator provider address and key, + // we remove the consumer key assigned to the validator otherwise + // HandleConsumerDoubleVoting uses the consumer key to verify the signature + if tc.ev.VoteA.ValidatorAddress.String() != consuVal.Address.String() { + s.providerApp.GetProviderKeeper().DeleteKeyAssignments(provCtx, s.consumerChain.ChainID) + } + + // convert validator public key + pk, err := cryptocodec.FromTmPubKeyInterface(tc.pubkey) + s.Require().NoError(err) + + err = s.providerApp.GetProviderKeeper().HandleConsumerDoubleVoting( + provCtx, + tc.ev, + tc.chainID, + pk, + ) + + if tc.expPass { + s.Require().NoError(err) + + // verifies that the jailing and tombstoning has occurred + s.Require().True(s.providerApp.GetTestStakingKeeper().IsValidatorJailed(provCtx, provAddr.ToSdkConsAddr())) + s.Require().True(s.providerApp.GetTestSlashingKeeper().IsTombstoned(provCtx, provAddr.ToSdkConsAddr())) + + // 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()) + s.Require().True(initialTokens.Sub(initialTokens.Mul(slashFraction)).Equal(actualTokens)) + } else { + s.Require().Error(err) + + // verifies that no jailing and no tombstoning has occurred + s.Require().False(s.providerApp.GetTestStakingKeeper().IsValidatorJailed(provCtx, provAddr.ToSdkConsAddr())) + s.Require().False(s.providerApp.GetTestSlashingKeeper().IsTombstoned(provCtx, provAddr.ToSdkConsAddr())) + } + }) + } +} + +// TestHandleConsumerDoubleVotingSlashesUndelegationsAndRelegations verifies that handling a successful double voting +// evidence of a consumer chain results in the expected slashing of the misbehave validator undelegations +func (s *CCVTestSuite) TestHandleConsumerDoubleVotingSlashesUndelegationsAndRelegations() { + s.SetupCCVChannel(s.path) + // required to have the consumer client revision height greater than 0 + s.SendEmptyVSCPacket() + + // create signing info for all validators + for _, v := range s.providerChain.Vals.Validators { + s.setDefaultValSigningInfo(*v) + } + + consuValSet, err := tmtypes.ValidatorSetFromProto(s.consumerChain.LastHeader.ValidatorSet) + s.Require().NoError(err) + consuVal := consuValSet.Validators[0] + consuVal2 := consuValSet.Validators[1] + consuSigner := s.consumerChain.Signers[consuVal.Address.String()] + + blockID1 := testutil.MakeBlockID([]byte("blockhash"), 1000, []byte("partshash")) + blockID2 := testutil.MakeBlockID([]byte("blockhash2"), 1000, []byte("partshash")) + + // create two votes using the consumer validator key + consuVote := testutil.MakeAndSignVote( + blockID1, + s.consumerCtx().BlockHeight(), + s.consumerCtx().BlockTime(), + consuValSet, + consuSigner, + s.consumerChain.ChainID, + ) + + consuBadVote := testutil.MakeAndSignVote( + blockID2, + s.consumerCtx().BlockHeight(), + s.consumerCtx().BlockTime(), + consuValSet, + consuSigner, + s.consumerChain.ChainID, + ) + + // In order to create an evidence for a consumer chain, + // we create two votes that only differ by their Block IDs and + // signed them using the same validator private key and chain ID + // of the consumer chain + evidence := &tmtypes.DuplicateVoteEvidence{ + VoteA: consuVote, + VoteB: consuBadVote, + ValidatorPower: consuVal.VotingPower, + TotalVotingPower: consuVal.VotingPower, + Timestamp: s.consumerCtx().BlockTime(), + } + + chainID := s.consumerChain.ChainID + pubKey := consuVal.PubKey + + consuAddr := types.NewConsumerConsAddress(sdk.ConsAddress(consuVal.Address.Bytes())) + provAddr := s.providerApp.GetProviderKeeper().GetProviderAddrFromConsumerAddr(s.providerCtx(), s.consumerChain.ChainID, consuAddr) + + 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) + + validator2, found := s.providerApp.GetTestStakingKeeper().GetValidator(s.providerCtx(), provAddr2.ToSdkConsAddr().Bytes()) + s.Require().True(found) + + s.Run("slash undelegations and redelegations when getting double voting evidence", func() { + // convert validator public key + pk, err := cryptocodec.FromTmPubKeyInterface(pubKey) + s.Require().NoError(err) + + // perform a delegation and an undelegation of the whole amount + bondAmt := sdk.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) + // loop through all validators to find the right `idx` + idx := 0 + for i := 0; i <= len(s.providerChain.Vals.Validators); i++ { + _, valAddr := s.getValByIdx(i) + if validator.OperatorAddress == valAddr.String() { + idx = i + break + } + } + + // delegate bond amount + _, shares, _ := delegateByIdx(s, delAddr, bondAmt, idx) + 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))) + + // check that undelegations were successful + ubds, _ := s.providerApp.GetTestStakingKeeper().GetUnbondingDelegation(s.providerCtx(), delAddr, validator.GetOperator()) + // 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() + + // 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))) + + // check that redelegation was successful + rdel := s.providerApp.GetTestStakingKeeper().GetRedelegations(s.providerCtx(), delAddr, uint16(10)) + s.Require().Len(rdel[0].Entries, 2) + + redelShares := rdel[0].Entries[0].SharesDst.Add(rdel[0].Entries[1].SharesDst) + + // cause double voting + err = s.providerApp.GetProviderKeeper().HandleConsumerDoubleVoting( + s.providerCtx(), + evidence, + chainID, + pk, + ) + s.Require().NoError(err) + + slashFraction := s.providerApp.GetTestSlashingKeeper().SlashFractionDoubleSign(s.providerCtx()) + + // check undelegations are slashed + ubds, _ = s.providerApp.GetTestStakingKeeper().GetUnbondingDelegation(s.providerCtx(), delAddr, validator.GetOperator()) + s.Require().True(len(ubds.Entries) > 0) + for _, unb := range ubds.Entries { + initialBalance := sdk.NewDecFromInt(unb.InitialBalance) + currentBalance := sdk.NewDecFromInt(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()) + s.Require().Equal(delegations.GetShares(), delShares.Add(redelShares).Sub(redelShares.Mul(slashFraction))) + }) +} diff --git a/tests/integration/misbehaviour.go b/tests/integration/misbehaviour.go new file mode 100644 index 0000000000..c0f2cf10b9 --- /dev/null +++ b/tests/integration/misbehaviour.go @@ -0,0 +1,551 @@ +package integration + +import ( + "time" + + ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + + sdk "github.com/cosmos/cosmos-sdk/types" + + tmtypes "github.com/cometbft/cometbft/types" + + testutil "github.com/cosmos/interchain-security/v3/testutil/crypto" + "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" +) + +// TestHandleConsumerMisbehaviour tests that handling a valid misbehaviour, +// with conflicting headers forming an equivocation, results in the jailing of the validators +func (s *CCVTestSuite) TestHandleConsumerMisbehaviour() { + s.SetupCCVChannel(s.path) + // required to have the consumer client revision height greater than 0 + s.SendEmptyVSCPacket() + + for _, v := range s.providerChain.Vals.Validators { + s.setDefaultValSigningInfo(*v) + } + + altTime := s.providerCtx().BlockTime().Add(time.Minute) + + clientHeight := s.consumerChain.LastHeader.TrustedHeight + clientTMValset := tmtypes.NewValidatorSet(s.consumerChain.Vals.Validators) + clientSigners := s.consumerChain.Signers + + misb := &ibctmtypes.Misbehaviour{ + ClientId: s.path.EndpointA.ClientID, + Header1: s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+1), + clientHeight, + altTime, + clientTMValset, + clientTMValset, + clientTMValset, + clientSigners, + ), + // create a different header by changing the header timestamp only + // in order to create an equivocation, i.e. both headers have the same deterministic states + Header2: s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+1), + clientHeight, + altTime.Add(10*time.Second), + clientTMValset, + clientTMValset, + clientTMValset, + clientSigners, + ), + } + + // we assume that all validators have the same number of initial tokens + validator, _ := s.getValByIdx(0) + initialTokens := sdk.NewDecFromInt(validator.GetTokens()) + + err := s.providerApp.GetProviderKeeper().HandleConsumerMisbehaviour(s.providerCtx(), *misb) + s.NoError(err) + + // verify that validators are jailed, tombstoned, and slashed + 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) + 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()) + s.Require().True(initialTokens.Sub(initialTokens.Mul(slashFraction)).Equal(actualTokens)) + } +} + +func (s *CCVTestSuite) TestGetByzantineValidators() { + s.SetupCCVChannel(s.path) + // required to have the consumer client revision height greater than 0 + s.SendEmptyVSCPacket() + + altTime := s.providerCtx().BlockTime().Add(time.Minute) + + // Get the consumer client validator set + clientHeight := s.consumerChain.LastHeader.TrustedHeight + clientTMValset := tmtypes.NewValidatorSet(s.consumerChain.Vals.Validators) + clientSigners := s.consumerChain.Signers + + // Create a subset of the consumer client validator set + altValset := tmtypes.NewValidatorSet(s.consumerChain.Vals.Validators[0:3]) + altSigners := make(map[string]tmtypes.PrivValidator, 3) + altSigners[clientTMValset.Validators[0].Address.String()] = clientSigners[clientTMValset.Validators[0].Address.String()] + altSigners[clientTMValset.Validators[1].Address.String()] = clientSigners[clientTMValset.Validators[1].Address.String()] + altSigners[clientTMValset.Validators[2].Address.String()] = clientSigners[clientTMValset.Validators[2].Address.String()] + + // create a consumer client header + clientHeader := s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+1), + clientHeight, + altTime, + clientTMValset, + clientTMValset, + clientTMValset, + clientSigners, + ) + + testCases := []struct { + name string + getMisbehaviour func() *ibctmtypes.Misbehaviour + expByzantineValidators []*tmtypes.Validator + expPass bool + }{ + { + "invalid misbehaviour - Header1 is empty", + func() *ibctmtypes.Misbehaviour { + return &ibctmtypes.Misbehaviour{ + Header1: &ibctmtypes.Header{}, + Header2: clientHeader, + } + }, + nil, + false, + }, + { + "invalid headers - Header2 is empty", + func() *ibctmtypes.Misbehaviour { + return &ibctmtypes.Misbehaviour{ + Header1: clientHeader, + Header2: &ibctmtypes.Header{}, + } + }, + nil, + false, + }, + { + "incorrect valset - shouldn't pass", + func() *ibctmtypes.Misbehaviour { + clientHeader := s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+1), + clientHeight, + altTime.Add(time.Minute), + clientTMValset, + clientTMValset, + clientTMValset, + clientSigners, + ) + + clientHeaderWithCorruptedValset := s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+1), + clientHeight, + altTime.Add(time.Hour), + clientTMValset, + clientTMValset, + clientTMValset, + clientSigners, + ) + + // change a validator public key in one the second header + testutil.CorruptValidatorPubkeyInHeader(clientHeaderWithCorruptedValset, clientTMValset.Validators[0].Address) + + return &ibctmtypes.Misbehaviour{ + ClientId: s.path.EndpointA.ClientID, + Header1: clientHeader, + Header2: clientHeaderWithCorruptedValset, + } + }, + []*tmtypes.Validator{}, + false, + }, + { + "incorrect valset 2 - shouldn't pass", + func() *ibctmtypes.Misbehaviour { + clientHeader := s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+1), + clientHeight, + altTime.Add(time.Minute), + clientTMValset, + clientTMValset, + clientTMValset, + clientSigners, + ) + + clientHeaderWithCorruptedSigs := s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+1), + clientHeight, + altTime.Add(time.Hour), + clientTMValset, + clientTMValset, + clientTMValset, + clientSigners, + ) + + // change the valset in the header + vs, _ := altValset.ToProto() + clientHeader.ValidatorSet.Validators = vs.Validators[:3] + clientHeaderWithCorruptedSigs.ValidatorSet.Validators = vs.Validators[:3] + + return &ibctmtypes.Misbehaviour{ + ClientId: s.path.EndpointA.ClientID, + Header1: clientHeader, + Header2: clientHeaderWithCorruptedSigs, + } + }, + []*tmtypes.Validator{}, + false, + }, + { + "incorrect signatures - shouldn't pass", + func() *ibctmtypes.Misbehaviour { + clientHeader := s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+1), + clientHeight, + altTime.Add(time.Minute), + clientTMValset, + clientTMValset, + clientTMValset, + clientSigners, + ) + + clientHeaderWithCorruptedSigs := s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+1), + clientHeight, + altTime.Add(time.Hour), + clientTMValset, + clientTMValset, + clientTMValset, + clientSigners, + ) + + // change the signature of one of the validator in the header + testutil.CorruptCommitSigsInHeader(clientHeaderWithCorruptedSigs, clientTMValset.Validators[0].Address) + + return &ibctmtypes.Misbehaviour{ + ClientId: s.path.EndpointA.ClientID, + Header1: clientHeader, + Header2: clientHeaderWithCorruptedSigs, + } + }, + []*tmtypes.Validator{}, + false, + }, + { + "light client attack - lunatic attack", + func() *ibctmtypes.Misbehaviour { + return &ibctmtypes.Misbehaviour{ + ClientId: s.path.EndpointA.ClientID, + Header1: clientHeader, + // the resulting header contains invalid fields + // i.e. ValidatorsHash, NextValidatorsHash. + Header2: s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+1), + clientHeight, + altTime, + altValset, + altValset, + clientTMValset, + altSigners, + ), + } + }, + // Expect to get only the validators + // who signed both headers + altValset.Validators, + true, + }, + { + "light client attack - equivocation", + func() *ibctmtypes.Misbehaviour { + return &ibctmtypes.Misbehaviour{ + ClientId: s.path.EndpointA.ClientID, + Header1: clientHeader, + // the resulting header contains a different BlockID + Header2: s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+1), + clientHeight, + altTime.Add(time.Minute), + clientTMValset, + clientTMValset, + clientTMValset, + clientSigners, + ), + } + }, + // Expect to get the entire valset since + // all validators double-signed + clientTMValset.Validators, + true, + }, + { + "light client attack - amnesia", + func() *ibctmtypes.Misbehaviour { + // create a valid header with a different hash + // and commit round + amnesiaHeader := s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+1), + clientHeight, + altTime.Add(time.Minute), + clientTMValset, + clientTMValset, + clientTMValset, + clientSigners, + ) + amnesiaHeader.Commit.Round = 2 + + return &ibctmtypes.Misbehaviour{ + ClientId: s.path.EndpointA.ClientID, + Header1: clientHeader, + Header2: amnesiaHeader, + } + }, + // Expect no validators + // since amnesia attacks are dropped + []*tmtypes.Validator{}, + true, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + byzantineValidators, err := s.providerApp.GetProviderKeeper().GetByzantineValidators( + s.providerCtx(), + *tc.getMisbehaviour(), + ) + if tc.expPass { + s.NoError(err) + s.Equal(len(tc.expByzantineValidators), len(byzantineValidators)) + + // For both lunatic and equivocation attacks, all the validators + // who signed both headers + if len(tc.expByzantineValidators) > 0 { + equivocatingVals := tc.getMisbehaviour().Header2.ValidatorSet + s.Equal(len(equivocatingVals.Validators), len(byzantineValidators)) + + vs, err := tmtypes.ValidatorSetFromProto(equivocatingVals) + s.NoError(err) + + for _, v := range tc.expByzantineValidators { + idx, _ := vs.GetByAddress(v.Address) + s.True(idx >= 0) + } + } + } else { + s.Error(err) + } + }) + } +} + +func (s *CCVTestSuite) TestCheckMisbehaviour() { + s.SetupCCVChannel(s.path) + // required to have the consumer client revision height greater than 0 + s.SendEmptyVSCPacket() + + // create signing info for all validators + for _, v := range s.providerChain.Vals.Validators { + s.setDefaultValSigningInfo(*v) + } + + // create a new header timestamp + headerTs := s.providerCtx().BlockTime().Add(time.Minute) + + // get trusted validators and height + clientHeight := s.consumerChain.LastHeader.TrustedHeight + clientTMValset := tmtypes.NewValidatorSet(s.consumerChain.Vals.Validators) + clientSigners := s.consumerChain.Signers + + // create a valid client header + clientHeader := s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+1), + clientHeight, + headerTs, + clientTMValset, + clientTMValset, + clientTMValset, + clientSigners, + ) + + // create an alternative validator set using more than 1/3 of the trusted validator set + altValset := tmtypes.NewValidatorSet(s.consumerChain.Vals.Validators[0:2]) + altSigners := make(map[string]tmtypes.PrivValidator, 2) + altSigners[clientTMValset.Validators[0].Address.String()] = clientSigners[clientTMValset.Validators[0].Address.String()] + altSigners[clientTMValset.Validators[1].Address.String()] = clientSigners[clientTMValset.Validators[1].Address.String()] + + // create a conflicting client with different block ID using + // to alternative validator set + clientHeaderWithDiffBlockID := s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+1), + clientHeight, + headerTs, + altValset, + altValset, + clientTMValset, // trusted valset stays the same + altSigners, + ) + + // create an alternative validator set using less than 1/3 of the trusted validator set + altValset2 := tmtypes.NewValidatorSet(s.consumerChain.Vals.Validators[0:1]) + altSigners2 := make(map[string]tmtypes.PrivValidator, 1) + altSigners2[clientTMValset.Validators[0].Address.String()] = clientSigners[clientTMValset.Validators[0].Address.String()] + + // create a conflicting client header with insufficient voting power + clientHeaderWithInsufficientVotingPower := s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+1), + clientHeight, + // use a different block time to change the header BlockID + headerTs.Add(time.Hour), + altValset2, + altValset2, + clientTMValset, + altSigners2, + ) + + // Set the equivocation evidence min height to the previous block height + equivocationEvidenceMinHeight := clientHeight.RevisionHeight + 1 + s.providerApp.GetProviderKeeper().SetEquivocationEvidenceMinHeight( + s.providerCtx(), + s.consumerChain.ChainID, + equivocationEvidenceMinHeight, + ) + + testCases := []struct { + name string + misbehaviour *ibctmtypes.Misbehaviour + expPass bool + }{ + { + "identical headers - shouldn't pass", + &ibctmtypes.Misbehaviour{ + ClientId: s.path.EndpointA.ClientID, + Header1: clientHeader, + Header2: clientHeader, + }, + false, + }, + { + "misbehaviour isn't for a consumer chain - shouldn't pass", + &ibctmtypes.Misbehaviour{ + ClientId: s.path.EndpointA.ClientID, + Header1: s.consumerChain.CreateTMClientHeader( + "aChainID", + int64(clientHeight.RevisionHeight+1), + clientHeight, + headerTs, + altValset, + altValset, + clientTMValset, + altSigners, + ), + Header2: clientHeader, + }, + false, + }, + { + "client ID doesn't correspond to the client ID of consumer chain - shouldn't pass", + &ibctmtypes.Misbehaviour{ + ClientId: "clientID", + Header1: clientHeader, + Header2: clientHeaderWithDiffBlockID, + }, + false, + }, + { + "invalid misbehaviour with different header height - shouldn't pass", + &ibctmtypes.Misbehaviour{ + ClientId: s.path.EndpointA.ClientID, + Header1: clientHeader, + Header2: s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(clientHeight.RevisionHeight+2), + clientHeight, + headerTs, + altValset, + altValset, + clientTMValset, + altSigners, + ), + }, + false, + }, + { + "invalid misbehaviour older than the min equivocation evidence height - shouldn't pass", + &ibctmtypes.Misbehaviour{ + ClientId: s.path.EndpointA.ClientID, + Header1: s.consumerChain.CreateTMClientHeader( + s.consumerChain.ChainID, + int64(equivocationEvidenceMinHeight-1), + clientHeight, + headerTs, + altValset, + altValset, + clientTMValset, + altSigners, + ), + Header2: clientHeader, + }, + false, + }, + { + "one header of the misbehaviour has insufficient voting power - shouldn't pass", + &ibctmtypes.Misbehaviour{ + ClientId: s.path.EndpointA.ClientID, + Header1: clientHeader, + Header2: clientHeaderWithInsufficientVotingPower, + }, + false, + }, + { + "valid misbehaviour - should pass", + &ibctmtypes.Misbehaviour{ + ClientId: s.path.EndpointA.ClientID, + Header1: clientHeader, + // create header using a different validator set + Header2: clientHeaderWithDiffBlockID, + }, + true, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + err := s.providerApp.GetProviderKeeper().CheckMisbehaviour(s.providerCtx(), *tc.misbehaviour) + cs, ok := s.providerApp.GetIBCKeeper().ClientKeeper.GetClientState(s.providerCtx(), s.path.EndpointA.ClientID) + s.Require().True(ok) + // verify that the client wasn't frozen + s.Require().Zero(cs.(*ibctmtypes.ClientState).FrozenHeight) + if tc.expPass { + s.NoError(err) + } else { + s.Error(err) + } + }) + } +} diff --git a/tests/integration/query_providerinfo_test.go b/tests/integration/query_providerinfo_test.go new file mode 100644 index 0000000000..8058248310 --- /dev/null +++ b/tests/integration/query_providerinfo_test.go @@ -0,0 +1,17 @@ +package integration + +func (s *CCVTestSuite) TestQueryProviderInfo() { + s.SetupCCVChannel(s.path) + s.SendEmptyVSCPacket() + + chainInfo, err := s.consumerApp.GetConsumerKeeper().GetProviderInfo(s.consumerCtx()) + s.Require().NoError(err) + s.Require().Equal(chainInfo.Provider.ChainID, "testchain1") + s.Require().Equal(chainInfo.Consumer.ChainID, "testchain2") + s.Require().Equal(chainInfo.Provider.ClientID, "07-tendermint-0") + s.Require().Equal(chainInfo.Consumer.ClientID, "07-tendermint-0") + s.Require().Equal(chainInfo.Provider.ConnectionID, "connection-0") + s.Require().Equal(chainInfo.Consumer.ConnectionID, "connection-0") + s.Require().Equal(chainInfo.Provider.ChannelID, "channel-0") + s.Require().Equal(chainInfo.Consumer.ChannelID, "channel-0") +} diff --git a/tests/integration/setup.go b/tests/integration/setup.go index 8db75519c0..4628ca3111 100644 --- a/tests/integration/setup.go +++ b/tests/integration/setup.go @@ -23,6 +23,8 @@ import ( icstestingutils "github.com/cosmos/interchain-security/v3/testutil/ibc_testing" testutil "github.com/cosmos/interchain-security/v3/testutil/integration" "github.com/cosmos/interchain-security/v3/testutil/simibc" + consumertypes "github.com/cosmos/interchain-security/v3/x/ccv/consumer/types" + "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" ccv "github.com/cosmos/interchain-security/v3/x/ccv/types" ) @@ -128,6 +130,9 @@ func (suite *CCVTestSuite) SetupTest() { 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 @@ -147,8 +152,12 @@ func (suite *CCVTestSuite) SetupTest() { chainID, ) suite.Require().True(found, "consumer genesis not found") - - initConsumerChain(suite, chainID, &consumerGenesisState) + genesisState := consumertypes.GenesisState{ + Params: consumerGenesisState.Params, + Provider: consumerGenesisState.Provider, + NewChain: consumerGenesisState.NewChain, + } + initConsumerChain(suite, chainID, &genesisState) } // try updating all clients @@ -182,7 +191,7 @@ func (s *CCVTestSuite) getSentPacket(chain *ibctesting.TestChain, sequence uint6 func initConsumerChain( s *CCVTestSuite, chainID string, - genesisState *ccv.ConsumerGenesisState, + genesisState *consumertypes.GenesisState, ) { providerKeeper := s.providerApp.GetProviderKeeper() bundle := s.consumerBundles[chainID] @@ -199,8 +208,8 @@ func initConsumerChain( if genesisState.NewChain { consumerEndpointClientState, consumerEndpointConsState := s.GetConsumerEndpointClientAndConsState(*bundle) - s.Require().Equal(genesisState.ProviderClientState, consumerEndpointClientState) - s.Require().Equal(genesisState.ProviderConsensusState, consumerEndpointConsState) + s.Require().Equal(genesisState.Provider.ClientState, consumerEndpointClientState) + s.Require().Equal(genesisState.Provider.ConsensusState, consumerEndpointConsState) } // create path for the CCV channel diff --git a/tests/integration/slashing.go b/tests/integration/slashing.go index f1be51d33c..4058494974 100644 --- a/tests/integration/slashing.go +++ b/tests/integration/slashing.go @@ -72,32 +72,34 @@ func (s *CCVTestSuite) TestRelayAndApplyDowntimePacket() { timeoutHeight = clienttypes.Height{} timeoutTimestamp = uint64(s.getFirstBundle().GetCtx().BlockTime().Add(ccv.DefaultCCVTimeoutPeriod).UnixNano()) ) - slashPacket := s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmVal, stakingtypes.Infraction_INFRACTION_DOWNTIME) - sequence, err := s.getFirstBundle().Path.EndpointA.SendPacket(timeoutHeight, timeoutTimestamp, slashPacket.GetBytes()) + slashPacket := s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmVal, stakingtypes.Infraction_INFRACTION_DOWNTIME, 1) + sequence, err := s.getFirstBundle().Path.EndpointA.SendPacket(timeoutHeight, timeoutTimestamp, slashPacket.GetData()) s.Require().NoError(err) // Set outstanding slashing flag for first consumer, it's important to use the consumer's cons addr here firstConsumerKeeper.SetOutstandingDowntime(s.consumerCtx(), consumerConsAddr.ToSdkConsAddr()) // Note: RecvPacket advances two blocks. Let's say the provider is currently at height N. - // The received slash packet will be queued during N, and handled by the ccv module during - // the endblocker of N. The staking module will then register a validator update from that - // packet during the endblocker of N+1 (note that staking endblocker runs before ccv endblocker, - // hence why the VSC is registered on N+1). Then the ccv module sends VSC packets to each consumer - // during the endblocker of N+1. The new validator set will be committed to in block N+2, - // and will be in effect for the provider during block N+3. + // The received slash packet will be handled during N. The staking module will then register + // a validator update from that packet during the endblocker of N. Then the ccv module sends + // VSC packets to each consumer during the endblocker of N (note ccv endblocker runs after staking). + // The new validator set will be committed to in block N+1, and will be in effect + // for the provider during block N+2. valsetUpdateIdN := providerKeeper.GetValidatorSetUpdateId(s.providerCtx()) // receive the slash packet on the provider chain. RecvPacket() calls the provider endblocker twice - packet := s.newPacketFromConsumer(slashPacket.GetBytes(), sequence, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp) + packet := s.newPacketFromConsumer(slashPacket.GetData(), sequence, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp) + heightBefore := s.providerCtx().BlockHeight() err = s.path.EndpointB.RecvPacket(packet) + heightAfter := s.providerCtx().BlockHeight() s.Require().NoError(err) + s.Require().Equal(heightBefore+2, heightAfter) // We've now advanced two blocks. - // VSC packets should have been sent from provider during block N+1 to each consumer - expectedSentValsetUpdateId := valsetUpdateIdN + 1 + // VSC packets should have been sent from provider during block N to each consumer + expectedSentValsetUpdateId := valsetUpdateIdN for _, bundle := range s.consumerBundles { _, found := providerKeeper.GetVscSendTimestamp(s.providerCtx(), bundle.Chain.ChainID, expectedSentValsetUpdateId) @@ -109,10 +111,7 @@ func (s *CCVTestSuite) TestRelayAndApplyDowntimePacket() { s.Require().Equal(valsetUpdateIdN+2, providerKeeper.GetValidatorSetUpdateId(s.providerCtx())) - // Call next block so provider is now on block N + 3 mentioned above - s.providerChain.NextBlock() - - // check that the validator was removed from the provider validator set by N + 3 + // check that the validator was removed from the provider validator set by N + 2 s.Require().Len(s.providerChain.Vals.Validators, validatorsPerChain-1) for _, bundle := range s.consumerBundles { @@ -156,9 +155,10 @@ func (s *CCVTestSuite) TestRelayAndApplyDowntimePacket() { pFlag := firstConsumerKeeper.OutstandingDowntime(s.consumerCtx(), consumerConsAddr.ToSdkConsAddr()) s.Require().False(pFlag) - // check that slashing packet gets acknowledged successfully - ack := channeltypes.NewResultAcknowledgement([]byte{byte(1)}) - err = s.path.EndpointA.AcknowledgePacket(packet, ack.Acknowledgement()) + // Check that first consumer can recv ack from provider. + // Provider has returned SlashPacketHandledResult. + ack := channeltypes.NewResultAcknowledgement(ccv.SlashPacketHandledResult) + err = s.getFirstBundle().Path.EndpointA.AcknowledgePacket(packet, ack.Acknowledgement()) s.Require().NoError(err) } @@ -205,8 +205,8 @@ func (s *CCVTestSuite) TestRelayAndApplyDoubleSignPacket() { timeoutHeight = clienttypes.Height{} timeoutTimestamp = uint64(s.getFirstBundle().GetCtx().BlockTime().Add(ccv.DefaultCCVTimeoutPeriod).UnixNano()) ) - slashPacket := s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmVal, stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN) - packet := sendOnConsumerRecvOnProvider(s, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp, slashPacket.GetBytes()) + slashPacket := s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmVal, stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN, 1) + packet := sendOnConsumerRecvOnProvider(s, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp, slashPacket.GetData()) // Advance a few more blocks to make sure any voting power changes would be reflected s.providerChain.NextBlock() @@ -238,8 +238,9 @@ func (s *CCVTestSuite) TestRelayAndApplyDoubleSignPacket() { // check that validator was NOT tombstoned on provider s.Require().False(valSignInfo.Tombstoned) - // check that slashing packet gets acknowledged successfully - ack := channeltypes.NewResultAcknowledgement([]byte{byte(1)}) + // check that slashing packet gets acknowledged successfully, + // provider returns V1Result acks for double sign packets + ack := channeltypes.NewResultAcknowledgement(ccv.V1Result) err = s.path.EndpointA.AcknowledgePacket(packet, ack.Acknowledgement()) s.Require().NoError(err) } @@ -429,16 +430,10 @@ func (suite *CCVTestSuite) TestOnRecvSlashPacketErrors() { errAck = providerKeeper.OnRecvSlashPacket(ctx, packet, *slashingPkt) suite.Require().False(errAck.Success()) - // Expect nothing was queued - suite.Require().Equal(0, len(providerKeeper.GetAllGlobalSlashEntries(ctx))) - suite.Require().Equal(uint64(0), (providerKeeper.GetThrottledPacketDataSize(ctx, consumerChainID))) - // expect to queue entries for the slash request slashingPkt.Infraction = stakingtypes.Infraction_INFRACTION_DOWNTIME ack = providerKeeper.OnRecvSlashPacket(ctx, packet, *slashingPkt) suite.Require().True(ack.Success()) - suite.Require().Equal(1, len(providerKeeper.GetAllGlobalSlashEntries(ctx))) - suite.Require().Equal(uint64(1), (providerKeeper.GetThrottledPacketDataSize(ctx, consumerChainID))) } // TestValidatorDowntime tests if a slash packet is sent diff --git a/tests/integration/stop_consumer.go b/tests/integration/stop_consumer.go index b3d32ee6a4..452b28e3b1 100644 --- a/tests/integration/stop_consumer.go +++ b/tests/integration/stop_consumer.go @@ -6,7 +6,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" ccv "github.com/cosmos/interchain-security/v3/x/ccv/types" ) @@ -80,33 +79,6 @@ func (s *CCVTestSuite) TestStopConsumerChain() { return nil }, }, - { - func(suite *CCVTestSuite) error { - // Queue slash and vsc packet data for consumer 0, these queue entries will be removed - firstBundle := s.getFirstBundle() - globalEntry := types.NewGlobalSlashEntry(s.providerCtx().BlockTime(), firstBundle.Chain.ChainID, 7, types.ProviderConsAddress{Address: []byte{}}) - providerKeeper.QueueGlobalSlashEntry(s.providerCtx(), globalEntry) - err := providerKeeper.QueueThrottledSlashPacketData(s.providerCtx(), firstBundle.Chain.ChainID, 1, - ccv.SlashPacketData{ValsetUpdateId: 1}) - suite.Require().NoError(err) - err = providerKeeper.QueueThrottledVSCMaturedPacketData(s.providerCtx(), - firstBundle.Chain.ChainID, 2, ccv.VSCMaturedPacketData{ValsetUpdateId: 2}) - suite.Require().NoError(err) - - // Queue slash and vsc packet data for consumer 1, these queue entries will be not be removed - secondBundle := s.getBundleByIdx(1) - globalEntry = types.NewGlobalSlashEntry(s.providerCtx().BlockTime(), secondBundle.Chain.ChainID, 7, types.ProviderConsAddress{Address: []byte{}}) - providerKeeper.QueueGlobalSlashEntry(s.providerCtx(), globalEntry) - err = providerKeeper.QueueThrottledSlashPacketData(s.providerCtx(), secondBundle.Chain.ChainID, 1, - ccv.SlashPacketData{ValsetUpdateId: 1}) - suite.Require().NoError(err) - err = providerKeeper.QueueThrottledVSCMaturedPacketData(s.providerCtx(), - secondBundle.Chain.ChainID, 2, ccv.VSCMaturedPacketData{ValsetUpdateId: 2}) - suite.Require().NoError(err) - - return nil - }, - }, } for _, so := range setupOperations { @@ -120,15 +92,6 @@ func (s *CCVTestSuite) TestStopConsumerChain() { // check all states are removed and the unbonding operation released s.checkConsumerChainIsRemoved(firstBundle.Chain.ChainID, true) - - // check entries related to second consumer chain are not removed - s.Require().Len(providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()), 1) - - secondBundle := s.getBundleByIdx(1) - slashData, vscMaturedData, _, _ := providerKeeper.GetAllThrottledPacketData( - s.providerCtx(), secondBundle.Chain.ChainID) - s.Require().Len(slashData, 1) - s.Require().Len(vscMaturedData, 1) } // TODO Simon: implement OnChanCloseConfirm in IBC-GO testing to close the consumer chain's channel end @@ -199,15 +162,4 @@ func (s *CCVTestSuite) checkConsumerChainIsRemoved(chainID string, checkChannel s.Require().Nil(providerKeeper.GetSlashAcks(s.providerCtx(), chainID)) s.Require().Zero(providerKeeper.GetInitChainHeight(s.providerCtx(), chainID)) s.Require().Empty(providerKeeper.GetPendingVSCPackets(s.providerCtx(), chainID)) - - // No remaining global entries for this consumer - allGlobalEntries := providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()) - for _, entry := range allGlobalEntries { - s.Require().NotEqual(chainID, entry.ConsumerChainID) - } - - // No remaining per-chain entries for this consumer - slashData, vscMaturedData, _, _ := providerKeeper.GetAllThrottledPacketData(s.providerCtx(), chainID) - s.Require().Empty(slashData) - s.Require().Empty(vscMaturedData) } diff --git a/tests/integration/throttle.go b/tests/integration/throttle.go index 7c83529262..f186077a07 100644 --- a/tests/integration/throttle.go +++ b/tests/integration/throttle.go @@ -30,10 +30,34 @@ func (s *CCVTestSuite) TestBasicSlashPacketThrottling() { expectedAllowanceAfterFirstSlash int64 expectedReplenishesTillPositive int }{ - {"0.2", 800, -200, 600, 1}, - {"0.1", 400, -600, 300, 3}, // 600/300 = 2, so 3 replenishes to reach positive - {"0.05", 200, -800, 150, 6}, - {"0.01", 40, -960, 30, 33}, // 960/30 = 32, so 33 replenishes to reach positive + { + "0.2", + 800, // replenishFraction * totalPower: 0.2 * 4000 + -200, // expectedMeterBeforeFirstSlash - power(V0): 800 - 1000 + 600, // replenishFraction * newTotalPower: 0.2 * 3000 + 1, // ceil((200+1)/600) + }, + { + "0.1", + 400, // replenishFraction * totalPower: 0.1 * 4000 + -600, // expectedMeterBeforeFirstSlash - power(V0): 400 - 1000 + 300, // replenishFraction * newTotalPower: 0.1 * 3000 + 3, // ceil((600+1)/300) + }, + { + "0.05", + 200, // replenishFraction * totalPower: 0.05 * 4000 + -800, // expectedMeterBeforeFirstSlash - power(V0): 200 - 1000 + 150, // replenishFraction * newTotalPower: 0.05 * 3000 + 6, // ceil((800+1)/150) + }, + { + "0.01", + 40, // replenishFraction * totalPower: 0.01 * 4000 + -960, // expectedMeterBeforeFirstSlash - power(V0): 40 - 1000 + 30, // replenishFraction * newTotalPower: 0.01 * 3000 + 33, // ceil((960+1)/30) + }, } for _, tc := range testCases { @@ -67,8 +91,8 @@ func (s *CCVTestSuite) TestBasicSlashPacketThrottling() { // Send a slash packet from consumer to provider s.setDefaultValSigningInfo(*s.providerChain.Vals.Validators[0]) tmVal := s.providerChain.Vals.Validators[0] - slashPacket := s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmVal, stakingtypes.Infraction_INFRACTION_DOWNTIME) - sendOnConsumerRecvOnProvider(s, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp, slashPacket.GetBytes()) + slashPacket := s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmVal, stakingtypes.Infraction_INFRACTION_DOWNTIME, 1) + sendOnConsumerRecvOnProvider(s, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp, slashPacket.GetData()) // Assert validator 0 is jailed and has no power vals = providerStakingKeeper.GetAllValidators(s.providerCtx()) @@ -86,10 +110,11 @@ func (s *CCVTestSuite) TestBasicSlashPacketThrottling() { // Now send a second slash packet from consumer to provider for a different validator. s.setDefaultValSigningInfo(*s.providerChain.Vals.Validators[2]) tmVal = s.providerChain.Vals.Validators[2] - slashPacket = s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmVal, stakingtypes.Infraction_INFRACTION_DOWNTIME) - sendOnConsumerRecvOnProvider(s, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp, slashPacket.GetBytes()) + slashPacket = s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmVal, stakingtypes.Infraction_INFRACTION_DOWNTIME, 2) + sendOnConsumerRecvOnProvider(s, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp, slashPacket.GetData()) - // Require that slash packet has not been handled + // 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()) s.Require().False(vals[2].IsJailed()) @@ -139,11 +164,14 @@ func (s *CCVTestSuite) TestBasicSlashPacketThrottling() { slashMeter = s.providerApp.GetProviderKeeper().GetSlashMeter(cacheCtx) s.Require().True(slashMeter.IsPositive()) - // Assert validator 2 is jailed once pending slash packets are handled in ccv endblocker. - s.providerChain.NextBlock() - vals = providerStakingKeeper.GetAllValidators(cacheCtx) - slashedVal = vals[2] - s.Require().True(slashedVal.IsJailed()) + // Assert validator 2 is jailed once slash packet is retried. + tmVal2 := s.providerChain.Vals.Validators[2] + packet := s.constructSlashPacketFromConsumer(s.getFirstBundle(), + *tmVal2, stakingtypes.Infraction_INFRACTION_DOWNTIME, 3) // make sure to use a new seq num + sendOnConsumerRecvOnProvider(s, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp, packet.GetData()) + + stakingVal2 := s.mustGetStakingValFromTmVal(*tmVal2) + s.Require().True(stakingVal2.IsJailed()) // Assert validator 2 has no power, this should be apparent next block, // since the staking endblocker runs before the ccv endblocker. @@ -160,26 +188,12 @@ func (s *CCVTestSuite) TestMultiConsumerSlashPacketThrottling() { s.SetupAllCCVChannels() s.setupValidatorPowers() - providerKeeper := s.providerApp.GetProviderKeeper() - providerStakingKeeper := s.providerApp.GetTestStakingKeeper() - - // First confirm that VSC matured packets are handled immediately (not queued) - // when no slash packets are sent. - - // Send 2 VSC matured packets from every consumer to provider var ( timeoutHeight = clienttypes.Height{} timeoutTimestamp = uint64(s.getFirstBundle().GetCtx().BlockTime().Add(ccvtypes.DefaultCCVTimeoutPeriod).UnixNano()) ) - for consumerChainID, bundle := range s.consumerBundles { - slashPacket := s.constructVSCMaturedPacketFromConsumer(*bundle) - sendOnConsumerRecvOnProvider(s, bundle.Path, timeoutHeight, timeoutTimestamp, slashPacket.GetBytes()) - slashPacket = s.constructVSCMaturedPacketFromConsumer(*bundle) - sendOnConsumerRecvOnProvider(s, bundle.Path, timeoutHeight, timeoutTimestamp, slashPacket.GetBytes()) - // Confirm packets were not queued on provider for this consumer - s.Require().Equal(uint64(0), - providerKeeper.GetThrottledPacketDataSize(s.providerCtx(), consumerChainID)) - } + + providerStakingKeeper := s.providerApp.GetTestStakingKeeper() // Choose 3 consumer bundles. It doesn't matter which ones. idx := 0 @@ -192,7 +206,7 @@ func (s *CCVTestSuite) TestMultiConsumerSlashPacketThrottling() { idx++ } - // Send some packets to provider from the 3 chosen consumers. + // Send some slash packets to provider from the 3 chosen consumers. // They will each slash a different validator according to idx. idx = 0 valsToSlash := []tmtypes.Validator{} @@ -208,53 +222,70 @@ func (s *CCVTestSuite) TestMultiConsumerSlashPacketThrottling() { *bundle, *tmVal, stakingtypes.Infraction_INFRACTION_DOWNTIME, + 1, // all consumers use 1 seq num ) - sendOnConsumerRecvOnProvider(s, bundle.Path, timeoutHeight, timeoutTimestamp, slashPacket.GetBytes()) - - // Send two trailing VSC matured packets from consumer to provider - slashPacket = s.constructVSCMaturedPacketFromConsumer(*bundle) - sendOnConsumerRecvOnProvider(s, bundle.Path, timeoutHeight, timeoutTimestamp, slashPacket.GetBytes()) - slashPacket = s.constructVSCMaturedPacketFromConsumer(*bundle) - sendOnConsumerRecvOnProvider(s, bundle.Path, timeoutHeight, timeoutTimestamp, slashPacket.GetBytes()) + sendOnConsumerRecvOnProvider(s, bundle.Path, timeoutHeight, timeoutTimestamp, slashPacket.GetData()) idx++ } - // Confirm that the slash packet and trailing VSC matured packet - // were handled immediately for the first consumer (this packet was recv first). + // Confirm that the slash packet for the first consumer was handled (this packet was recv first). s.confirmValidatorJailed(valsToSlash[0], true) - s.Require().Equal(uint64(0), providerKeeper.GetThrottledPacketDataSize( - s.providerCtx(), senderBundles[0].Chain.ChainID)) - // Packets were queued for the second and third consumers. - s.confirmValidatorNotJailed(valsToSlash[1], 1000) - s.Require().Equal(uint64(3), providerKeeper.GetThrottledPacketDataSize( - s.providerCtx(), senderBundles[1].Chain.ChainID)) + // Packets were bounced for the second and third consumers. + s.confirmValidatorNotJailed(valsToSlash[1], 1000) // each validator has 1000 power from the setup s.confirmValidatorNotJailed(valsToSlash[2], 1000) - s.Require().Equal(uint64(3), providerKeeper.GetThrottledPacketDataSize( - s.providerCtx(), senderBundles[2].Chain.ChainID)) - // Total power is now 3000 + // Total power is now 3000 (as one validator was jailed) s.Require().Equal(int64(3000), providerStakingKeeper.GetLastTotalPower(s.providerCtx()).Int64()) // Now replenish the slash meter and confirm one of two queued slash - // packet entries are then handled. Order is irrelevant here since those - // two packets were sent and recv at the same block time when being queued. + // packet entries are then handled, when both are retried. s.replenishSlashMeterTillPositive() - // 1st NextBlock will handle the slash packet, 2nd will update staking module val powers + // Retry from consumer with idx 1 + bundle := senderBundles[1] + packet := s.constructSlashPacketFromConsumer( + *bundle, + valsToSlash[1], + stakingtypes.Infraction_INFRACTION_DOWNTIME, + 2, // seq number is incremented since last try + ) + sendOnConsumerRecvOnProvider(s, bundle.Path, timeoutHeight, timeoutTimestamp, packet.GetData()) + + // retry from consumer with idx 2 + bundle = senderBundles[2] + packet = s.constructSlashPacketFromConsumer( + *bundle, + valsToSlash[2], + stakingtypes.Infraction_INFRACTION_DOWNTIME, + 2, // seq number is incremented since last try + ) + sendOnConsumerRecvOnProvider(s, bundle.Path, timeoutHeight, timeoutTimestamp, packet.GetData()) + + // Call NextBlocks to update staking module val powers s.providerChain.NextBlock() s.providerChain.NextBlock() - // If one of the entires was handled, total power will be 2000 (1000 power was slashed) + // If one of the entires was handled, total power will be 2000 (1000 power was just slashed) s.Require().Equal(int64(2000), providerStakingKeeper.GetLastTotalPower(s.providerCtx()).Int64()) // Now replenish one more time, and handle final slash packet. s.replenishSlashMeterTillPositive() - // 1st NextBlock will handle the slash packet, 2nd will update last validator power + // Retry from consumer with idx 2 + bundle = senderBundles[2] + packet = s.constructSlashPacketFromConsumer( + *bundle, + valsToSlash[2], + stakingtypes.Infraction_INFRACTION_DOWNTIME, + 3, // seq number is incremented since last try + ) + sendOnConsumerRecvOnProvider(s, bundle.Path, timeoutHeight, timeoutTimestamp, packet.GetData()) + + // Call NextBlocks to update staking module val powers s.providerChain.NextBlock() s.providerChain.NextBlock() @@ -267,15 +298,6 @@ func (s *CCVTestSuite) TestMultiConsumerSlashPacketThrottling() { for _, val := range valsToSlash { s.confirmValidatorJailed(val, true) } - s.Require().Equal(uint64(0), providerKeeper.GetThrottledPacketDataSize( - s.providerCtx(), senderBundles[0].Chain.ChainID)) - s.Require().Equal(uint64(0), providerKeeper.GetThrottledPacketDataSize( - s.providerCtx(), senderBundles[1].Chain.ChainID)) - s.Require().Equal(uint64(0), providerKeeper.GetThrottledPacketDataSize( - s.providerCtx(), senderBundles[2].Chain.ChainID)) - - // All global queue entries are gone too - s.Require().Empty(providerKeeper.GetAllGlobalSlashEntries(s.providerCtx())) } // TestPacketSpam confirms that the provider can handle a large number of @@ -319,8 +341,8 @@ func (s *CCVTestSuite) TestPacketSpam() { infractionType = stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN } valToJail := s.providerChain.Vals.Validators[ibcSeqNum%3] - slashPacket := s.constructSlashPacketFromConsumer(firstBundle, *valToJail, infractionType) - packetsData = append(packetsData, slashPacket.GetBytes()) + slashPacket := s.constructSlashPacketFromConsumer(firstBundle, *valToJail, infractionType, ibcSeqNum) + packetsData = append(packetsData, slashPacket.GetData()) } // Recv 500 packets from consumer to provider in same block @@ -335,17 +357,14 @@ func (s *CCVTestSuite) TestPacketSpam() { providerKeeper.OnRecvSlashPacket(s.providerCtx(), packet, *consumerPacketData.GetSlashPacketData()) } - // Execute block to handle packets in endblock + // Execute block s.providerChain.NextBlock() - // Confirm all packets are handled or dropped (queues empty) - s.Require().Equal(uint64(0), providerKeeper.GetThrottledPacketDataSize( - s.providerCtx(), firstBundle.Chain.ChainID)) - slashData, vscMData, _, _ := providerKeeper.GetAllThrottledPacketData( - s.providerCtx(), firstBundle.Chain.ChainID) - s.Require().Empty(slashData) - s.Require().Empty(vscMData) - s.Require().Empty(providerKeeper.GetAllGlobalSlashEntries(s.providerCtx())) + // Confirm 3 expected vals are jailed + for i := 0; i < 3; i++ { + val := s.providerChain.Vals.Validators[i] + s.confirmValidatorJailed(*val, true) + } } func (s *CCVTestSuite) TestDoubleSignDoesNotAffectThrottling() { @@ -379,8 +398,8 @@ func (s *CCVTestSuite) TestDoubleSignDoesNotAffectThrottling() { // Increment ibc seq num for each packet (starting at 1) ibcSeqNum++ valToJail := s.providerChain.Vals.Validators[ibcSeqNum%3] - slashPacket := s.constructSlashPacketFromConsumer(firstBundle, *valToJail, stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN) - packetsData = append(packetsData, slashPacket.GetBytes()) + slashPacket := s.constructSlashPacketFromConsumer(firstBundle, *valToJail, stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN, ibcSeqNum) + packetsData = append(packetsData, slashPacket.GetData()) } // Recv 500 packets from consumer to provider in same block @@ -398,15 +417,6 @@ func (s *CCVTestSuite) TestDoubleSignDoesNotAffectThrottling() { // Execute block to handle packets in endblock s.providerChain.NextBlock() - // Confirm all packets are dropped (queues empty) - s.Require().Equal(uint64(0), providerKeeper.GetThrottledPacketDataSize( - s.providerCtx(), firstBundle.Chain.ChainID)) - slashData, vscMData, _, _ := providerKeeper.GetAllThrottledPacketData( - s.providerCtx(), firstBundle.Chain.ChainID) - s.Require().Empty(slashData) - s.Require().Empty(vscMData) - s.Require().Empty(providerKeeper.GetAllGlobalSlashEntries(s.providerCtx())) - // Confirm that slash meter is not affected s.Require().Equal(providerKeeper.GetSlashMeterAllowance(s.providerCtx()), providerKeeper.GetSlashMeter(s.providerCtx())) @@ -436,162 +446,6 @@ func (s *CCVTestSuite) TestDoubleSignDoesNotAffectThrottling() { } } -// TestQueueOrdering validates that the ordering of slash packet entries -// in the global queue (relevant to a single chain) matches the ordering of slash packet -// data in the chain specific queues, even in the presence of packet spam. -// -// Note: The global queue is ordered by: time, then IBC sequence number, see GlobalSlashEntryKey. -// The chain specific queue is ordered by: IBC sequence number, see ThrottledPacketDataKey. -func (s *CCVTestSuite) TestQueueOrdering() { - // Setup ccv channels to all consumers - s.SetupAllCCVChannels() - - // Setup validator powers to be 25%, 25%, 25%, 25% - s.setupValidatorPowers() - - // Explicitly set params, initialize slash meter - providerKeeper := s.providerApp.GetProviderKeeper() - params := providerKeeper.GetParams(s.providerCtx()) - params.SlashMeterReplenishFraction = "0.05" // 5% total power can be jailed - providerKeeper.SetParams(s.providerCtx(), params) - providerKeeper.InitializeSlashMeter(s.providerCtx()) - - // The packets to be recv in a single block, ordered as they will be recv. - var packetsData [][]byte - - firstBundle := s.getFirstBundle() - - // Slash first 3 but not 4th validator - s.setDefaultValSigningInfo(*s.providerChain.Vals.Validators[0]) - s.setDefaultValSigningInfo(*s.providerChain.Vals.Validators[1]) - s.setDefaultValSigningInfo(*s.providerChain.Vals.Validators[2]) - - // Track and increment ibc seq num for each packet, since these need to be unique. - var ( - ibcSeqNum = uint64(4) - ibcSeqs []uint64 - ) - - for ibcSeqNum < 504 { - // Increment ibc seq num for each packet (starting at 5) - ibcSeqNum++ - ibcSeqs = append(ibcSeqs, ibcSeqNum) - - // Instantiate a vsc matured packet every 10th packet - if ibcSeqNum%10 == 0 { - packetsData = append(packetsData, s.constructVSCMaturedPacketFromConsumer(firstBundle).GetBytes()) - continue - } - // Else instantiate a slash packet - - valToJail := s.providerChain.Vals.Validators[ibcSeqNum%3] - packetsData = append(packetsData, s.constructSlashPacketFromConsumer(firstBundle, *valToJail, stakingtypes.Infraction_INFRACTION_DOWNTIME).GetBytes()) - } - - // Recv 500 packets from consumer to provider in same block - var ( - timeoutHeight = clienttypes.Height{} - timeoutTimestamp = uint64(firstBundle.GetCtx().BlockTime().Add(ccvtypes.DefaultCCVTimeoutPeriod).UnixNano()) - ) - for i, data := range packetsData { - consumerPacketData, err := provider.UnmarshalConsumerPacketData(data) // Same func used by provider's OnRecvPacket - s.Require().NoError(err) - packet := s.newPacketFromConsumer(data, ibcSeqs[i], firstBundle.Path, timeoutHeight, timeoutTimestamp) - // Type depends on index packets were appended from above - if (i+5)%10 == 0 { - vscMaturedPacketData := consumerPacketData.GetVscMaturedPacketData() - vscMaturedPacketData.ValsetUpdateId = uint64(i + 1000) - providerKeeper.OnRecvVSCMaturedPacket(s.providerCtx(), packet, *vscMaturedPacketData) - } else { - // Set valset update id to be 2000 + index to assert ordering - slashPacketData := consumerPacketData.GetSlashPacketData() - slashPacketData.ValsetUpdateId = uint64(i + 2000) - // Set block height mapping so packet is not dropped - providerKeeper.SetValsetUpdateBlockHeight(s.providerCtx(), - slashPacketData.ValsetUpdateId, uint64(firstBundle.GetCtx().BlockHeight())) - providerKeeper.OnRecvSlashPacket(s.providerCtx(), packet, *slashPacketData) - } - } - - // Confirm that global queue has 450 packet entries (500 * 0.9) - allGlobalEntries := providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()) - s.Require().Equal(450, len(allGlobalEntries)) - - // Confirm that the chain specific queue has 450 slash packet data instances, and 50 vsc matured - slashPacketData, vscMaturedPacketData, _, _ := providerKeeper.GetAllThrottledPacketData( - s.providerCtx(), firstBundle.Chain.ChainID) - s.Require().Equal(450, len(slashPacketData)) - s.Require().Equal(50, len(vscMaturedPacketData)) - - // IBC seq numbers of recv slash packets range from 5 to 504. - // Confirm expected global queue ordering. - expectedSeqNum := uint64(5) - for _, globalEntry := range allGlobalEntries { - // entries should be ordered by ibc seq num starting at 5 - s.Require().Equal(expectedSeqNum, globalEntry.IbcSeqNum) - expectedSeqNum++ - if expectedSeqNum%10 == 0 { - // Skip over vsc matured packets - expectedSeqNum++ - } - } - - // Confirm expected chain specific queue ordering. - expectedVscId := uint64(2000) - for _, slashPacket := range slashPacketData { - // entries should be ordered by valset update id starting at 2000 - s.Require().Equal(expectedVscId, slashPacket.ValsetUpdateId) - expectedVscId++ - if (expectedVscId+5)%10 == 0 { - // Skip over vsc matured packets - expectedVscId++ - } - } - for idx, vscMaturedPacket := range vscMaturedPacketData { - // entries should be ordered by valset update id starting at 1005 - // and show up every 10 packets - expectedVscId = uint64(1005) + 10*uint64(idx) - s.Require().Equal(expectedVscId, vscMaturedPacket.ValsetUpdateId) - } - - // Execute endblock to handle packets in throttled manner - s.providerChain.NextBlock() - - // Confirm that only the first packet was handled - allGlobalEntries = providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()) - s.Require().Equal(449, len(allGlobalEntries)) - slashPacketData, vscMaturedPacketData, _, _ = providerKeeper.GetAllThrottledPacketData( - s.providerCtx(), firstBundle.Chain.ChainID) - s.Require().Equal(449, len(slashPacketData)) - // No VSC matured packets should be handled yet - s.Require().Equal(50, len(vscMaturedPacketData)) - - // Replenish frac is 0.05, so jailing %25 of the validators should result in a negative slash meter. - s.Require().True(providerKeeper.GetSlashMeter(s.providerCtx()).IsNegative()) - - // Confirm total power is now 3000 once updated by staking end blocker - s.providerChain.NextBlock() - totalPower := s.providerApp.GetTestStakingKeeper().GetLastTotalPower(s.providerCtx()) - s.Require().Equal(sdk.NewInt(3000), totalPower) - - // Now change replenish frac to 0.67 and fully replenish the meter. - params.SlashMeterReplenishFraction = "0.67" - providerKeeper.SetParams(s.providerCtx(), params) - providerKeeper.InitializeSlashMeter(s.providerCtx()) - - // Execute endblock to handle packets (remaining packets are relevant to 2/3 of the validators) - // so the current replenish frac should be enough to handle all packets this block. - s.providerChain.NextBlock() - - // Confirm both queues are now empty, meaning every packet was handled. - allGlobalEntries = providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()) - s.Require().Equal(0, len(allGlobalEntries)) - slashPacketData, vscMaturedPacketData, _, _ = providerKeeper.GetAllThrottledPacketData( - s.providerCtx(), firstBundle.Chain.ChainID) - s.Require().Equal(0, len(slashPacketData)) - s.Require().Equal(0, len(vscMaturedPacketData)) -} - // TestSlashingSmallValidators tests that multiple slash packets from validators with small // power can be handled by the provider chain in a non-throttled manner. func (s *CCVTestSuite) TestSlashingSmallValidators() { @@ -628,12 +482,12 @@ func (s *CCVTestSuite) TestSlashingSmallValidators() { tmval1 := s.providerChain.Vals.Validators[1] tmval2 := s.providerChain.Vals.Validators[2] tmval3 := s.providerChain.Vals.Validators[3] - slashPacket1 := s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmval1, stakingtypes.Infraction_INFRACTION_DOWNTIME) - slashPacket2 := s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmval2, stakingtypes.Infraction_INFRACTION_DOWNTIME) - slashPacket3 := s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmval3, stakingtypes.Infraction_INFRACTION_DOWNTIME) - sendOnConsumerRecvOnProvider(s, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp, slashPacket1.GetBytes()) - sendOnConsumerRecvOnProvider(s, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp, slashPacket2.GetBytes()) - sendOnConsumerRecvOnProvider(s, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp, slashPacket3.GetBytes()) + slashPacket1 := s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmval1, stakingtypes.Infraction_INFRACTION_DOWNTIME, 1) + slashPacket2 := s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmval2, stakingtypes.Infraction_INFRACTION_DOWNTIME, 2) + slashPacket3 := s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmval3, stakingtypes.Infraction_INFRACTION_DOWNTIME, 3) + sendOnConsumerRecvOnProvider(s, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp, slashPacket1.GetData()) + sendOnConsumerRecvOnProvider(s, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp, slashPacket2.GetData()) + 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()) @@ -675,64 +529,6 @@ func (s *CCVTestSuite) TestSlashMeterAllowanceChanges() { s.Require().Equal(int64(1200), providerKeeper.GetSlashMeterAllowance(s.providerCtx()).Int64()) } -// TestSlashSameValidator tests the edge case that that the total slashed validator power -// queued up for a single block exceeds the slash meter allowance, -// but some of the slash packets are for the same validator, and therefore some packets -// will be applied to a validator that is already jailed but still not unbonded (ie. still slashable). -func (s *CCVTestSuite) TestSlashSameValidator() { - s.SetupAllCCVChannels() - - // Setup 4 validators with 25% of the total power each. - s.setupValidatorPowers() - - providerKeeper := s.providerApp.GetProviderKeeper() - - // Set replenish fraction to 1.0 so that all sent packets should handled immediately (no throttling) - params := providerKeeper.GetParams(s.providerCtx()) - params.SlashMeterReplenishFraction = fullSlashMeterString // needs to be const for linter - providerKeeper.SetParams(s.providerCtx(), params) - providerKeeper.InitializeSlashMeter(s.providerCtx()) - - // Send a downtime and double-sign slash packet for 3/4 validators - // This will have a total slashing power of 150% total power. - tmval1 := s.providerChain.Vals.Validators[1] - tmval2 := s.providerChain.Vals.Validators[2] - tmval3 := s.providerChain.Vals.Validators[3] - s.setDefaultValSigningInfo(*tmval1) - s.setDefaultValSigningInfo(*tmval2) - s.setDefaultValSigningInfo(*tmval3) - - packetsData := [][]byte{ - s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmval1, stakingtypes.Infraction_INFRACTION_DOWNTIME).GetBytes(), - s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmval2, stakingtypes.Infraction_INFRACTION_DOWNTIME).GetBytes(), - s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmval3, stakingtypes.Infraction_INFRACTION_DOWNTIME).GetBytes(), - s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmval1, stakingtypes.Infraction_INFRACTION_DOWNTIME).GetBytes(), - s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmval2, stakingtypes.Infraction_INFRACTION_DOWNTIME).GetBytes(), - s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmval3, stakingtypes.Infraction_INFRACTION_DOWNTIME).GetBytes(), - } - - // Recv and queue all slash packets. - var ( - timeoutHeight = clienttypes.Height{} - timeoutTimestamp = uint64(s.getFirstBundle().GetCtx().BlockTime().Add(ccvtypes.DefaultCCVTimeoutPeriod).UnixNano()) - ) - for i, data := range packetsData { - consumerPacketData, err := provider.UnmarshalConsumerPacketData(data) // Same func used by provider's OnRecvPacket - s.Require().NoError(err) - packet := s.newPacketFromConsumer(data, uint64(i), s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp) - providerKeeper.OnRecvSlashPacket(s.providerCtx(), packet, *consumerPacketData.GetSlashPacketData()) - } - - // We should have 6 pending slash packet entries queued. - s.Require().Len(providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()), 6) - - // Call next block to process all pending slash packets in end blocker. - s.providerChain.NextBlock() - - // All slash packets should have been handled immediately, even though they totaled to 150% of total power. - s.Require().Len(providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()), 0) -} - // Similar to TestSlashSameValidator, but 100% of val power is jailed a single block, // and in the first packets recv for that block. // This edge case should not occur in practice, but is useful to validate that @@ -758,17 +554,20 @@ func (s CCVTestSuite) TestSlashAllValidators() { //nolint:govet // this is a tes // Instantiate a slash packet for each validator, // these first 4 packets should jail 100% of the total power. + ibcSeqNum := uint64(1) for _, val := range s.providerChain.Vals.Validators { s.setDefaultValSigningInfo(*val) packetsData = append(packetsData, s.constructSlashPacketFromConsumer( - s.getFirstBundle(), *val, stakingtypes.Infraction_INFRACTION_DOWNTIME).GetBytes()) + s.getFirstBundle(), *val, stakingtypes.Infraction_INFRACTION_DOWNTIME, ibcSeqNum).GetData()) + ibcSeqNum++ } // add 5 more slash packets for each validator, that will be handled in the same block. for _, val := range s.providerChain.Vals.Validators { for i := 0; i < 5; i++ { packetsData = append(packetsData, s.constructSlashPacketFromConsumer( - s.getFirstBundle(), *val, stakingtypes.Infraction_INFRACTION_DOWNTIME).GetBytes()) + s.getFirstBundle(), *val, stakingtypes.Infraction_INFRACTION_DOWNTIME, ibcSeqNum).GetData()) + ibcSeqNum++ } } @@ -785,17 +584,7 @@ func (s CCVTestSuite) TestSlashAllValidators() { //nolint:govet // this is a tes providerKeeper.OnRecvSlashPacket(s.providerCtx(), packet, *consumerPacketData.GetSlashPacketData()) } - // We should have 24 pending slash packet entries queued. - s.Require().Len(providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()), 24) - - // Call next block to process all pending slash packets in end blocker. - s.providerChain.NextBlock() - - // All slash packets should have been handled immediately, - // even though the first 4 packets jailed 100% of the total power. - s.Require().Len(providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()), 0) - - // Sanity check that all validators are jailed. + // Check that all validators are jailed. for _, val := range s.providerChain.Vals.Validators { // Do not check power, since val power is not yet updated by staking endblocker. s.confirmValidatorJailed(*val, false) @@ -805,162 +594,6 @@ func (s CCVTestSuite) TestSlashAllValidators() { //nolint:govet // this is a tes // "applying the validator changes would result in empty set". } -func (s *CCVTestSuite) TestLeadingVSCMaturedAreDequeued() { - s.SetupAllCCVChannels() - providerKeeper := s.providerApp.GetProviderKeeper() - - // Queue up 50 vsc matured packets for each consumer - var ( - timeoutHeight = clienttypes.Height{} - timeoutTimestamp = uint64(s.getFirstBundle().GetCtx().BlockTime().Add(ccvtypes.DefaultCCVTimeoutPeriod).UnixNano()) - ) - for _, bundle := range s.consumerBundles { - for i := 0; i < 50; i++ { - ibcSeqNum := uint64(i) - data := s.constructVSCMaturedPacketFromConsumer(*bundle).GetBytes() - packetData, err := provider.UnmarshalConsumerPacketData(data) // Same func used by provider's OnRecvPacket - s.Require().NoError(err) - packet := s.newPacketFromConsumer(data, ibcSeqNum, bundle.Path, timeoutHeight, timeoutTimestamp) - providerKeeper.OnRecvVSCMaturedPacket(s.providerCtx(), - packet, *packetData.GetVscMaturedPacketData()) - } - } - - // Queue up 50 slash packets for each consumer - for _, bundle := range s.consumerBundles { - for i := 50; i < 100; i++ { - ibcSeqNum := uint64(i) - data := s.constructSlashPacketFromConsumer(*bundle, - *s.providerChain.Vals.Validators[0], stakingtypes.Infraction_INFRACTION_DOWNTIME).GetBytes() - packetData, err := provider.UnmarshalConsumerPacketData(data) // Same func used by provider's OnRecvPacket - s.Require().NoError(err) - packet := s.newPacketFromConsumer(data, ibcSeqNum, bundle.Path, timeoutHeight, timeoutTimestamp) - providerKeeper.OnRecvSlashPacket(s.providerCtx(), - packet, *packetData.GetSlashPacketData()) - } - } - - // Queue up another 50 vsc matured packets for each consumer - for _, bundle := range s.consumerBundles { - for i := 100; i < 150; i++ { - ibcSeqNum := uint64(i) - data := s.constructVSCMaturedPacketFromConsumer(*bundle).GetBytes() - packetData := ccvtypes.ConsumerPacketData{} - ccvtypes.ModuleCdc.MustUnmarshalJSON(data, &packetData) - packet := s.newPacketFromConsumer(data, ibcSeqNum, bundle.Path, timeoutHeight, timeoutTimestamp) - providerKeeper.OnRecvVSCMaturedPacket(s.providerCtx(), - packet, *packetData.GetVscMaturedPacketData()) - } - } - - // Confirm queue size is 150 for each consumer-specific queue. - for _, bundle := range s.consumerBundles { - s.Require().Equal(uint64(150), - providerKeeper.GetThrottledPacketDataSize(s.providerCtx(), bundle.Chain.ChainID)) - } - // Confirm global queue size is 50 * 5 (50 slash packets for each of 5 consumers) - globalEntries := providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()) - s.Require().Equal(len(globalEntries), 50*5) - - // Set slash meter to negative value to not allow any slash packets to be handled. - providerKeeper.SetSlashMeter(s.providerCtx(), sdk.NewInt(-1)) - - // Set replenish time candidate so that no replenishment happens next block. - providerKeeper.SetSlashMeterReplenishTimeCandidate(s.providerCtx()) - - // Execute end blocker to dequeue only the leading vsc matured packets. - // Note we must call the end blocker three times, since only 100 vsc matured packets can be handled - // each block, and we have 5*50=250 total. - s.providerChain.NextBlock() - s.providerChain.NextBlock() - s.providerChain.NextBlock() - - // Confirm queue size is 100 for each consumer-specific queue (50 leading vsc matured are dequeued). - for _, bundle := range s.consumerBundles { - s.Require().Equal(uint64(100), - providerKeeper.GetThrottledPacketDataSize(s.providerCtx(), bundle.Chain.ChainID)) - } - - // No slash packets handled, global slash queue is same size as last block. - globalEntries = providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()) - s.Require().Equal(len(globalEntries), 50*5) - - // No slash packets handled even if we call end blocker a couple more times. - s.providerChain.NextBlock() - s.providerChain.NextBlock() - globalEntries = providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()) - s.Require().Equal(len(globalEntries), 50*5) -} - -// TestVscMaturedHandledPerBlockLimit tests that only 100 vsc matured packets are handled per block, -// specifically from HandleThrottleQueues(). -// -// Note the vsc matured per block limit is also tested in, TestLeadingVSCMaturedAreDequeued, -// specifically in the context of HandleLeadingVSCMaturedPackets(). -func (s *CCVTestSuite) TestVscMaturedHandledPerBlockLimit() { - s.SetupAllCCVChannels() - providerKeeper := s.providerApp.GetProviderKeeper() - - // Set replenish fraction to 1.0 so that all sent packets should be handled immediately (no jail throttling) - params := providerKeeper.GetParams(s.providerCtx()) - params.SlashMeterReplenishFraction = fullSlashMeterString // needs to be const for linter - providerKeeper.SetParams(s.providerCtx(), params) - providerKeeper.InitializeSlashMeter(s.providerCtx()) - - // Queue up 100 vsc matured packets for each consumer - var ( - timeoutHeight = clienttypes.Height{} - timeoutTimestamp = uint64(s.getFirstBundle().GetCtx().BlockTime().Add(ccvtypes.DefaultCCVTimeoutPeriod).UnixNano()) - ) - for _, bundle := range s.consumerBundles { - for i := 0; i < 100; i++ { - ibcSeqNum := uint64(i) - data := s.constructVSCMaturedPacketFromConsumer(*bundle).GetBytes() - packetData := ccvtypes.ConsumerPacketData{} - ccvtypes.ModuleCdc.MustUnmarshalJSON(data, &packetData) - packet := s.newPacketFromConsumer(data, ibcSeqNum, bundle.Path, timeoutHeight, timeoutTimestamp) - providerKeeper.OnRecvVSCMaturedPacket(s.providerCtx(), - packet, *packetData.GetVscMaturedPacketData()) - } - } - - // Queue up 50 slash packets for each consumer, with new IBC sequence numbers - for _, bundle := range s.consumerBundles { - for i := 100; i < 150; i++ { - ibcSeqNum := uint64(i) - data := s.constructSlashPacketFromConsumer(*bundle, - *s.providerChain.Vals.Validators[0], stakingtypes.Infraction_INFRACTION_DOWNTIME).GetBytes() - consumderPacketData, err := provider.UnmarshalConsumerPacketData(data) // Same func used by provider's OnRecvPacket - s.Require().NoError(err) - packet := s.newPacketFromConsumer(data, ibcSeqNum, bundle.Path, timeoutHeight, timeoutTimestamp) - providerKeeper.OnRecvSlashPacket(s.providerCtx(), packet, *consumderPacketData.GetSlashPacketData()) - } - } - - // Confirm queue size is 150 for each consumer-specific queue. - for _, bundle := range s.consumerBundles { - s.Require().Equal(uint64(150), - providerKeeper.GetThrottledPacketDataSize(s.providerCtx(), bundle.Chain.ChainID)) - } - // Confirm global queue size is 50 * 5 (50 slash packets for each of 5 consumers) - globalEntries := providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()) - s.Require().Equal(len(globalEntries), 50*5) - - // Note even though there is no jail throttling active, slash packets will not be handled until - // all of the leading vsc matured packets are handled first. This should take 5 blocks. - for i := 0; i < 5; i++ { - s.providerChain.NextBlock() - s.Require().Len(providerKeeper.GetAllGlobalSlashEntries(s.providerCtx()), 250) // global entries remain same size - } - - // Set signing info for val to be jailed, preventing panic - s.setDefaultValSigningInfo(*s.providerChain.Vals.Validators[0]) - - // Now we execute one more block and all 250 of the slash packets should be handled. - s.providerChain.NextBlock() - s.Require().Empty(providerKeeper.GetAllGlobalSlashEntries(s.providerCtx())) // empty global entries = all slash packets handled -} - func (s *CCVTestSuite) confirmValidatorJailed(tmVal tmtypes.Validator, checkPower bool) { sdkVal, found := s.providerApp.GetTestStakingKeeper().GetValidator( s.providerCtx(), sdk.ValAddress(tmVal.Address)) diff --git a/tests/integration/throttle_retry.go b/tests/integration/throttle_retry.go index 4d46b310cf..4b445d5d25 100644 --- a/tests/integration/throttle_retry.go +++ b/tests/integration/throttle_retry.go @@ -1,33 +1,25 @@ package integration import ( - clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" + "time" + channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - provider "github.com/cosmos/interchain-security/v3/x/ccv/provider" - providertypes "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" ccvtypes "github.com/cosmos/interchain-security/v3/x/ccv/types" ) -// TestSlashRetries tests the throttling v2 retry logic. Without provider changes, -// the consumer will queue up a slash packet, the provider will return a v1 result, -// and the consumer will never need to retry. -// -// Once provider changes are made (slash packet queuing is removed), the consumer may retry packets -// via new result acks from the provider. -// -// TODO: This test will need updating once provider changes are made. +// TestSlashRetries tests the throttling v2 retry logic at an integration level. func (s *CCVTestSuite) TestSlashRetries() { s.SetupAllCCVChannels() + s.SendEmptyVSCPacket() // Establish ccv channel s.setupValidatorPowers() // // Provider setup // providerKeeper := s.providerApp.GetProviderKeeper() - providerModule := provider.NewAppModule(&providerKeeper, s.providerApp.GetSubspace(providertypes.ModuleName)) // Initialize slash meter providerKeeper.InitializeSlashMeter(s.providerCtx()) // Assert that we start out with no jailings @@ -36,13 +28,24 @@ func (s *CCVTestSuite) TestSlashRetries() { for _, val := range vals { s.Require().False(val.IsJailed()) } + + // We jail two different validators in this test, referred to as val1 and val2. + // This may or may not correspond to the indexes 1 and 2 in various validator slices, + // depending on how the slice is constructed. + + // The s.providerChain.Vals.Validators set will change depending on jailings, + // so we cache these two val objects now to be the canonical val1 and val2. + tmval1 := s.providerChain.Vals.Validators[1] + tmval2 := s.providerChain.Vals.Validators[2] + // Setup signing info for jailings - s.setDefaultValSigningInfo(*s.providerChain.Vals.Validators[1]) + s.setDefaultValSigningInfo(*tmval1) + s.setDefaultValSigningInfo(*tmval2) // // Consumer setup // - consumerKeeper := s.consumerApp.GetConsumerKeeper() + consumerKeeper := s.getFirstBundle().App.GetConsumerKeeper() // Assert no slash record exists _, found := consumerKeeper.GetSlashRecord(s.consumerCtx()) s.Require().False(found) @@ -51,106 +54,166 @@ func (s *CCVTestSuite) TestSlashRetries() { // Test section: See FSM explanation in throttle_retry.go // - // Construct a mock slash packet from consumer - tmval1 := s.providerChain.Vals.Validators[1] - packetData1 := s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmval1, stakingtypes.Infraction_INFRACTION_DOWNTIME).GetBytes() - var ( - timeoutHeight = clienttypes.Height{} - timeoutTimestamp = uint64(s.getFirstBundle().GetCtx().BlockTime().Add(ccvtypes.DefaultCCVTimeoutPeriod).UnixNano()) - ) - packet1 := s.newPacketFromConsumer(packetData1, 1, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp) - // Mock the sending of the packet on consumer + // Construct a slash packet + packet1, data := s.constructSlashPacketFromConsumerWithData( + s.getFirstBundle(), *tmval1, stakingtypes.Infraction_INFRACTION_DOWNTIME, 1) + + // Append packet to be sent by consumer consumerKeeper.AppendPendingPacket(s.consumerCtx(), ccvtypes.SlashPacket, &ccvtypes.ConsumerPacketData_SlashPacketData{ - SlashPacketData: &ccvtypes.SlashPacketData{}, + SlashPacketData: &data, }, ) - consumerKeeper.UpdateSlashRecordOnSend(s.consumerCtx()) + + sendTime := s.consumerCtx().BlockTime() + + // Advance block on consumer to send pending packet + s.getFirstBundle().Chain.NextBlock() + + // Confirm packet was sent via state that's updated on send slashRecord, found := consumerKeeper.GetSlashRecord(s.consumerCtx()) s.Require().True(found) s.Require().True(slashRecord.WaitingOnReply) + s.Require().NotZero(slashRecord.SendTime) + s.Require().Equal(sendTime, slashRecord.SendTime) s.Require().Len(consumerKeeper.GetPendingPackets(s.consumerCtx()), 1) - // Recv packet on provider and assert ack. Provider should return v1 result. - ack := providerModule.OnRecvPacket(s.providerCtx(), packet1, nil) - expectedv1Ack := channeltypes.NewResultAcknowledgement([]byte(ccvtypes.V1Result)) - s.Require().Equal(expectedv1Ack.Acknowledgement(), ack.Acknowledgement()) + // Packet sending blocked until provider returns slash packet handled ack + s.Require().False(consumerKeeper.PacketSendingPermitted(s.consumerCtx())) + + // Recv packet on provider. + relayAllCommittedPackets(s, s.consumerChain, s.path, ccvtypes.ConsumerPortID, s.path.EndpointA.ChannelID, 1) // Couple blocks pass on provider for provider staking keeper to process jailing s.providerChain.NextBlock() s.providerChain.NextBlock() // Default slash meter replenish fraction is 0.05, so packet should be handled on provider. - vals = s.providerApp.GetTestStakingKeeper().GetAllValidators(s.providerCtx()) - s.Require().True(vals[1].IsJailed()) + stakingVal1 := s.mustGetStakingValFromTmVal(*tmval1) + s.Require().True(stakingVal1.IsJailed()) s.Require().Equal(int64(0), - s.providerApp.GetTestStakingKeeper().GetLastValidatorPower(s.providerCtx(), vals[1].GetOperator())) - s.Require().Equal(uint64(0), providerKeeper.GetThrottledPacketDataSize(s.providerCtx(), - s.getFirstBundle().Chain.ChainID)) + s.providerApp.GetTestStakingKeeper().GetLastValidatorPower(s.providerCtx(), stakingVal1.GetOperator())) // Now slash meter should be negative on provider s.Require().True(s.providerApp.GetProviderKeeper().GetSlashMeter(s.providerCtx()).IsNegative()) // Apply ack back on consumer - ackForConsumer := expectedv1Ack - err := consumerKeeper.OnAcknowledgementPacket(s.consumerCtx(), packet1, ackForConsumer) + expectedAck := channeltypes.NewResultAcknowledgement([]byte(ccvtypes.SlashPacketHandledResult)) + 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 - // Since provider has handled the packet + // Slash record should have been deleted, head of pending packets should have been popped, + // since provider has handled the packet. _, found = consumerKeeper.GetSlashRecord(s.consumerCtx()) s.Require().False(found) s.Require().Empty(consumerKeeper.GetPendingPackets(s.consumerCtx())) + // Packet sending should now be unblocked + s.Require().True(consumerKeeper.PacketSendingPermitted(s.consumerCtx())) + // pass two blocks on provider and consumer for good measure s.providerChain.NextBlock() s.providerChain.NextBlock() s.consumerChain.NextBlock() s.consumerChain.NextBlock() - // Construct and mock the sending of a second packet on consumer - tmval2 := s.providerChain.Vals.Validators[2] - packetData2 := s.constructSlashPacketFromConsumer(s.getFirstBundle(), *tmval2, stakingtypes.Infraction_INFRACTION_DOWNTIME).GetBytes() - packet2 := s.newPacketFromConsumer(packetData2, 1, s.getFirstBundle().Path, timeoutHeight, timeoutTimestamp) - + // Have consumer queue a new slash packet for a different validator. + packet2, data := s.constructSlashPacketFromConsumerWithData( + s.getFirstBundle(), *tmval2, stakingtypes.Infraction_INFRACTION_DOWNTIME, 1) consumerKeeper.AppendPendingPacket(s.consumerCtx(), ccvtypes.SlashPacket, &ccvtypes.ConsumerPacketData_SlashPacketData{ - SlashPacketData: &ccvtypes.SlashPacketData{}, + SlashPacketData: &data, }, ) - consumerKeeper.UpdateSlashRecordOnSend(s.consumerCtx()) + + // Advance block on consumer to send pending packet + sendTime = s.consumerCtx().BlockTime() + s.getFirstBundle().Chain.NextBlock() + + // Confirm packet was sent via state that's updated on send slashRecord, found = consumerKeeper.GetSlashRecord(s.consumerCtx()) s.Require().True(found) s.Require().True(slashRecord.WaitingOnReply) + s.Require().NotZero(slashRecord.SendTime) + s.Require().Equal(sendTime, slashRecord.SendTime) s.Require().Len(consumerKeeper.GetPendingPackets(s.consumerCtx()), 1) - // Recv 2nd slash packet on provider for different validator. - // Provider should return the same v1 result ack even tho the packet was queued. - ack = providerModule.OnRecvPacket(s.providerCtx(), packet2, nil) - expectedv1Ack = channeltypes.NewResultAcknowledgement([]byte(ccvtypes.V1Result)) - s.Require().Equal(expectedv1Ack.Acknowledgement(), ack.Acknowledgement()) + // Packet sending blocked until provider returns slash packet handled ack + s.Require().False(consumerKeeper.PacketSendingPermitted(s.consumerCtx())) + + // Recv 2nd packet on provider. + relayAllCommittedPackets(s, s.consumerChain, s.path, ccvtypes.ConsumerPortID, s.path.EndpointA.ChannelID, 1) // Couple blocks pass on provider for staking keeper to process jailings s.providerChain.NextBlock() s.providerChain.NextBlock() - // Val shouldn't be jailed on provider. Slash packet was queued - s.Require().False(vals[2].IsJailed()) + // 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(), vals[2].GetOperator())) - s.Require().Equal(uint64(1), providerKeeper.GetThrottledPacketDataSize(s.providerCtx(), - s.getFirstBundle().Chain.ChainID)) + providerStakingKeeper.GetLastValidatorPower(s.providerCtx(), stakingVal2.GetOperator())) // Apply ack on consumer - ackForConsumer = expectedv1Ack - err = consumerKeeper.OnAcknowledgementPacket(s.consumerCtx(), packet2, ackForConsumer) + expectedAck = channeltypes.NewResultAcknowledgement([]byte(ccvtypes.SlashPacketBouncedResult)) + err = s.getFirstBundle().Path.EndpointA.AcknowledgePacket(packet2, expectedAck.Acknowledgement()) s.Require().NoError(err) - // TODO: when provider changes are made, slashRecord.WaitingOnReply should have been updated to false on consumer. Slash Packet will still be in consumer's pending packets queue. + // Now consumer should have updated it's slash record on receipt of bounce ack + slashRecord, found = consumerKeeper.GetSlashRecord(s.consumerCtx()) + s.Require().True(found) + s.Require().False(slashRecord.WaitingOnReply) + // Packet still at head of queue + s.Require().Len(consumerKeeper.GetPendingPackets(s.consumerCtx()), 1) + + // Packet sending should still be blocked, WaitingOnReply is false, + // but retry delay hasn't passed yet. + s.Require().False(consumerKeeper.PacketSendingPermitted(s.consumerCtx())) + + // IBC testing framework doesn't have a way to advance time, + // so we manually mutate send time in the slash record to be in the past. + slashRecord.SendTime = slashRecord.SendTime.Add(-time.Hour - time.Minute) + consumerKeeper.SetSlashRecord(s.consumerCtx(), slashRecord) + + s.Require().True(consumerKeeper.PacketSendingPermitted(s.consumerCtx())) + + // Set slash meter on provider to positive value, + // now allowing handling of the slash packet + providerKeeper.InitializeSlashMeter(s.providerCtx()) + + // Advance block on consumer, now consumer should retry the sending of the slash packet. + sendTime = s.consumerCtx().BlockTime() + s.getFirstBundle().Chain.NextBlock() + + // Confirm packet was sent via state that's updated on send + slashRecord, found = consumerKeeper.GetSlashRecord(s.consumerCtx()) + s.Require().True(found) + s.Require().True(slashRecord.WaitingOnReply) + s.Require().NotZero(slashRecord.SendTime) + s.Require().Equal(sendTime, slashRecord.SendTime) + s.Require().Len(consumerKeeper.GetPendingPackets(s.consumerCtx()), 1) + + // Recv retried packet on provider. + relayAllCommittedPackets(s, s.consumerChain, s.path, ccvtypes.ConsumerPortID, s.path.EndpointA.ChannelID, 1) + + // Couple blocks pass on provider for provider staking keeper to process jailing + s.providerChain.NextBlock() + s.providerChain.NextBlock() + + // 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())) + + // Apply ack on consumer + expectedAck = channeltypes.NewResultAcknowledgement([]byte(ccvtypes.SlashPacketHandledResult)) + err = s.getFirstBundle().Path.EndpointA.AcknowledgePacket(packet2, expectedAck.Acknowledgement()) + s.Require().NoError(err) - // Slash record should have been deleted, head of pending packets should have been popped - // Since provider has handled the packet + // Consumer state is properly cleared again _, found = consumerKeeper.GetSlashRecord(s.consumerCtx()) s.Require().False(found) s.Require().Empty(consumerKeeper.GetPendingPackets(s.consumerCtx())) + s.Require().True(consumerKeeper.PacketSendingPermitted(s.consumerCtx())) } diff --git a/testutil/crypto/evidence.go b/testutil/crypto/evidence.go new file mode 100644 index 0000000000..653f20824e --- /dev/null +++ b/testutil/crypto/evidence.go @@ -0,0 +1,135 @@ +package crypto + +import ( + "time" + + ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + + "github.com/cometbft/cometbft/crypto/tmhash" + "github.com/cometbft/cometbft/libs/bytes" + tmtypes "github.com/cometbft/cometbft/types" +) + +// utility function duplicated from CometBFT +// see https://github.com/cometbft/cometbft/blob/main/evidence/verify_test.go#L554 +func MakeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) tmtypes.BlockID { + var ( + h = make([]byte, tmhash.Size) + psH = make([]byte, tmhash.Size) + ) + copy(h, hash) + copy(psH, partSetHash) + return tmtypes.BlockID{ + Hash: h, + PartSetHeader: tmtypes.PartSetHeader{ + Total: partSetSize, + Hash: psH, + }, + } +} + +func MakeAndSignVote( + blockID tmtypes.BlockID, + blockHeight int64, + blockTime time.Time, + valSet *tmtypes.ValidatorSet, + signer tmtypes.PrivValidator, + chainID string, +) *tmtypes.Vote { + vote, err := tmtypes.MakeVote( + blockHeight, + blockID, + valSet, + signer, + chainID, + blockTime, + ) + if err != nil { + panic(err) + } + + v := vote.ToProto() + err = signer.SignVote(chainID, v) + if err != nil { + panic(err) + } + + vote.Signature = v.Signature + return vote +} + +// MakeAndSignVoteWithForgedValAddress makes and signs a vote using two different keys: +// one to derive the validator address in the vote and a second to sign it. +func MakeAndSignVoteWithForgedValAddress( + blockID tmtypes.BlockID, + blockHeight int64, + blockTime time.Time, + valSet *tmtypes.ValidatorSet, + signer tmtypes.PrivValidator, + valAddressSigner tmtypes.PrivValidator, + chainID string, +) *tmtypes.Vote { + // create the vote using a different key than the signing key + vote, err := tmtypes.MakeVote( + blockHeight, + blockID, + valSet, + valAddressSigner, + chainID, + blockTime, + ) + if err != nil { + panic(err) + } + + // sign vote using the given private key + v := vote.ToProto() + err = signer.SignVote(chainID, v) + if err != nil { + panic(err) + } + + vote.Signature = v.Signature + return vote +} + +// CorruptCommitSigsInHeader corrupts the header by changing the value +// of the commit signature for given validator address. +// Note that this method is solely used for testing purposes +func CorruptCommitSigsInHeader(header *ibctmtypes.Header, valAddress bytes.HexBytes) { + commit, err := tmtypes.CommitFromProto(header.Commit) + if err != nil { + panic(err) + } + + for idx, sig := range commit.Signatures { + if sig.ValidatorAddress.String() == valAddress.String() { + sig.Signature = []byte("randomsig") + commit.Signatures[idx] = sig + } + } + // update the commit in client the header + header.SignedHeader.Commit = commit.ToProto() +} + +// CorruptValidatorPubkeyInHeader corrupts the header by changing the validator pubkey +// of the given validator address in the validator set. +// Note that this method is solely used for testing purposes +func CorruptValidatorPubkeyInHeader(header *ibctmtypes.Header, valAddress bytes.HexBytes) { + valset, err := tmtypes.ValidatorSetFromProto(header.ValidatorSet) + if err != nil { + panic(err) + } + + for _, v := range valset.Validators { + if v.Address.String() == valAddress.String() { + v.PubKey = tmtypes.NewMockPV().PrivKey.PubKey() + } + } + + vs, err := valset.ToProto() + if err != nil { + panic(err) + } + header.ValidatorSet = vs +} diff --git a/testutil/ibc_testing/generic_setup.go b/testutil/ibc_testing/generic_setup.go index e9d959b665..4b108e8120 100644 --- a/testutil/ibc_testing/generic_setup.go +++ b/testutil/ibc_testing/generic_setup.go @@ -145,7 +145,7 @@ func AddConsumer[Tp testutil.ProviderApp, Tc testutil.ConsumerApp]( // use InitialValSet as the valset on the consumer var valz []*tmtypes.Validator - for _, update := range consumerGenesisState.InitialValSet { + for _, update := range consumerGenesisState.Provider.InitialValSet { // tmPubKey update.PubKey tmPubKey, err := tmencoding.PubKeyFromProto(update.PubKey) s.Require().NoError(err) @@ -158,7 +158,7 @@ func AddConsumer[Tp testutil.ProviderApp, Tc testutil.ConsumerApp]( } // create and instantiate consumer chain - ibctesting.DefaultTestingAppInit = appIniter(consumerGenesisState.InitialValSet) + ibctesting.DefaultTestingAppInit = appIniter(consumerGenesisState.Provider.InitialValSet) testChain := ibctesting.NewTestChainWithValSet(s.T(), coordinator, chainID, tmtypes.NewValidatorSet(valz), providerChain.Signers) coordinator.Chains[chainID] = testChain diff --git a/testutil/ibc_testing/specific_setup.go b/testutil/ibc_testing/specific_setup.go index 1c5529e22a..d0b2ac7bb8 100644 --- a/testutil/ibc_testing/specific_setup.go +++ b/testutil/ibc_testing/specific_setup.go @@ -53,7 +53,7 @@ func ConsumerAppIniter(initValPowers []types.ValidatorUpdate) AppIniter { // Feed consumer genesis with provider validators var consumerGenesis ccvtypes.ConsumerGenesisState encoding.Codec.MustUnmarshalJSON(genesisState[consumertypes.ModuleName], &consumerGenesis) - consumerGenesis.InitialValSet = initValPowers + consumerGenesis.Provider.InitialValSet = initValPowers consumerGenesis.Params.Enabled = true genesisState[consumertypes.ModuleName] = encoding.Codec.MustMarshalJSON(&consumerGenesis) @@ -71,7 +71,7 @@ func DemocracyConsumerAppIniter(initValPowers []types.ValidatorUpdate) AppIniter // TODO See if useful for democracy var consumerGenesis ccvtypes.ConsumerGenesisState encoding.Codec.MustUnmarshalJSON(genesisState[consumertypes.ModuleName], &consumerGenesis) - consumerGenesis.InitialValSet = initValPowers + consumerGenesis.Provider.InitialValSet = initValPowers consumerGenesis.Params.Enabled = true genesisState[consumertypes.ModuleName] = encoding.Codec.MustMarshalJSON(&consumerGenesis) diff --git a/testutil/integration/debug_test.go b/testutil/integration/debug_test.go index 6b9415440e..dc1ae22543 100644 --- a/testutil/integration/debug_test.go +++ b/testutil/integration/debug_test.go @@ -181,10 +181,6 @@ func TestDoubleSignDoesNotAffectThrottling(t *testing.T) { runCCVTestByName(t, "TestDoubleSignDoesNotAffectThrottling") } -func TestQueueOrdering(t *testing.T) { - runCCVTestByName(t, "TestQueueOrdering") -} - func TestSlashingSmallValidators(t *testing.T) { runCCVTestByName(t, "TestSlashingSmallValidators") } @@ -193,22 +189,10 @@ func TestSlashMeterAllowanceChanges(t *testing.T) { runCCVTestByName(t, "TestSlashMeterAllowanceChanges") } -func TestSlashSameValidator(t *testing.T) { - runCCVTestByName(t, "TestSlashSameValidator") -} - func TestSlashAllValidators(t *testing.T) { runCCVTestByName(t, "TestSlashAllValidators") } -func TestLeadingVSCMaturedAreDequeued(t *testing.T) { - runCCVTestByName(t, "TestLeadingVSCMaturedAreDequeued") -} - -func TestVscMaturedHandledPerBlockLimit(t *testing.T) { - runCCVTestByName(t, "TestVscMaturedHandledPerBlockLimit") -} - // // Unbonding tests // @@ -258,6 +242,33 @@ func TestRecycleTransferChannel(t *testing.T) { } // +// Misbehaviour tests +// + +func TestHandleConsumerMisbehaviour(t *testing.T) { + runCCVTestByName(t, "TestHandleConsumerMisbehaviour") +} + +func TestGetByzantineValidators(t *testing.T) { + runCCVTestByName(t, "TestGetByzantineValidators") +} + +func TestCheckMisbehaviour(t *testing.T) { + runCCVTestByName(t, "TestCheckMisbehaviour") +} + +// +// Consumer Equivocation test +// + +func TestHandleConsumerDoubleVoting(t *testing.T) { + runCCVTestByName(t, "TestHandleConsumerDoubleVoting") +} + +func TestHandleConsumerDoubleVotingSlashesUndelegationsAndRelegations(t *testing.T) { + runCCVTestByName(t, "TestHandleConsumerDoubleVotingSlashesUndelegationsAndRelegations") +} + // Throttle retry tests // diff --git a/testutil/keeper/expectations.go b/testutil/keeper/expectations.go index 7814fe0fcf..9494b66936 100644 --- a/testutil/keeper/expectations.go +++ b/testutil/keeper/expectations.go @@ -11,6 +11,8 @@ import ( "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" @@ -156,3 +158,64 @@ func GetMocksForSendIBCPacket(ctx sdk.Context, mocks MockedKeepers, channelID st ).Return(uint64(888), nil).Times(times), } } + +func GetMocksForSlashValidator( + ctx sdk.Context, + mocks MockedKeepers, + validator stakingtypes.Validator, + consAddr sdk.ConsAddress, + undelegations []stakingtypes.UnbondingDelegation, + redelegations []stakingtypes.Redelegation, + powerReduction math.Int, + slashFraction math.LegacyDec, + currentPower, + expectedInfractionHeight, + expectedSlashPower int64, +) []*gomock.Call { + return []*gomock.Call{ + mocks.MockStakingKeeper.EXPECT(). + GetUnbondingDelegationsFromValidator(ctx, validator.GetOperator()). + Return(undelegations), + mocks.MockStakingKeeper.EXPECT(). + GetRedelegationsFromSrcValidator(ctx, validator.GetOperator()). + Return(redelegations), + mocks.MockStakingKeeper.EXPECT(). + GetLastValidatorPower(ctx, validator.GetOperator()). + Return(currentPower), + 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) + for _, r := range undelegation.Entries { + if r.IsMature(ctx.BlockTime()) { + continue + } + sum = sum.Add(sdk.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) + for _, r := range redelegation.Entries { + if r.IsMature(ctx.BlockTime()) { + continue + } + sum = sum.Add(sdk.NewInt(r.InitialBalance.Int64())) + } + return sum + }).AnyTimes(), + mocks.MockSlashingKeeper.EXPECT(). + SlashFractionDoubleSign(ctx). + Return(slashFraction), + mocks.MockStakingKeeper.EXPECT(). + SlashWithInfractionReason(ctx, consAddr, expectedInfractionHeight, expectedSlashPower, slashFraction, stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN). + Times(1), + } +} diff --git a/testutil/keeper/mocks.go b/testutil/keeper/mocks.go index b075819cc4..02b4749e43 100644 --- a/testutil/keeper/mocks.go +++ b/testutil/keeper/mocks.go @@ -14,13 +14,13 @@ import ( 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" - types3 "github.com/cosmos/cosmos-sdk/x/evidence/types" - types4 "github.com/cosmos/cosmos-sdk/x/slashing/types" - types5 "github.com/cosmos/cosmos-sdk/x/staking/types" - types6 "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" - types7 "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" - types8 "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types" - types9 "github.com/cosmos/ibc-go/v7/modules/core/04-channel/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" gomock "github.com/golang/mock/gomock" ) @@ -63,10 +63,10 @@ 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) types5.DelegationI { +func (m *MockStakingKeeper) Delegation(ctx types0.Context, addr types0.AccAddress, valAddr types0.ValAddress) types4.DelegationI { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Delegation", ctx, addr, valAddr) - ret0, _ := ret[0].(types5.DelegationI) + ret0, _ := ret[0].(types4.DelegationI) return ret0 } @@ -105,10 +105,10 @@ func (mr *MockStakingKeeperMockRecorder) GetLastValidatorPower(ctx, operator int } // GetLastValidators mocks base method. -func (m *MockStakingKeeper) GetLastValidators(ctx types0.Context) []types5.Validator { +func (m *MockStakingKeeper) GetLastValidators(ctx types0.Context) []types4.Validator { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetLastValidators", ctx) - ret0, _ := ret[0].([]types5.Validator) + ret0, _ := ret[0].([]types4.Validator) return ret0 } @@ -118,11 +118,39 @@ func (mr *MockStakingKeeperMockRecorder) GetLastValidators(ctx interface{}) *gom return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastValidators", reflect.TypeOf((*MockStakingKeeper)(nil).GetLastValidators), ctx) } +// GetRedelegationsFromSrcValidator mocks base method. +func (m *MockStakingKeeper) GetRedelegationsFromSrcValidator(ctx types0.Context, valAddr types0.ValAddress) []types4.Redelegation { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetRedelegationsFromSrcValidator", ctx, valAddr) + ret0, _ := ret[0].([]types4.Redelegation) + return ret0 +} + +// GetRedelegationsFromSrcValidator indicates an expected call of GetRedelegationsFromSrcValidator. +func (mr *MockStakingKeeperMockRecorder) GetRedelegationsFromSrcValidator(ctx, valAddr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRedelegationsFromSrcValidator", reflect.TypeOf((*MockStakingKeeper)(nil).GetRedelegationsFromSrcValidator), ctx, valAddr) +} + +// GetUnbondingDelegationsFromValidator mocks base method. +func (m *MockStakingKeeper) GetUnbondingDelegationsFromValidator(ctx types0.Context, valAddr types0.ValAddress) []types4.UnbondingDelegation { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUnbondingDelegationsFromValidator", ctx, valAddr) + ret0, _ := ret[0].([]types4.UnbondingDelegation) + return ret0 +} + +// GetUnbondingDelegationsFromValidator indicates an expected call of GetUnbondingDelegationsFromValidator. +func (mr *MockStakingKeeperMockRecorder) GetUnbondingDelegationsFromValidator(ctx, valAddr interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUnbondingDelegationsFromValidator", reflect.TypeOf((*MockStakingKeeper)(nil).GetUnbondingDelegationsFromValidator), ctx, valAddr) +} + // GetUnbondingType mocks base method. -func (m *MockStakingKeeper) GetUnbondingType(ctx types0.Context, id uint64) (types5.UnbondingType, bool) { +func (m *MockStakingKeeper) GetUnbondingType(ctx types0.Context, id uint64) (types4.UnbondingType, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUnbondingType", ctx, id) - ret0, _ := ret[0].(types5.UnbondingType) + ret0, _ := ret[0].(types4.UnbondingType) ret1, _ := ret[1].(bool) return ret0, ret1 } @@ -134,10 +162,10 @@ func (mr *MockStakingKeeperMockRecorder) GetUnbondingType(ctx, id interface{}) * } // GetValidator mocks base method. -func (m *MockStakingKeeper) GetValidator(ctx types0.Context, addr types0.ValAddress) (types5.Validator, bool) { +func (m *MockStakingKeeper) GetValidator(ctx types0.Context, addr types0.ValAddress) (types4.Validator, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetValidator", ctx, addr) - ret0, _ := ret[0].(types5.Validator) + ret0, _ := ret[0].(types4.Validator) ret1, _ := ret[1].(bool) return ret0, ret1 } @@ -149,10 +177,10 @@ func (mr *MockStakingKeeperMockRecorder) GetValidator(ctx, addr interface{}) *go } // GetValidatorByConsAddr mocks base method. -func (m *MockStakingKeeper) GetValidatorByConsAddr(ctx types0.Context, consAddr types0.ConsAddress) (types5.Validator, bool) { +func (m *MockStakingKeeper) GetValidatorByConsAddr(ctx types0.Context, consAddr types0.ConsAddress) (types4.Validator, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetValidatorByConsAddr", ctx, consAddr) - ret0, _ := ret[0].(types5.Validator) + ret0, _ := ret[0].(types4.Validator) ret1, _ := ret[1].(bool) return ret0, ret1 } @@ -204,7 +232,7 @@ func (mr *MockStakingKeeperMockRecorder) IterateLastValidatorPowers(ctx, cb inte } // IterateValidators mocks base method. -func (m *MockStakingKeeper) IterateValidators(ctx types0.Context, f func(int64, types5.ValidatorI) bool) { +func (m *MockStakingKeeper) IterateValidators(ctx types0.Context, f func(int64, types4.ValidatorI) bool) { m.ctrl.T.Helper() m.ctrl.Call(m, "IterateValidators", ctx, f) } @@ -283,8 +311,36 @@ func (mr *MockStakingKeeperMockRecorder) Slash(arg0, arg1, arg2, arg3, arg4 inte return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Slash", reflect.TypeOf((*MockStakingKeeper)(nil).Slash), arg0, arg1, arg2, arg3, arg4) } +// SlashRedelegation mocks base method. +func (m *MockStakingKeeper) SlashRedelegation(arg0 types0.Context, arg1 types4.Validator, arg2 types4.Redelegation, arg3 int64, arg4 types0.Dec) math.Int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SlashRedelegation", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(math.Int) + return ret0 +} + +// SlashRedelegation indicates an expected call of SlashRedelegation. +func (mr *MockStakingKeeperMockRecorder) SlashRedelegation(arg0, arg1, arg2, arg3, arg4 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) +} + +// SlashUnbondingDelegation mocks base method. +func (m *MockStakingKeeper) SlashUnbondingDelegation(arg0 types0.Context, arg1 types4.UnbondingDelegation, arg2 int64, arg3 types0.Dec) math.Int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SlashUnbondingDelegation", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(math.Int) + return ret0 +} + +// SlashUnbondingDelegation indicates an expected call of SlashUnbondingDelegation. +func (mr *MockStakingKeeperMockRecorder) SlashUnbondingDelegation(arg0, arg1, arg2, arg3 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) +} + // SlashWithInfractionReason mocks base method. -func (m *MockStakingKeeper) SlashWithInfractionReason(arg0 types0.Context, arg1 types0.ConsAddress, arg2, arg3 int64, arg4 types0.Dec, arg5 types5.Infraction) math.Int { +func (m *MockStakingKeeper) SlashWithInfractionReason(arg0 types0.Context, arg1 types0.ConsAddress, arg2, arg3 int64, arg4 types0.Dec, arg5 types4.Infraction) math.Int { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SlashWithInfractionReason", arg0, arg1, arg2, arg3, arg4, arg5) ret0, _ := ret[0].(math.Int) @@ -338,10 +394,10 @@ func (mr *MockStakingKeeperMockRecorder) Unjail(ctx, addr interface{}) *gomock.C } // Validator mocks base method. -func (m *MockStakingKeeper) Validator(ctx types0.Context, addr types0.ValAddress) types5.ValidatorI { +func (m *MockStakingKeeper) Validator(ctx types0.Context, addr types0.ValAddress) types4.ValidatorI { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Validator", ctx, addr) - ret0, _ := ret[0].(types5.ValidatorI) + ret0, _ := ret[0].(types4.ValidatorI) return ret0 } @@ -352,10 +408,10 @@ func (mr *MockStakingKeeperMockRecorder) Validator(ctx, addr interface{}) *gomoc } // ValidatorByConsAddr mocks base method. -func (m *MockStakingKeeper) ValidatorByConsAddr(ctx types0.Context, consAddr types0.ConsAddress) types5.ValidatorI { +func (m *MockStakingKeeper) ValidatorByConsAddr(ctx types0.Context, consAddr types0.ConsAddress) types4.ValidatorI { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ValidatorByConsAddr", ctx, consAddr) - ret0, _ := ret[0].(types5.ValidatorI) + ret0, _ := ret[0].(types4.ValidatorI) return ret0 } @@ -365,41 +421,6 @@ func (mr *MockStakingKeeperMockRecorder) ValidatorByConsAddr(ctx, consAddr inter return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorByConsAddr", reflect.TypeOf((*MockStakingKeeper)(nil).ValidatorByConsAddr), ctx, consAddr) } -// MockEvidenceKeeper is a mock of EvidenceKeeper interface. -type MockEvidenceKeeper struct { - ctrl *gomock.Controller - recorder *MockEvidenceKeeperMockRecorder -} - -// MockEvidenceKeeperMockRecorder is the mock recorder for MockEvidenceKeeper. -type MockEvidenceKeeperMockRecorder struct { - mock *MockEvidenceKeeper -} - -// NewMockEvidenceKeeper creates a new mock instance. -func NewMockEvidenceKeeper(ctrl *gomock.Controller) *MockEvidenceKeeper { - mock := &MockEvidenceKeeper{ctrl: ctrl} - mock.recorder = &MockEvidenceKeeperMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockEvidenceKeeper) EXPECT() *MockEvidenceKeeperMockRecorder { - return m.recorder -} - -// HandleEquivocationEvidence mocks base method. -func (m *MockEvidenceKeeper) HandleEquivocationEvidence(ctx types0.Context, evidence *types3.Equivocation) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "HandleEquivocationEvidence", ctx, evidence) -} - -// HandleEquivocationEvidence indicates an expected call of HandleEquivocationEvidence. -func (mr *MockEvidenceKeeperMockRecorder) HandleEquivocationEvidence(ctx, evidence interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HandleEquivocationEvidence", reflect.TypeOf((*MockEvidenceKeeper)(nil).HandleEquivocationEvidence), ctx, evidence) -} - // MockSlashingKeeper is a mock of SlashingKeeper interface. type MockSlashingKeeper struct { ctrl *gomock.Controller @@ -438,10 +459,10 @@ func (mr *MockSlashingKeeperMockRecorder) DowntimeJailDuration(arg0 interface{}) } // GetValidatorSigningInfo mocks base method. -func (m *MockSlashingKeeper) GetValidatorSigningInfo(ctx types0.Context, address types0.ConsAddress) (types4.ValidatorSigningInfo, bool) { +func (m *MockSlashingKeeper) GetValidatorSigningInfo(ctx types0.Context, address types0.ConsAddress) (types3.ValidatorSigningInfo, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetValidatorSigningInfo", ctx, address) - ret0, _ := ret[0].(types4.ValidatorSigningInfo) + ret0, _ := ret[0].(types3.ValidatorSigningInfo) ret1, _ := ret[1].(bool) return ret0, ret1 } @@ -556,28 +577,34 @@ func (mr *MockChannelKeeperMockRecorder) ChanCloseInit(ctx, portID, channelID, c } // GetChannel mocks base method. -func (m *MockChannelKeeper) GetChannel(ctx types0.Context, srcPort, srcChan string) (types9.Channel, bool) { +func (m *MockChannelKeeper) GetChannel(ctx types0.Context, srcPort, srcChan string) (types8.Channel, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetChannel", ctx, srcPort, srcChan) - ret0, _ := ret[0].(types9.Channel) + ret0, _ := ret[0].(types8.Channel) ret1, _ := ret[1].(bool) return ret0, ret1 } +// GetChannel indicates an expected call of GetChannel. +func (mr *MockChannelKeeperMockRecorder) GetChannel(ctx, srcPort, srcChan interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChannel", reflect.TypeOf((*MockChannelKeeper)(nil).GetChannel), ctx, srcPort, srcChan) +} + +// GetChannelConnection mocks base method. func (m *MockChannelKeeper) GetChannelConnection(ctx types0.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) - ret1, _ := ret[0].(exported.ConnectionI) - ret2, _ := ret[1].(error) - + ret1, _ := ret[1].(exported.ConnectionI) + ret2, _ := ret[2].(error) return ret0, ret1, ret2 } -// GetChannel indicates an expected call of GetChannel. -func (mr *MockChannelKeeperMockRecorder) GetChannel(ctx, srcPort, srcChan interface{}) *gomock.Call { +// GetChannelConnection indicates an expected call of GetChannelConnection. +func (mr *MockChannelKeeperMockRecorder) GetChannelConnection(ctx, portID, channelID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChannel", reflect.TypeOf((*MockChannelKeeper)(nil).GetChannel), ctx, srcPort, srcChan) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChannelConnection", reflect.TypeOf((*MockChannelKeeper)(nil).GetChannelConnection), ctx, portID, channelID) } // GetNextSequenceSend mocks base method. @@ -596,7 +623,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 types7.Height, timeoutTimestamp uint64, data []byte) (uint64, error) { +func (m *MockChannelKeeper) SendPacket(ctx types0.Context, chanCap *types2.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) @@ -685,10 +712,10 @@ func (m *MockConnectionKeeper) EXPECT() *MockConnectionKeeperMockRecorder { } // GetConnection mocks base method. -func (m *MockConnectionKeeper) GetConnection(ctx types0.Context, connectionID string) (types8.ConnectionEnd, bool) { +func (m *MockConnectionKeeper) GetConnection(ctx types0.Context, connectionID string) (types7.ConnectionEnd, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetConnection", ctx, connectionID) - ret0, _ := ret[0].(types8.ConnectionEnd) + ret0, _ := ret[0].(types7.ConnectionEnd) ret1, _ := ret[1].(bool) return ret0, ret1 } @@ -722,6 +749,20 @@ func (m *MockClientKeeper) EXPECT() *MockClientKeeperMockRecorder { return m.recorder } +// ClientStore mocks base method. +func (m *MockClientKeeper) ClientStore(ctx types0.Context, clientID string) types0.KVStore { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClientStore", ctx, clientID) + ret0, _ := ret[0].(types0.KVStore) + return ret0 +} + +// ClientStore indicates an expected call of ClientStore. +func (mr *MockClientKeeperMockRecorder) ClientStore(ctx, clientID interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClientStore", reflect.TypeOf((*MockClientKeeper)(nil).ClientStore), ctx, clientID) +} + // CreateClient mocks base method. func (m *MockClientKeeper) CreateClient(ctx types0.Context, clientState exported.ClientState, consensusState exported.ConsensusState) (string, error) { m.ctrl.T.Helper() @@ -737,6 +778,21 @@ func (mr *MockClientKeeperMockRecorder) CreateClient(ctx, clientState, consensus return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateClient", reflect.TypeOf((*MockClientKeeper)(nil).CreateClient), ctx, clientState, consensusState) } +// GetClientConsensusState mocks base method. +func (m *MockClientKeeper) GetClientConsensusState(ctx types0.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) + ret1, _ := ret[1].(bool) + return ret0, ret1 +} + +// GetClientConsensusState indicates an expected call of GetClientConsensusState. +func (mr *MockClientKeeperMockRecorder) GetClientConsensusState(ctx, clientID, height interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetClientConsensusState", reflect.TypeOf((*MockClientKeeper)(nil).GetClientConsensusState), ctx, clientID, height) +} + // GetClientState mocks base method. func (m *MockClientKeeper) GetClientState(ctx types0.Context, clientID string) (exported.ClientState, bool) { m.ctrl.T.Helper() @@ -782,6 +838,18 @@ func (mr *MockClientKeeperMockRecorder) GetSelfConsensusState(ctx, height interf return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSelfConsensusState", reflect.TypeOf((*MockClientKeeper)(nil).GetSelfConsensusState), ctx, height) } +// SetClientState mocks base method. +func (m *MockClientKeeper) SetClientState(ctx types0.Context, clientID string, clientState exported.ClientState) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetClientState", ctx, clientID, clientState) +} + +// SetClientState indicates an expected call of SetClientState. +func (mr *MockClientKeeperMockRecorder) SetClientState(ctx, clientID, clientState interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetClientState", reflect.TypeOf((*MockClientKeeper)(nil).SetClientState), ctx, clientID, clientState) +} + // MockDistributionKeeper is a mock of DistributionKeeper interface. type MockDistributionKeeper struct { ctrl *gomock.Controller @@ -982,10 +1050,10 @@ func (m *MockIBCTransferKeeper) EXPECT() *MockIBCTransferKeeperMockRecorder { } // Transfer mocks base method. -func (m *MockIBCTransferKeeper) Transfer(arg0 context.Context, arg1 *types6.MsgTransfer) (*types6.MsgTransferResponse, error) { +func (m *MockIBCTransferKeeper) Transfer(arg0 context.Context, arg1 *types5.MsgTransfer) (*types5.MsgTransferResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Transfer", arg0, arg1) - ret0, _ := ret[0].(*types6.MsgTransferResponse) + ret0, _ := ret[0].(*types5.MsgTransferResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1020,10 +1088,10 @@ func (m *MockIBCCoreKeeper) EXPECT() *MockIBCCoreKeeperMockRecorder { } // ChannelOpenInit mocks base method. -func (m *MockIBCCoreKeeper) ChannelOpenInit(goCtx context.Context, msg *types9.MsgChannelOpenInit) (*types9.MsgChannelOpenInitResponse, error) { +func (m *MockIBCCoreKeeper) ChannelOpenInit(goCtx context.Context, msg *types8.MsgChannelOpenInit) (*types8.MsgChannelOpenInitResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ChannelOpenInit", goCtx, msg) - ret0, _ := ret[0].(*types9.MsgChannelOpenInitResponse) + ret0, _ := ret[0].(*types8.MsgChannelOpenInitResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -1099,3 +1167,41 @@ 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 b58d6d2471..d114a57651 100644 --- a/testutil/keeper/unit_test_helpers.go +++ b/testutil/keeper/unit_test_helpers.go @@ -87,8 +87,8 @@ type MockedKeepers struct { *MockBankKeeper *MockIBCTransferKeeper *MockIBCCoreKeeper - *MockEvidenceKeeper *MockDistributionKeeper + *MockGovKeeper } // NewMockedKeepers instantiates a struct with pointers to properly instantiated mocked keepers. @@ -105,8 +105,8 @@ func NewMockedKeepers(ctrl *gomock.Controller) MockedKeepers { MockBankKeeper: NewMockBankKeeper(ctrl), MockIBCTransferKeeper: NewMockIBCTransferKeeper(ctrl), MockIBCCoreKeeper: NewMockIBCCoreKeeper(ctrl), - MockEvidenceKeeper: NewMockEvidenceKeeper(ctrl), MockDistributionKeeper: NewMockDistributionKeeper(ctrl), + MockGovKeeper: NewMockGovKeeper(ctrl), } } @@ -124,9 +124,9 @@ func NewInMemProviderKeeper(params InMemKeeperParams, mocks MockedKeepers) provi mocks.MockStakingKeeper, mocks.MockSlashingKeeper, mocks.MockAccountKeeper, - mocks.MockEvidenceKeeper, mocks.MockDistributionKeeper, mocks.MockBankKeeper, + mocks.MockGovKeeper, authtypes.FeeCollectorName, ) } @@ -254,15 +254,6 @@ func TestProviderStateIsCleanedAfterConsumerChainIsStopped(t *testing.T, ctx sdk require.Empty(t, providerKeeper.GetAllValidatorsByConsumerAddr(ctx, &expectedChainID)) require.Empty(t, providerKeeper.GetAllKeyAssignmentReplacements(ctx, expectedChainID)) require.Empty(t, providerKeeper.GetAllConsumerAddrsToPrune(ctx, expectedChainID)) - - allGlobalEntries := providerKeeper.GetAllGlobalSlashEntries(ctx) - for _, entry := range allGlobalEntries { - require.NotEqual(t, expectedChainID, entry.ConsumerChainID) - } - - slashPacketData, vscMaturedPacketData, _, _ := providerKeeper.GetAllThrottledPacketData(ctx, expectedChainID) - require.Empty(t, slashPacketData) - require.Empty(t, vscMaturedPacketData) } func GetTestConsumerAdditionProp() *providertypes.ConsumerAdditionProposal { diff --git a/x/ccv/consumer/client/cli/query.go b/x/ccv/consumer/client/cli/query.go index dc1ecfc2f4..f1a0c0f258 100644 --- a/x/ccv/consumer/client/cli/query.go +++ b/x/ccv/consumer/client/cli/query.go @@ -22,6 +22,7 @@ func NewQueryCmd() *cobra.Command { cmd.AddCommand( CmdNextFeeDistribution(), CmdProviderInfo(), + CmdThrottleState(), ) return cmd @@ -80,3 +81,30 @@ func CmdProviderInfo() *cobra.Command { return cmd } + +func CmdThrottleState() *cobra.Command { + cmd := &cobra.Command{ + Use: "throttle-state", + Short: "Query throttle state", + 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.QueryThrottleStateRequest{} + res, err := queryClient.QueryThrottleState(cmd.Context(), req) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/ccv/consumer/ibc_module.go b/x/ccv/consumer/ibc_module.go index 93b8096092..99f0141e64 100644 --- a/x/ccv/consumer/ibc_module.go +++ b/x/ccv/consumer/ibc_module.go @@ -176,7 +176,7 @@ func (am AppModule) OnChanOpenAck( ctx.EventManager().EmitEvent( sdk.NewEvent( - types.EventTypeFeeTransferChannelOpened, + consumertypes.EventTypeFeeTransferChannelOpened, sdk.NewAttribute(sdk.AttributeKeyModule, consumertypes.ModuleName), sdk.NewAttribute(channeltypes.AttributeKeyChannelID, channelID), sdk.NewAttribute(channeltypes.AttributeKeyPortID, transfertypes.PortID), diff --git a/x/ccv/consumer/keeper/distribution.go b/x/ccv/consumer/keeper/distribution.go index a2c19b495d..c0a98d0a21 100644 --- a/x/ccv/consumer/keeper/distribution.go +++ b/x/ccv/consumer/keeper/distribution.go @@ -42,7 +42,7 @@ func (k Keeper) EndBlockRD(ctx sdk.Context) { } // Update LastTransmissionBlockHeight - newLtbh := ccv.LastTransmissionBlockHeight{ + newLtbh := types.LastTransmissionBlockHeight{ Height: ctx.BlockHeight(), } k.SetLastTransmissionBlockHeight(ctx, newLtbh) @@ -161,13 +161,13 @@ func (k Keeper) SendRewardsToProvider(ctx sdk.Context) error { currentHeight := ctx.BlockHeight() ctx.EventManager().EmitEvent( sdk.NewEvent( - ccv.EventTypeFeeDistribution, + types.EventTypeFeeDistribution, sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), - sdk.NewAttribute(ccv.AttributeDistributionCurrentHeight, strconv.Itoa(int(currentHeight))), - sdk.NewAttribute(ccv.AttributeDistributionNextHeight, strconv.Itoa(int(currentHeight+k.GetBlocksPerDistributionTransmission(ctx)))), - sdk.NewAttribute(ccv.AttributeDistributionFraction, (k.GetConsumerRedistributionFrac(ctx))), - sdk.NewAttribute(ccv.AttributeDistributionTotal, allBalances.String()), - sdk.NewAttribute(ccv.AttributeDistributionToProvider, sentCoins.String()), + sdk.NewAttribute(types.AttributeDistributionCurrentHeight, strconv.Itoa(int(currentHeight))), + sdk.NewAttribute(types.AttributeDistributionNextHeight, strconv.Itoa(int(currentHeight+k.GetBlocksPerDistributionTransmission(ctx)))), + sdk.NewAttribute(types.AttributeDistributionFraction, (k.GetConsumerRedistributionFrac(ctx))), + sdk.NewAttribute(types.AttributeDistributionTotal, allBalances.String()), + sdk.NewAttribute(types.AttributeDistributionToProvider, sentCoins.String()), ), ) @@ -202,10 +202,10 @@ func (k Keeper) AllowedRewardDenoms(ctx sdk.Context) []string { return rewardDenoms } -func (k Keeper) GetLastTransmissionBlockHeight(ctx sdk.Context) ccv.LastTransmissionBlockHeight { +func (k Keeper) GetLastTransmissionBlockHeight(ctx sdk.Context) types.LastTransmissionBlockHeight { store := ctx.KVStore(k.storeKey) bz := store.Get(types.LastDistributionTransmissionKey()) - ltbh := ccv.LastTransmissionBlockHeight{} + ltbh := types.LastTransmissionBlockHeight{} if bz != nil { if err := ltbh.Unmarshal(bz); err != nil { panic(fmt.Errorf("failed to unmarshal LastTransmissionBlockHeight: %w", err)) @@ -214,7 +214,7 @@ func (k Keeper) GetLastTransmissionBlockHeight(ctx sdk.Context) ccv.LastTransmis return ltbh } -func (k Keeper) SetLastTransmissionBlockHeight(ctx sdk.Context, ltbh ccv.LastTransmissionBlockHeight) { +func (k Keeper) SetLastTransmissionBlockHeight(ctx sdk.Context, ltbh types.LastTransmissionBlockHeight) { store := ctx.KVStore(k.storeKey) bz, err := ltbh.Marshal() if err != nil { diff --git a/x/ccv/consumer/keeper/genesis.go b/x/ccv/consumer/keeper/genesis.go index f20d8849dc..0edcb57d7f 100644 --- a/x/ccv/consumer/keeper/genesis.go +++ b/x/ccv/consumer/keeper/genesis.go @@ -7,6 +7,7 @@ import ( abci "github.com/cometbft/cometbft/abci/types" + "github.com/cosmos/interchain-security/v3/x/ccv/consumer/types" ccv "github.com/cosmos/interchain-security/v3/x/ccv/types" ) @@ -16,7 +17,7 @@ import ( // 1. A client to the provider was never created, i.e. a new consumer chain is started for the first time. // 2. A consumer chain restarts after a client to the provider was created, but the CCV channel handshake is still in progress // 3. A consumer chain restarts after the CCV channel handshake was completed. -func (k Keeper) InitGenesis(ctx sdk.Context, state *ccv.ConsumerGenesisState) []abci.ValidatorUpdate { +func (k Keeper) InitGenesis(ctx sdk.Context, state *types.GenesisState) []abci.ValidatorUpdate { // PreCCV is true during the process of a standalone to consumer changeover. // At the PreCCV point in the process, the standalone chain has just been upgraded to include // the consumer ccv module, but the standalone staking keeper is still managing the validator set. @@ -26,7 +27,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *ccv.ConsumerGenesisState) [] if state.PreCCV { k.SetPreCCVTrue(ctx) k.MarkAsPrevStandaloneChain(ctx) - k.SetInitialValSet(ctx, state.InitialValSet) + k.SetInitialValSet(ctx, state.Provider.InitialValSet) } k.SetInitGenesisHeight(ctx, ctx.BlockHeight()) // Usually 0, but not the case for changeover chains @@ -55,7 +56,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *ccv.ConsumerGenesisState) [] // start a new chain if state.NewChain { // create the provider client in InitGenesis for new consumer chain. CCV Handshake must be established with this client id. - clientID, err := k.clientKeeper.CreateClient(ctx, state.ProviderClientState, state.ProviderConsensusState) + clientID, err := k.clientKeeper.CreateClient(ctx, state.Provider.ClientState, state.Provider.ConsensusState) if err != nil { // If the client creation fails, the chain MUST NOT start panic(err) @@ -110,15 +111,15 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *ccv.ConsumerGenesisState) [] } // populate cross chain validators states with initial valset - k.ApplyCCValidatorChanges(ctx, state.InitialValSet) - return state.InitialValSet + k.ApplyCCValidatorChanges(ctx, state.Provider.InitialValSet) + return state.Provider.InitialValSet } // ExportGenesis returns the CCV consumer module's exported genesis -func (k Keeper) ExportGenesis(ctx sdk.Context) (genesis *ccv.ConsumerGenesisState) { +func (k Keeper) ExportGenesis(ctx sdk.Context) (genesis *types.GenesisState) { params := k.GetConsumerParams(ctx) if !params.Enabled { - return ccv.DefaultConsumerGenesisState() + return types.DefaultGenesisState() } // export the current validator set @@ -126,7 +127,7 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) (genesis *ccv.ConsumerGenesisStat // export pending packets using the depreciated ConsumerPacketDataList type pendingPackets := k.GetPendingPackets(ctx) - pendingPacketsDepreciated := ccv.ConsumerPacketDataList{} + pendingPacketsDepreciated := types.ConsumerPacketDataList{} pendingPacketsDepreciated.List = append(pendingPacketsDepreciated.List, pendingPackets...) // export all the states created after a provider channel got established @@ -137,7 +138,7 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) (genesis *ccv.ConsumerGenesisStat panic("provider client does not exist although provider channel does exist") } - genesis = ccv.NewRestartConsumerGenesisState( + genesis = types.NewRestartGenesisState( clientID, channelID, k.GetAllPacketMaturityTimes(ctx), @@ -153,11 +154,11 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) (genesis *ccv.ConsumerGenesisStat // if provider clientID and channelID don't exist on the consumer chain, // then CCV protocol is disabled for this chain return a default genesis state if !ok { - return ccv.DefaultConsumerGenesisState() + return types.DefaultGenesisState() } // export client states and pending slashing requests into a new chain genesis - genesis = ccv.NewRestartConsumerGenesisState( + genesis = types.NewRestartGenesisState( clientID, "", nil, @@ -165,7 +166,7 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) (genesis *ccv.ConsumerGenesisStat k.GetAllHeightToValsetUpdateIDs(ctx), pendingPacketsDepreciated, nil, - ccv.LastTransmissionBlockHeight{}, + types.LastTransmissionBlockHeight{}, params, ) } diff --git a/x/ccv/consumer/keeper/genesis_test.go b/x/ccv/consumer/keeper/genesis_test.go index a07388a6cb..93e856d6ef 100644 --- a/x/ccv/consumer/keeper/genesis_test.go +++ b/x/ccv/consumer/keeper/genesis_test.go @@ -61,13 +61,13 @@ func TestInitGenesis(t *testing.T) { []string{"upgrade", "upgradedIBCState"}, ) - matPackets := []ccv.MaturingVSCPacket{ + matPackets := []consumertypes.MaturingVSCPacket{ { VscId: 1, MaturityTime: time.Now().UTC(), }, } - pendingDataPackets := ccv.ConsumerPacketDataList{ + pendingDataPackets := consumertypes.ConsumerPacketDataList{ List: []ccv.ConsumerPacketData{ { Type: ccv.SlashPacket, @@ -84,11 +84,11 @@ func TestInitGenesis(t *testing.T) { }, } // mock height to valset update ID values - defaultHeightValsetUpdateIDs := []ccv.HeightToValsetUpdateID{ + defaultHeightValsetUpdateIDs := []consumertypes.HeightToValsetUpdateID{ {ValsetUpdateId: vscID, Height: blockHeight}, } updatedHeightValsetUpdateIDs := append(defaultHeightValsetUpdateIDs, - ccv.HeightToValsetUpdateID{ValsetUpdateId: vscID + 1, Height: blockHeight + 1}, + consumertypes.HeightToValsetUpdateID{ValsetUpdateId: vscID + 1, Height: blockHeight + 1}, ) // create default parameters for a new chain @@ -100,8 +100,8 @@ func TestInitGenesis(t *testing.T) { testCases := []struct { name string malleate func(sdk.Context, testkeeper.MockedKeepers) - genesis *ccv.ConsumerGenesisState - assertStates func(sdk.Context, consumerkeeper.Keeper, *ccv.ConsumerGenesisState) + genesis *consumertypes.GenesisState + assertStates func(sdk.Context, consumerkeeper.Keeper, *consumertypes.GenesisState) }{ { "start a new chain", @@ -112,13 +112,13 @@ func TestInitGenesis(t *testing.T) { testkeeper.ExpectGetCapabilityMock(ctx, mocks, 1), ) }, - ccv.NewInitialConsumerGenesisState( + consumertypes.NewInitialGenesisState( provClientState, provConsState, valset, params, ), - func(ctx sdk.Context, ck consumerkeeper.Keeper, gs *ccv.ConsumerGenesisState) { + func(ctx sdk.Context, ck consumerkeeper.Keeper, gs *consumertypes.GenesisState) { assertConsumerPortIsBound(t, ctx, &ck) assertProviderClientID(t, ctx, &ck, provClientID) @@ -134,7 +134,7 @@ func TestInitGenesis(t *testing.T) { testkeeper.ExpectGetCapabilityMock(ctx, mocks, 2), ) }, - ccv.NewRestartConsumerGenesisState( + consumertypes.NewRestartGenesisState( provClientID, "", matPackets, @@ -142,10 +142,10 @@ func TestInitGenesis(t *testing.T) { defaultHeightValsetUpdateIDs, pendingDataPackets, nil, - ccv.LastTransmissionBlockHeight{}, + consumertypes.LastTransmissionBlockHeight{}, params, ), - func(ctx sdk.Context, ck consumerkeeper.Keeper, gs *ccv.ConsumerGenesisState) { + func(ctx sdk.Context, ck consumerkeeper.Keeper, gs *consumertypes.GenesisState) { assertConsumerPortIsBound(t, ctx, &ck) obtainedPendingPackets := ck.GetPendingPackets(ctx) @@ -170,20 +170,20 @@ func TestInitGenesis(t *testing.T) { ) }, // create a genesis for a restarted chain - ccv.NewRestartConsumerGenesisState( + consumertypes.NewRestartGenesisState( provClientID, provChannelID, matPackets, valset, updatedHeightValsetUpdateIDs, pendingDataPackets, - []ccv.OutstandingDowntime{ + []consumertypes.OutstandingDowntime{ {ValidatorConsensusAddress: sdk.ConsAddress(validator.Bytes()).String()}, }, - ccv.LastTransmissionBlockHeight{Height: int64(100)}, + consumertypes.LastTransmissionBlockHeight{Height: int64(100)}, params, ), - func(ctx sdk.Context, ck consumerkeeper.Keeper, gs *ccv.ConsumerGenesisState) { + func(ctx sdk.Context, ck consumerkeeper.Keeper, gs *consumertypes.GenesisState) { assertConsumerPortIsBound(t, ctx, &ck) gotChannelID, ok := ck.GetProviderChannel(ctx) @@ -239,7 +239,7 @@ func TestExportGenesis(t *testing.T) { vscID := uint64(0) blockHeight := uint64(0) - matPackets := []ccv.MaturingVSCPacket{ + matPackets := []consumertypes.MaturingVSCPacket{ { VscId: 1, MaturityTime: time.Now().UTC(), @@ -255,7 +255,7 @@ func TestExportGenesis(t *testing.T) { valset := []abci.ValidatorUpdate{tmtypes.TM2PB.ValidatorUpdate(validator)} // create pending consumer packets - consPackets := ccv.ConsumerPacketDataList{ + consPackets := consumertypes.ConsumerPacketDataList{ List: []ccv.ConsumerPacketData{ { Type: ccv.SlashPacket, @@ -272,13 +272,13 @@ func TestExportGenesis(t *testing.T) { }, } // mock height to valset update ID values - defaultHeightValsetUpdateIDs := []ccv.HeightToValsetUpdateID{ + defaultHeightValsetUpdateIDs := []consumertypes.HeightToValsetUpdateID{ {ValsetUpdateId: vscID, Height: blockHeight}, } updatedHeightValsetUpdateIDs := append(defaultHeightValsetUpdateIDs, - ccv.HeightToValsetUpdateID{ValsetUpdateId: vscID + 1, Height: blockHeight + 1}, + consumertypes.HeightToValsetUpdateID{ValsetUpdateId: vscID + 1, Height: blockHeight + 1}, ) - ltbh := ccv.LastTransmissionBlockHeight{Height: int64(1000)} + ltbh := consumertypes.LastTransmissionBlockHeight{Height: int64(1000)} // create default parameters for a new chain params := ccv.DefaultParams() params.Enabled = true @@ -289,7 +289,7 @@ func TestExportGenesis(t *testing.T) { testCases := []struct { name string malleate func(sdk.Context, consumerkeeper.Keeper, testkeeper.MockedKeepers) - expGenesis *ccv.ConsumerGenesisState + expGenesis *consumertypes.GenesisState }{ { "export a chain without an established CCV channel", @@ -307,7 +307,7 @@ func TestExportGenesis(t *testing.T) { ck.SetHeightValsetUpdateID(ctx, defaultHeightValsetUpdateIDs[0].Height, defaultHeightValsetUpdateIDs[0].ValsetUpdateId) }, - ccv.NewRestartConsumerGenesisState( + consumertypes.NewRestartGenesisState( provClientID, "", nil, @@ -315,7 +315,7 @@ func TestExportGenesis(t *testing.T) { defaultHeightValsetUpdateIDs, consPackets, nil, - ccv.LastTransmissionBlockHeight{}, + consumertypes.LastTransmissionBlockHeight{}, params, ), }, @@ -343,14 +343,14 @@ func TestExportGenesis(t *testing.T) { ck.SetOutstandingDowntime(ctx, sdk.ConsAddress(validator.Address.Bytes())) ck.SetLastTransmissionBlockHeight(ctx, ltbh) }, - ccv.NewRestartConsumerGenesisState( + consumertypes.NewRestartGenesisState( provClientID, provChannelID, matPackets, valset, updatedHeightValsetUpdateIDs, consPackets, - []ccv.OutstandingDowntime{ + []consumertypes.OutstandingDowntime{ {ValidatorConsensusAddress: sdk.ConsAddress(validator.Address.Bytes()).String()}, }, ltbh, @@ -394,7 +394,7 @@ func assertProviderClientID(t *testing.T, ctx sdk.Context, ck *consumerkeeper.Ke } // assert that the given input match the height to valset update ID mappings in the store -func assertHeightValsetUpdateIDs(t *testing.T, ctx sdk.Context, ck *consumerkeeper.Keeper, heighValsetUpdateIDs []ccv.HeightToValsetUpdateID) { +func assertHeightValsetUpdateIDs(t *testing.T, ctx sdk.Context, ck *consumerkeeper.Keeper, heighValsetUpdateIDs []consumertypes.HeightToValsetUpdateID) { t.Helper() ctr := 0 diff --git a/x/ccv/consumer/keeper/grpc_query.go b/x/ccv/consumer/keeper/grpc_query.go index 80e6b695a9..0d1bb78d16 100644 --- a/x/ccv/consumer/keeper/grpc_query.go +++ b/x/ccv/consumer/keeper/grpc_query.go @@ -9,6 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/interchain-security/v3/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v3/x/ccv/types" ) var _ types.QueryServer = Keeper{} //nolint:golint @@ -51,3 +52,25 @@ func (k Keeper) QueryProviderInfo(c context.Context, //nolint:golint return k.GetProviderInfo(ctx) } + +func (k Keeper) QueryThrottleState(c context.Context, + req *types.QueryThrottleStateRequest, +) (*types.QueryThrottleStateResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + + resp := types.QueryThrottleStateResponse{} + + slashRecord, found := k.GetSlashRecord(ctx) + if found { + resp.SlashRecord = &slashRecord + } else { + resp.SlashRecord = nil + } + + resp.PacketDataQueue = make([]ccvtypes.ConsumerPacketData, 0) + pendingPackets := k.GetAllPendingPacketsWithIdx(ctx) + for _, packet := range pendingPackets { + resp.PacketDataQueue = append(resp.PacketDataQueue, packet.ConsumerPacketData) + } + return &resp, nil +} diff --git a/x/ccv/consumer/keeper/keeper.go b/x/ccv/consumer/keeper/keeper.go index b84f3d1864..27076ac938 100644 --- a/x/ccv/consumer/keeper/keeper.go +++ b/x/ccv/consumer/keeper/keeper.go @@ -309,8 +309,8 @@ func (k Keeper) DeletePreCCV(ctx sdk.Context) { func (k Keeper) SetInitialValSet(ctx sdk.Context, initialValSet []tmtypes.ValidatorUpdate) { store := ctx.KVStore(k.storeKey) - initialValSetState := ccv.ConsumerGenesisState{ - InitialValSet: initialValSet, + initialValSetState := types.GenesisState{ + Provider: ccv.ProviderInfo{InitialValSet: initialValSet}, } bz := k.cdc.MustMarshal(&initialValSetState) store.Set(types.InitialValSetKey(), bz) @@ -318,11 +318,11 @@ func (k Keeper) SetInitialValSet(ctx sdk.Context, initialValSet []tmtypes.Valida func (k Keeper) GetInitialValSet(ctx sdk.Context) []tmtypes.ValidatorUpdate { store := ctx.KVStore(k.storeKey) - initialValSet := ccv.ConsumerGenesisState{} + initialValSet := types.GenesisState{} bz := store.Get(types.InitialValSetKey()) if bz != nil { k.cdc.MustUnmarshal(bz, &initialValSet) - return initialValSet.InitialValSet + return initialValSet.Provider.InitialValSet } return []tmtypes.ValidatorUpdate{} } @@ -336,14 +336,14 @@ func (k Keeper) GetLastStandaloneValidators(ctx sdk.Context) []stakingtypes.Vali // GetElapsedPacketMaturityTimes returns a slice of already elapsed PacketMaturityTimes, sorted by maturity times, // i.e., the slice contains the IDs of the matured VSCPackets. -func (k Keeper) GetElapsedPacketMaturityTimes(ctx sdk.Context) (maturingVSCPackets []ccv.MaturingVSCPacket) { +func (k Keeper) GetElapsedPacketMaturityTimes(ctx sdk.Context) (maturingVSCPackets []types.MaturingVSCPacket) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte{types.PacketMaturityTimeBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { - var maturingVSCPacket ccv.MaturingVSCPacket + var maturingVSCPacket types.MaturingVSCPacket if err := maturingVSCPacket.Unmarshal(iterator.Value()); err != nil { // An error here would indicate something is very wrong, // the MaturingVSCPackets are assumed to be correctly serialized in SetPacketMaturityTime. @@ -368,13 +368,13 @@ func (k Keeper) GetElapsedPacketMaturityTimes(ctx sdk.Context) (maturingVSCPacke // PacketMaturityTimeBytePrefix | maturityTime.UnixNano() | vscID // Thus, the returned array is in ascending order of maturityTimes. // If two entries have the same maturityTime, then they are ordered by vscID. -func (k Keeper) GetAllPacketMaturityTimes(ctx sdk.Context) (maturingVSCPackets []ccv.MaturingVSCPacket) { +func (k Keeper) GetAllPacketMaturityTimes(ctx sdk.Context) (maturingVSCPackets []types.MaturingVSCPacket) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte{types.PacketMaturityTimeBytePrefix}) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { - var maturingVSCPacket ccv.MaturingVSCPacket + var maturingVSCPacket types.MaturingVSCPacket if err := maturingVSCPacket.Unmarshal(iterator.Value()); err != nil { // An error here would indicate something is very wrong, // the MaturingVSCPackets are assumed to be correctly serialized in SetPacketMaturityTime. @@ -389,7 +389,7 @@ func (k Keeper) GetAllPacketMaturityTimes(ctx sdk.Context) (maturingVSCPackets [ // SetPacketMaturityTime sets the maturity time for a given received VSC packet id func (k Keeper) SetPacketMaturityTime(ctx sdk.Context, vscId uint64, maturityTime time.Time) { store := ctx.KVStore(k.storeKey) - maturingVSCPacket := ccv.MaturingVSCPacket{ + maturingVSCPacket := types.MaturingVSCPacket{ VscId: vscId, MaturityTime: maturityTime, } @@ -469,7 +469,7 @@ func (k Keeper) DeleteHeightValsetUpdateID(ctx sdk.Context, height uint64) { // Note that the block height to vscID mapping is stored under keys with the following format: // HeightValsetUpdateIDBytePrefix | height // Thus, the returned array is in ascending order of heights. -func (k Keeper) GetAllHeightToValsetUpdateIDs(ctx sdk.Context) (heightToValsetUpdateIDs []ccv.HeightToValsetUpdateID) { +func (k Keeper) GetAllHeightToValsetUpdateIDs(ctx sdk.Context) (heightToValsetUpdateIDs []types.HeightToValsetUpdateID) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte{types.HeightValsetUpdateIDBytePrefix}) @@ -478,7 +478,7 @@ func (k Keeper) GetAllHeightToValsetUpdateIDs(ctx sdk.Context) (heightToValsetUp height := binary.BigEndian.Uint64(iterator.Key()[1:]) vscID := binary.BigEndian.Uint64(iterator.Value()) - heightToValsetUpdateIDs = append(heightToValsetUpdateIDs, ccv.HeightToValsetUpdateID{ + heightToValsetUpdateIDs = append(heightToValsetUpdateIDs, types.HeightToValsetUpdateID{ Height: height, ValsetUpdateId: vscID, }) @@ -515,7 +515,7 @@ func (k Keeper) DeleteOutstandingDowntime(ctx sdk.Context, consAddress string) { // Note that the outstanding downtime flags are stored under keys with the following format: // OutstandingDowntimeBytePrefix | consAddress // Thus, the returned array is in ascending order of consAddresses. -func (k Keeper) GetAllOutstandingDowntimes(ctx sdk.Context) (downtimes []ccv.OutstandingDowntime) { +func (k Keeper) GetAllOutstandingDowntimes(ctx sdk.Context) (downtimes []types.OutstandingDowntime) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, []byte{types.OutstandingDowntimeBytePrefix}) @@ -524,7 +524,7 @@ func (k Keeper) GetAllOutstandingDowntimes(ctx sdk.Context) (downtimes []ccv.Out addrBytes := iterator.Key()[1:] addr := sdk.ConsAddress(addrBytes).String() - downtimes = append(downtimes, ccv.OutstandingDowntime{ + downtimes = append(downtimes, types.OutstandingDowntime{ ValidatorConsensusAddress: addr, }) } @@ -578,21 +578,6 @@ func (k Keeper) GetAllCCValidator(ctx sdk.Context) (validators []types.CrossChai return validators } -// Implement from stakingkeeper interface -func (k Keeper) GetAllValidators(ctx sdk.Context) (validators []stakingtypes.Validator) { - store := ctx.KVStore(k.storeKey) - - iterator := sdk.KVStorePrefixIterator(store, stakingtypes.ValidatorsKey) - defer iterator.Close() - - for ; iterator.Valid(); iterator.Next() { - validator := stakingtypes.MustUnmarshalValidator(k.cdc, iterator.Value()) - validators = append(validators, validator) - } - - return validators -} - // getAndIncrementPendingPacketsIdx returns the current pending packets index and increments it. // This index is used for implementing a FIFO queue of pending packets in the KV store. func (k Keeper) getAndIncrementPendingPacketsIdx(ctx sdk.Context) (toReturn uint64) { diff --git a/x/ccv/consumer/keeper/keeper_test.go b/x/ccv/consumer/keeper/keeper_test.go index 4b536a071a..06fdeae082 100644 --- a/x/ccv/consumer/keeper/keeper_test.go +++ b/x/ccv/consumer/keeper/keeper_test.go @@ -201,7 +201,7 @@ func TestPacketMaturityTime(t *testing.T) { defer ctrl.Finish() now := time.Now().UTC() - packets := []ccv.MaturingVSCPacket{ + packets := []types.MaturingVSCPacket{ { VscId: 2, MaturityTime: now, @@ -220,9 +220,9 @@ func TestPacketMaturityTime(t *testing.T) { }, } // sort by MaturityTime and not by VscId - expectedGetAllOrder := []ccv.MaturingVSCPacket{packets[2], packets[1], packets[0], packets[3]} + expectedGetAllOrder := []types.MaturingVSCPacket{packets[2], packets[1], packets[0], packets[3]} // only packets with MaturityTime before or equal to now - expectedGetElapsedOrder := []ccv.MaturingVSCPacket{packets[2], packets[1], packets[0]} + expectedGetElapsedOrder := []types.MaturingVSCPacket{packets[2], packets[1], packets[0]} // test SetPacketMaturityTime for _, packet := range packets { @@ -502,7 +502,7 @@ func TestGetAllHeightToValsetUpdateIDs(t *testing.T) { ck, ctx, ctrl, _ := testkeeper.GetConsumerKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() - cases := []ccv.HeightToValsetUpdateID{ + cases := []types.HeightToValsetUpdateID{ { ValsetUpdateId: 2, Height: 22, @@ -549,9 +549,9 @@ func TestGetAllOutstandingDowntimes(t *testing.T) { sdk.ConsAddress([]byte("consAddress4")), sdk.ConsAddress([]byte("consAddress3")), } - expectedGetAllOrder := []ccv.OutstandingDowntime{} + expectedGetAllOrder := []types.OutstandingDowntime{} for _, addr := range addresses { - expectedGetAllOrder = append(expectedGetAllOrder, ccv.OutstandingDowntime{ValidatorConsensusAddress: addr.String()}) + expectedGetAllOrder = append(expectedGetAllOrder, types.OutstandingDowntime{ValidatorConsensusAddress: addr.String()}) } // sorting by ConsAddress sort.Slice(expectedGetAllOrder, func(i, j int) bool { diff --git a/x/ccv/consumer/keeper/migration.go b/x/ccv/consumer/keeper/migration.go index 5d5d913b9b..e63960fdb1 100644 --- a/x/ccv/consumer/keeper/migration.go +++ b/x/ccv/consumer/keeper/migration.go @@ -7,7 +7,6 @@ import ( paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" consumertypes "github.com/cosmos/interchain-security/v3/x/ccv/consumer/types" - ccvtypes "github.com/cosmos/interchain-security/v3/x/ccv/types" ) // Migrator is a struct for handling in-place store migrations. @@ -32,7 +31,7 @@ func (m Migrator) Migrate1to2(ctx sdk.Context) error { // Note an equivalent migration is not required for providers. func (k Keeper) MigrateConsumerPacketData(ctx sdk.Context) error { // deserialize packet data from old format - var depreciatedType ccvtypes.ConsumerPacketDataList + var depreciatedType consumertypes.ConsumerPacketDataList store := ctx.KVStore(k.storeKey) bz := store.Get([]byte{consumertypes.PendingDataPacketsBytePrefix}) if bz == nil { @@ -64,7 +63,7 @@ func PendingDataPacketsKeyOnlyForTesting() []byte { // Note: a better test of the old functionality would be to directly reference the old ICS version, // including the version of ccv.ConsumerPacketDataList has a list of ccv.ConsumerPacketData without indexes. -func (k Keeper) SetPendingPacketsOnlyForTesting(ctx sdk.Context, packets ccvtypes.ConsumerPacketDataList) { +func (k Keeper) SetPendingPacketsOnlyForTesting(ctx sdk.Context, packets consumertypes.ConsumerPacketDataList) { store := ctx.KVStore(k.storeKey) bz, err := packets.Marshal() if err != nil { diff --git a/x/ccv/consumer/keeper/migration_test.go b/x/ccv/consumer/keeper/migration_test.go index 7cb87665f0..359e394f31 100644 --- a/x/ccv/consumer/keeper/migration_test.go +++ b/x/ccv/consumer/keeper/migration_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/require" testutil "github.com/cosmos/interchain-security/v3/testutil/keeper" + "github.com/cosmos/interchain-security/v3/x/ccv/consumer/types" ccvtypes "github.com/cosmos/interchain-security/v3/x/ccv/types" ) @@ -14,7 +15,7 @@ func TestMigrateConsumerPacketData(t *testing.T) { defer ctrl.Finish() // Set some pending data packets in the old format - packets := ccvtypes.ConsumerPacketDataList{ + packets := types.ConsumerPacketDataList{ List: []ccvtypes.ConsumerPacketData{ { Type: ccvtypes.SlashPacket, diff --git a/x/ccv/consumer/keeper/params.go b/x/ccv/consumer/keeper/params.go index 12524fe3d2..3c0e01f1c3 100644 --- a/x/ccv/consumer/keeper/params.go +++ b/x/ccv/consumer/keeper/params.go @@ -25,6 +25,7 @@ func (k Keeper) GetConsumerParams(ctx sdk.Context) ccvtypes.ConsumerParams { k.GetSoftOptOutThreshold(ctx), k.GetRewardDenoms(ctx), k.GetProviderRewardDenoms(ctx), + k.GetRetryDelayPeriod(ctx), ) } @@ -138,3 +139,9 @@ func (k Keeper) GetProviderRewardDenoms(ctx sdk.Context) []string { k.paramStore.Get(ctx, ccvtypes.KeyProviderRewardDenoms, &denoms) return denoms } + +func (k Keeper) GetRetryDelayPeriod(ctx sdk.Context) time.Duration { + var period time.Duration + k.paramStore.Get(ctx, ccvtypes.KeyRetryDelayPeriod, &period) + return period +} diff --git a/x/ccv/consumer/keeper/params_test.go b/x/ccv/consumer/keeper/params_test.go index 49b1816520..e575e26185 100644 --- a/x/ccv/consumer/keeper/params_test.go +++ b/x/ccv/consumer/keeper/params_test.go @@ -31,6 +31,7 @@ func TestParams(t *testing.T) { ccv.DefaultSoftOptOutThreshold, rewardDenoms, provideRewardDenoms, + ccv.DefaultRetryDelayPeriod, ) // these are the default params, IBC suite independently sets enabled=true params := consumerKeeper.GetConsumerParams(ctx) @@ -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, "0.05", []string{"untrn"}, []string{"uatom"}) + 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/relay.go b/x/ccv/consumer/keeper/relay.go index 060aadff20..3afeb33188 100644 --- a/x/ccv/consumer/keeper/relay.go +++ b/x/ccv/consumer/keeper/relay.go @@ -115,12 +115,12 @@ func (k Keeper) QueueVSCMaturedPackets(ctx sdk.Context) { ctx.EventManager().EmitEvent( sdk.NewEvent( - ccv.EventTypeVSCMatured, + types.EventTypeVSCMatured, sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), sdk.NewAttribute(ccv.AttributeChainID, ctx.ChainID()), - sdk.NewAttribute(ccv.AttributeConsumerHeight, strconv.Itoa(int(ctx.BlockHeight()))), + sdk.NewAttribute(types.AttributeConsumerHeight, strconv.Itoa(int(ctx.BlockHeight()))), sdk.NewAttribute(ccv.AttributeValSetUpdateID, strconv.Itoa(int(maturityTime.VscId))), - sdk.NewAttribute(ccv.AttributeTimestamp, ctx.BlockTime().String()), + sdk.NewAttribute(types.AttributeTimestamp, ctx.BlockTime().String()), ), ) } @@ -162,7 +162,7 @@ func (k Keeper) QueueSlashPacket(ctx sdk.Context, validator abci.Validator, vals ctx.EventManager().EmitEvent( sdk.NewEvent( - ccv.EventTypeConsumerSlashRequest, + types.EventTypeConsumerSlashRequest, sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), sdk.NewAttribute(ccv.AttributeValidatorAddress, sdk.ConsAddress(validator.Address).String()), sdk.NewAttribute(ccv.AttributeValSetUpdateID, strconv.Itoa(int(valsetUpdateID))), diff --git a/x/ccv/consumer/keeper/throttle_retry.go b/x/ccv/consumer/keeper/throttle_retry.go index 4c4585cb1d..7f8d85191d 100644 --- a/x/ccv/consumer/keeper/throttle_retry.go +++ b/x/ccv/consumer/keeper/throttle_retry.go @@ -2,7 +2,6 @@ package keeper import ( "fmt" - "time" sdktypes "github.com/cosmos/cosmos-sdk/types" @@ -44,9 +43,6 @@ import ( // This design is implemented below, and in relay.go under SendPackets() and OnAcknowledgementPacket(). // -// Retry delay period could be implemented as a param, but 1 hour is reasonable -const RetryDelayPeriod = time.Hour - // PacketSendingPermitted returns whether the consumer is allowed to send packets // from the pending packets queue. func (k Keeper) PacketSendingPermitted(ctx sdktypes.Context) bool { @@ -60,7 +56,7 @@ func (k Keeper) PacketSendingPermitted(ctx sdktypes.Context) bool { return false } // If retry delay period has elapsed, we can send again - return ctx.BlockTime().After(record.SendTime.Add(RetryDelayPeriod)) + return ctx.BlockTime().After(record.SendTime.Add(k.GetRetryDelayPeriod(ctx))) } func (k Keeper) UpdateSlashRecordOnSend(ctx sdktypes.Context) { diff --git a/x/ccv/consumer/keeper/throttle_retry_test.go b/x/ccv/consumer/keeper/throttle_retry_test.go index cc14ce3cdd..50157df843 100644 --- a/x/ccv/consumer/keeper/throttle_retry_test.go +++ b/x/ccv/consumer/keeper/throttle_retry_test.go @@ -7,14 +7,16 @@ import ( "github.com/stretchr/testify/require" testutil "github.com/cosmos/interchain-security/v3/testutil/keeper" - consumerkeeper "github.com/cosmos/interchain-security/v3/x/ccv/consumer/keeper" consumertypes "github.com/cosmos/interchain-security/v3/x/ccv/consumer/types" + ccvtypes "github.com/cosmos/interchain-security/v3/x/ccv/types" ) func TestPacketSendingPermitted(t *testing.T) { consumerKeeper, ctx, ctrl, _ := testutil.GetConsumerKeeperAndCtx(t, testutil.NewInMemKeeperParams(t)) defer ctrl.Finish() + consumerKeeper.SetParams(ctx, ccvtypes.DefaultParams()) + ctx = ctx.WithBlockTime(time.Now()) // No slash record exists, send is permitted @@ -42,7 +44,8 @@ func TestPacketSendingPermitted(t *testing.T) { require.False(t, consumerKeeper.PacketSendingPermitted(ctx)) // Elapse retry delay period - ctx = ctx.WithBlockTime(ctx.BlockTime().Add(2 * consumerkeeper.RetryDelayPeriod)) + period := consumerKeeper.GetRetryDelayPeriod(ctx) + ctx = ctx.WithBlockTime(ctx.BlockTime().Add(2 * period)) // Now packet sending is permitted again require.True(t, consumerKeeper.PacketSendingPermitted(ctx)) diff --git a/x/ccv/consumer/keeper/validators.go b/x/ccv/consumer/keeper/validators.go index 2233b22d28..c3c9638b4d 100644 --- a/x/ccv/consumer/keeper/validators.go +++ b/x/ccv/consumer/keeper/validators.go @@ -312,3 +312,9 @@ func (k Keeper) MustGetCurrentValidatorsAsABCIUpdates(ctx sdk.Context) []abci.Va func (k Keeper) ApplyAndReturnValidatorSetUpdates(sdk.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{} +} diff --git a/x/ccv/consumer/module.go b/x/ccv/consumer/module.go index ba38b01d73..f063075211 100644 --- a/x/ccv/consumer/module.go +++ b/x/ccv/consumer/module.go @@ -57,7 +57,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { // ValidateGenesis performs genesis state validation for the ibc consumer module. func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { - var data ccvtypes.ConsumerGenesisState + var data consumertypes.GenesisState if err := cdc.UnmarshalJSON(bz, &data); err != nil { return fmt.Errorf("failed to unmarshal %s genesis state: %w", consumertypes.ModuleName, err) } @@ -117,7 +117,7 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { // InitGenesis performs genesis initialization for the consumer module. It returns // no validator updates. func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { - var genesisState ccvtypes.ConsumerGenesisState + var genesisState consumertypes.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) return am.keeper.InitGenesis(ctx, &genesisState) } diff --git a/x/ccv/consumer/types/consumer.pb.go b/x/ccv/consumer/types/consumer.pb.go index c6c09166a5..93a3c32a83 100644 --- a/x/ccv/consumer/types/consumer.pb.go +++ b/x/ccv/consumer/types/consumer.pb.go @@ -10,8 +10,6 @@ import ( _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" - _ "github.com/cosmos/interchain-security/v3/x/ccv/types" - _ "google.golang.org/protobuf/types/known/durationpb" _ "google.golang.org/protobuf/types/known/timestamppb" io "io" math "math" @@ -31,10 +29,10 @@ var _ = time.Kitchen // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// CrossChainValidator defines the type used to store validator information internal -// to the consumer CCV module. Note one cross chain validator entry is persisted for -// each consumer validator, where incoming VSC packets update this data, which is eventually -// forwarded to comet for consumer chain consensus. +// CrossChainValidator defines the type used to store validator information +// internal to the consumer CCV module. Note one cross chain validator entry is +// persisted for each consumer validator, where incoming VSC packets update this +// data, which is eventually forwarded to comet for consumer chain consensus. // // Note this type is only used internally to the consumer CCV module. type CrossChainValidator struct { @@ -164,34 +162,33 @@ func init() { } var fileDescriptor_5b27a82b276e7f93 = []byte{ - // 432 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x52, 0xcb, 0x8e, 0xd3, 0x30, - 0x14, 0xad, 0x19, 0x31, 0x94, 0x14, 0x21, 0x14, 0x2a, 0x51, 0xba, 0x48, 0xab, 0x22, 0xa4, 0x6e, - 0xc6, 0x56, 0xdb, 0x1d, 0x12, 0x8b, 0xe9, 0x2c, 0x59, 0x80, 0x02, 0x02, 0x89, 0x4d, 0xe4, 0x38, - 0x26, 0xb5, 0x48, 0x7c, 0x23, 0x3f, 0x52, 0xcc, 0x57, 0xcc, 0x67, 0xf0, 0x01, 0x7c, 0xc4, 0x88, - 0xd5, 0x2c, 0x59, 0x0d, 0xa8, 0xfd, 0x03, 0xbe, 0x00, 0xe5, 0x55, 0xc4, 0xc0, 0xec, 0xee, 0xf1, - 0xf1, 0x39, 0x3e, 0xf7, 0xfa, 0x7a, 0x4b, 0x21, 0x0d, 0x57, 0x6c, 0x43, 0x85, 0x8c, 0x34, 0x67, - 0x56, 0x09, 0xe3, 0x08, 0x63, 0x25, 0x61, 0x20, 0xb5, 0xcd, 0xb9, 0x22, 0xe5, 0xe2, 0x50, 0xe3, - 0x42, 0x81, 0x01, 0xff, 0xc9, 0x7f, 0x34, 0x98, 0xb1, 0x12, 0x1f, 0xee, 0x95, 0x8b, 0xf1, 0xd3, - 0x9b, 0x8c, 0xcb, 0x05, 0xd9, 0x0a, 0xc5, 0x1b, 0xaf, 0xf1, 0xe3, 0x14, 0x20, 0xcd, 0x38, 0xa9, - 0x51, 0x6c, 0x3f, 0x10, 0x2a, 0x5d, 0x4b, 0x0d, 0x53, 0x48, 0xa1, 0x2e, 0x49, 0x55, 0x75, 0x02, - 0x06, 0x3a, 0x07, 0x1d, 0x35, 0x44, 0x03, 0x5a, 0x2a, 0xb8, 0xee, 0x95, 0x58, 0x45, 0x8d, 0x00, - 0xd9, 0xf2, 0x93, 0xeb, 0xbc, 0x11, 0x39, 0xd7, 0x86, 0xe6, 0x45, 0x73, 0x61, 0xf6, 0x05, 0x79, - 0x0f, 0xcf, 0x14, 0x68, 0x7d, 0x56, 0xc5, 0x7e, 0x4b, 0x33, 0x91, 0x50, 0x03, 0xca, 0x1f, 0x79, - 0x77, 0x68, 0x92, 0x28, 0xae, 0xf5, 0x08, 0x4d, 0xd1, 0xfc, 0x5e, 0xd8, 0x41, 0x7f, 0xe8, 0xdd, - 0x2e, 0x60, 0xcb, 0xd5, 0xe8, 0xd6, 0x14, 0xcd, 0x8f, 0xc2, 0x06, 0xf8, 0xd4, 0x3b, 0x2e, 0x6c, - 0xfc, 0x91, 0xbb, 0xd1, 0xd1, 0x14, 0xcd, 0x07, 0xcb, 0x21, 0x6e, 0x5e, 0xc6, 0xdd, 0xcb, 0xf8, - 0x54, 0xba, 0xf5, 0xea, 0xd7, 0xd5, 0xe4, 0x91, 0xa3, 0x79, 0xf6, 0x6c, 0x56, 0x0d, 0x8e, 0x4b, - 0x6d, 0x75, 0xd4, 0xe8, 0x66, 0xdf, 0xbe, 0x9e, 0x0c, 0xdb, 0xde, 0x98, 0x72, 0x85, 0x01, 0xfc, - 0xca, 0xc6, 0x2f, 0xb8, 0x0b, 0x5b, 0xe3, 0xd9, 0x67, 0x6f, 0xf0, 0x3a, 0xa3, 0x7a, 0x13, 0x72, - 0x06, 0x2a, 0xf1, 0xe7, 0xde, 0x83, 0x2d, 0x15, 0x46, 0xc8, 0x34, 0x02, 0x19, 0x29, 0x5e, 0x64, - 0xae, 0x8e, 0xda, 0x0f, 0xef, 0xb7, 0xe7, 0x2f, 0x65, 0x58, 0x9d, 0xfa, 0xa7, 0xde, 0x5d, 0xcd, - 0x65, 0x12, 0x55, 0xbd, 0xd7, 0xa9, 0x07, 0xcb, 0xf1, 0x3f, 0xf1, 0xde, 0x74, 0x83, 0x59, 0xf7, - 0x2f, 0xae, 0x26, 0xbd, 0xf3, 0x1f, 0x13, 0x14, 0xf6, 0x2b, 0x59, 0x45, 0xac, 0xdf, 0x5d, 0xec, - 0x02, 0x74, 0xb9, 0x0b, 0xd0, 0xcf, 0x5d, 0x80, 0xce, 0xf7, 0x41, 0xef, 0x72, 0x1f, 0xf4, 0xbe, - 0xef, 0x83, 0xde, 0xfb, 0xe7, 0xa9, 0x30, 0x1b, 0x1b, 0x63, 0x06, 0x79, 0xfb, 0x35, 0xe4, 0xcf, - 0x1a, 0x9c, 0x1c, 0xd6, 0xa0, 0x5c, 0x91, 0x4f, 0x7f, 0x2f, 0x99, 0x71, 0x05, 0xd7, 0xf1, 0x71, - 0x1d, 0x60, 0xf5, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x5c, 0xdb, 0x0f, 0x5e, 0x95, 0x02, 0x00, 0x00, + // 413 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x92, 0xcd, 0x8e, 0xd3, 0x30, + 0x10, 0xc7, 0x6b, 0x56, 0x2c, 0xc5, 0x45, 0x08, 0x85, 0x4a, 0x74, 0x7b, 0x48, 0xab, 0x70, 0xc9, + 0x65, 0x6d, 0x6d, 0x7b, 0x43, 0xe2, 0xb0, 0xdd, 0x23, 0x07, 0x50, 0x40, 0x20, 0x71, 0x89, 0x1c, + 0xc7, 0xa4, 0x16, 0x89, 0x27, 0xb2, 0x9d, 0x2c, 0xe6, 0x29, 0xf6, 0x31, 0x78, 0x00, 0x1e, 0x62, + 0xc5, 0x69, 0x8f, 0x9c, 0x0a, 0x6a, 0xdf, 0x80, 0x27, 0x40, 0xf9, 0x68, 0x11, 0xb0, 0xb7, 0xf9, + 0xf0, 0x7f, 0xe6, 0x37, 0xe3, 0xc1, 0x0b, 0xa9, 0xac, 0xd0, 0x7c, 0xcd, 0xa4, 0x8a, 0x8d, 0xe0, + 0x95, 0x96, 0xd6, 0x51, 0xce, 0x6b, 0xca, 0x41, 0x99, 0xaa, 0x10, 0x9a, 0xd6, 0x67, 0x07, 0x9b, + 0x94, 0x1a, 0x2c, 0x78, 0x4f, 0x6f, 0xd1, 0x10, 0xce, 0x6b, 0x72, 0x78, 0x57, 0x9f, 0x4d, 0x4f, + 0x32, 0x80, 0x2c, 0x17, 0xb4, 0x95, 0x24, 0xd5, 0x07, 0xca, 0x94, 0xeb, 0xf4, 0xd3, 0x71, 0x06, + 0x19, 0xb4, 0x26, 0x6d, 0xac, 0x3e, 0x7a, 0xc2, 0xc1, 0x14, 0x60, 0xe2, 0x2e, 0xd1, 0x39, 0x7d, + 0x6a, 0xf6, 0x6f, 0x2d, 0x2b, 0x0b, 0x61, 0x2c, 0x2b, 0xca, 0xee, 0x41, 0xf0, 0x05, 0xe1, 0xc7, + 0x17, 0x1a, 0x8c, 0xb9, 0x68, 0xa0, 0xde, 0xb2, 0x5c, 0xa6, 0xcc, 0x82, 0xf6, 0x26, 0xf8, 0x1e, + 0x4b, 0x53, 0x2d, 0x8c, 0x99, 0xa0, 0x39, 0x0a, 0x1f, 0x44, 0x7b, 0xd7, 0x1b, 0xe3, 0xbb, 0x25, + 0x5c, 0x0a, 0x3d, 0xb9, 0x33, 0x47, 0xe1, 0x51, 0xd4, 0x39, 0x1e, 0xc3, 0xc7, 0x65, 0x95, 0x7c, + 0x14, 0x6e, 0x72, 0x34, 0x47, 0xe1, 0x68, 0x31, 0x26, 0x5d, 0x67, 0xb2, 0xef, 0x4c, 0xce, 0x95, + 0x5b, 0x2d, 0x7f, 0x6d, 0x66, 0x4f, 0x1c, 0x2b, 0xf2, 0x67, 0x41, 0x33, 0xb1, 0x50, 0xa6, 0x32, + 0x71, 0xa7, 0x0b, 0xbe, 0x7d, 0x3d, 0x1d, 0xf7, 0xec, 0x5c, 0xbb, 0xd2, 0x02, 0x79, 0x55, 0x25, + 0x2f, 0x84, 0x8b, 0xfa, 0xc2, 0xc1, 0x67, 0x3c, 0x7a, 0x9d, 0x33, 0xb3, 0x8e, 0x04, 0x07, 0x9d, + 0x7a, 0x21, 0x7e, 0x74, 0xc9, 0xa4, 0x95, 0x2a, 0x8b, 0x41, 0xc5, 0x5a, 0x94, 0xb9, 0x6b, 0x51, + 0x87, 0xd1, 0xc3, 0x3e, 0xfe, 0x52, 0x45, 0x4d, 0xd4, 0x3b, 0xc7, 0xf7, 0x8d, 0x50, 0x69, 0xdc, + 0xcc, 0xde, 0x52, 0x8f, 0x16, 0xd3, 0xff, 0xf0, 0xde, 0xec, 0x17, 0xb3, 0x1a, 0x5e, 0x6f, 0x66, + 0x83, 0xab, 0x1f, 0x33, 0x14, 0x0d, 0x1b, 0x59, 0x93, 0x58, 0xbd, 0xbb, 0xde, 0xfa, 0xe8, 0x66, + 0xeb, 0xa3, 0x9f, 0x5b, 0x1f, 0x5d, 0xed, 0xfc, 0xc1, 0xcd, 0xce, 0x1f, 0x7c, 0xdf, 0xf9, 0x83, + 0xf7, 0xcf, 0x33, 0x69, 0xd7, 0x55, 0x42, 0x38, 0x14, 0xfd, 0xea, 0xe9, 0x9f, 0x4f, 0x3e, 0x3d, + 0x1c, 0x46, 0xbd, 0xa4, 0x9f, 0xfe, 0xbe, 0x0e, 0xeb, 0x4a, 0x61, 0x92, 0xe3, 0x16, 0x60, 0xf9, + 0x3b, 0x00, 0x00, 0xff, 0xff, 0x43, 0xb2, 0x00, 0x6a, 0x4e, 0x02, 0x00, 0x00, } func (m *CrossChainValidator) Marshal() (dAtA []byte, err error) { diff --git a/x/ccv/consumer/types/events.go b/x/ccv/consumer/types/events.go new file mode 100644 index 0000000000..ccc2616416 --- /dev/null +++ b/x/ccv/consumer/types/events.go @@ -0,0 +1,18 @@ +package types + +const ( + AttributeConsumerHeight = "consumer_height" + AttributeTimestamp = "timestamp" + + EventTypeFeeDistribution = "fee_distribution" + EventTypeVSCMatured = "vsc_matured" + EventTypeConsumerSlashRequest = "consumer_slash_request" + EventTypeFeeTransferChannelOpened = "fee_transfer_channel_opened" + + AttributeDistributionCurrentHeight = "current_distribution_height" + //#nosec G101 -- (false positive) this is not a hardcoded credential + AttributeDistributionNextHeight = "next_distribution_height" + AttributeDistributionFraction = "distribution_fraction" + AttributeDistributionTotal = "total" + AttributeDistributionToProvider = "provider_amount" +) diff --git a/x/ccv/consumer/types/genesis.go b/x/ccv/consumer/types/genesis.go new file mode 100644 index 0000000000..0aac48e8f5 --- /dev/null +++ b/x/ccv/consumer/types/genesis.go @@ -0,0 +1,173 @@ +package types + +import ( + ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + + errorsmod "cosmossdk.io/errors" + + abci "github.com/cometbft/cometbft/abci/types" + + ccv "github.com/cosmos/interchain-security/v3/x/ccv/types" +) + +// NewRestartGenesisState returns a consumer GenesisState that has already been established. +func NewRestartGenesisState( + clientID, channelID string, + maturingPackets []MaturingVSCPacket, + initValSet []abci.ValidatorUpdate, + heightToValsetUpdateIDs []HeightToValsetUpdateID, + pendingConsumerPackets ConsumerPacketDataList, + outstandingDowntimes []OutstandingDowntime, + lastTransBlockHeight LastTransmissionBlockHeight, + params ccv.ConsumerParams, +) *GenesisState { + return &GenesisState{ + NewChain: false, + Params: params, + Provider: ccv.ProviderInfo{ + InitialValSet: initValSet, + }, + MaturingPackets: maturingPackets, + HeightToValsetUpdateId: heightToValsetUpdateIDs, + PendingConsumerPackets: pendingConsumerPackets, + OutstandingDowntimeSlashing: outstandingDowntimes, + LastTransmissionBlockHeight: lastTransBlockHeight, + ProviderClientId: clientID, + ProviderChannelId: channelID, + } +} + +// DefaultGenesisState returns a default disabled consumer chain genesis state. This allows the module to be hooked up to app without getting use +// unless explicitly specified in genesis. +func DefaultGenesisState() *GenesisState { + return &GenesisState{ + Params: ccv.DefaultParams(), + } +} + +// NewInitialGenesisState returns a GenesisState for a completely new consumer chain. +func NewInitialGenesisState(cs *ibctmtypes.ClientState, consState *ibctmtypes.ConsensusState, + initValSet []abci.ValidatorUpdate, params ccv.ConsumerParams, +) *GenesisState { + return &GenesisState{ + NewChain: true, + Params: params, + Provider: ccv.ProviderInfo{ + ClientState: cs, + ConsensusState: consState, + InitialValSet: initValSet, + }, + } +} + +// Validate performs basic genesis state validation returning an error upon any failure. +// +// The three cases where a consumer chain starts/restarts +// expect the following optional and mandatory genesis states: +// +// 1. New chain starts: +// - Params, InitialValset, provider client state, provider consensus state // mandatory +// +// 2. Chain restarts with CCV handshake still in progress: +// - Params, InitialValset, ProviderID, HeightToValidatorSetUpdateID // mandatory +// - PendingConsumerPacket // optional +// +// 3. Chain restarts with CCV handshake completed: +// - Params, InitialValset, ProviderID, channelID, HeightToValidatorSetUpdateID // mandatory +// - MaturingVSCPackets, OutstandingDowntime, PendingConsumerPacket, LastTransmissionBlockHeight // optional +// + +func (gs GenesisState) Validate() error { + if !gs.Params.Enabled { + return nil + } + if len(gs.Provider.InitialValSet) == 0 { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "initial validator set is empty") + } + if err := gs.Params.Validate(); err != nil { + return err + } + + if gs.NewChain { + if gs.Provider.ClientState == nil { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider client state cannot be nil for new chain") + } + if err := gs.Provider.ClientState.Validate(); err != nil { + return errorsmod.Wrapf(ccv.ErrInvalidGenesis, "provider client state invalid for new chain %s", err.Error()) + } + if gs.Provider.ConsensusState == nil { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider consensus state cannot be nil for new chain") + } + if err := gs.Provider.ConsensusState.ValidateBasic(); err != nil { + return errorsmod.Wrapf(ccv.ErrInvalidGenesis, "provider consensus state invalid for new chain %s", err.Error()) + } + if gs.ProviderClientId != "" { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider client id cannot be set for new chain. It must be established on handshake") + } + if gs.ProviderChannelId != "" { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider channel id cannot be set for new chain. It must be established on handshake") + } + if len(gs.MaturingPackets) != 0 { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "maturing packets must be empty for new chain") + } + if len(gs.PendingConsumerPackets.List) != 0 { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "pending consumer packets must be empty for new chain") + } + if gs.LastTransmissionBlockHeight.Height != 0 { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "last transmission block height must be empty for new chain") + } + } else { + // NOTE: For restart genesis, we will verify initial validator set in InitGenesis. + if gs.ProviderClientId == "" { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider client id must be set for a restarting consumer genesis state") + } + // handshake is still in progress + handshakeInProgress := gs.ProviderChannelId == "" + if handshakeInProgress { + if len(gs.MaturingPackets) != 0 { + return errorsmod.Wrap( + ccv.ErrInvalidGenesis, "maturing packets must be empty when handshake isn't completed") + } + if len(gs.OutstandingDowntimeSlashing) != 0 { + return errorsmod.Wrap( + ccv.ErrInvalidGenesis, "outstanding downtime must be empty when handshake isn't completed") + } + if gs.LastTransmissionBlockHeight.Height != 0 { + return errorsmod.Wrap( + ccv.ErrInvalidGenesis, "last transmission block height must be zero when handshake isn't completed") + } + if len(gs.PendingConsumerPackets.List) != 0 { + for _, packet := range gs.PendingConsumerPackets.List { + if packet.Type == ccv.VscMaturedPacket { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "pending maturing packets must be empty when handshake isn't completed") + } + } + } + } + /* if gs.HeightToValsetUpdateId == nil { + return errorsmod.Wrap( + ccv.ErrInvalidGenesis, + "empty height to validator set update id mapping", + ) + } */ + if gs.Provider.ClientState != nil || gs.Provider.ConsensusState != nil { + return errorsmod.Wrap(ccv.ErrInvalidGenesis, "provider client state and consensus state must be nil for a restarting genesis state") + } + for _, mat := range gs.MaturingPackets { + if err := mat.Validate(); err != nil { + return errorsmod.Wrap(err, "invalid unbonding sequences") + } + } + } + return nil +} + +func (mat MaturingVSCPacket) Validate() error { + if mat.MaturityTime.IsZero() { + return errorsmod.Wrap(ccv.ErrInvalidVSCMaturedTime, "cannot have 0 maturity time") + } + if mat.VscId == 0 { + return errorsmod.Wrap(ccv.ErrInvalidVSCMaturedId, "cannot have 0 maturity time") + } + return nil +} diff --git a/x/ccv/consumer/types/genesis.pb.go b/x/ccv/consumer/types/genesis.pb.go new file mode 100644 index 0000000000..66f3544a6c --- /dev/null +++ b/x/ccv/consumer/types/genesis.pb.go @@ -0,0 +1,2018 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: interchain_security/ccv/consumer/v1/genesis.proto + +package types + +import ( + fmt "fmt" + types1 "github.com/cometbft/cometbft/abci/types" + _ "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/v3/x/ccv/types" + _ "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. +// 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 + +// GenesisState defines the CCV consumer genesis state +// +// Note: this type is only used on consumer side and references shared types with +// provider +type GenesisState struct { + // ConsumerParams is a shared type with provider module + Params types.ConsumerParams `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + // Client ID of the provider. Empty for a new chain, filled in on restart. + ProviderClientId string `protobuf:"bytes,2,opt,name=provider_client_id,json=providerClientId,proto3" json:"provider_client_id,omitempty"` + // Channel ID of the provider. Empty for a new chain, filled in on restart. + ProviderChannelId string `protobuf:"bytes,3,opt,name=provider_channel_id,json=providerChannelId,proto3" json:"provider_channel_id,omitempty"` + // true for new chain, false for chain restart. + NewChain bool `protobuf:"varint,4,opt,name=new_chain,json=newChain,proto3" json:"new_chain,omitempty"` + // !!! DEPRECATED !!! ProviderClientState is deprecated. Use provider.client_state instead + ProviderClientState *_07_tendermint.ClientState `protobuf:"bytes,5,opt,name=provider_client_state,json=providerClientState,proto3" json:"provider_client_state,omitempty"` // Deprecated: Do not use. + // !!! DEPRECATED !!! ProviderConsensusState is deprecated. Use provider.consensus_state instead + ProviderConsensusState *_07_tendermint.ConsensusState `protobuf:"bytes,6,opt,name=provider_consensus_state,json=providerConsensusState,proto3" json:"provider_consensus_state,omitempty"` // Deprecated: Do not use. + // MaturingPackets nil on new chain, filled in on restart. + MaturingPackets []MaturingVSCPacket `protobuf:"bytes,7,rep,name=maturing_packets,json=maturingPackets,proto3" json:"maturing_packets"` + // !!! DEPRECATED !!!! InitialValset is deprecated. Use provider.initial_val_set instead + InitialValSet []types1.ValidatorUpdate `protobuf:"bytes,8,rep,name=initial_val_set,json=initialValSet,proto3" json:"initial_val_set"` // Deprecated: Do not use. + // HeightToValsetUpdateId nil on new chain, filled in on restart. + HeightToValsetUpdateId []HeightToValsetUpdateID `protobuf:"bytes,9,rep,name=height_to_valset_update_id,json=heightToValsetUpdateId,proto3" json:"height_to_valset_update_id"` + // OutstandingDowntimes nil on new chain, filled in on restart. + OutstandingDowntimeSlashing []OutstandingDowntime `protobuf:"bytes,10,rep,name=outstanding_downtime_slashing,json=outstandingDowntimeSlashing,proto3" json:"outstanding_downtime_slashing"` + // PendingConsumerPackets nil on new chain, filled in on restart. + PendingConsumerPackets ConsumerPacketDataList `protobuf:"bytes,11,opt,name=pending_consumer_packets,json=pendingConsumerPackets,proto3" json:"pending_consumer_packets"` + // LastTransmissionBlockHeight nil on new chain, filled in on restart. + LastTransmissionBlockHeight LastTransmissionBlockHeight `protobuf:"bytes,12,opt,name=last_transmission_block_height,json=lastTransmissionBlockHeight,proto3" json:"last_transmission_block_height"` + // flag indicating whether the consumer CCV module starts in pre-CCV state + PreCCV bool `protobuf:"varint,13,opt,name=preCCV,proto3" json:"preCCV,omitempty"` + Provider types.ProviderInfo `protobuf:"bytes,14,opt,name=provider,proto3" json:"provider"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_2db73a6057a27482, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.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 *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetParams() types.ConsumerParams { + if m != nil { + return m.Params + } + return types.ConsumerParams{} +} + +func (m *GenesisState) GetProviderClientId() string { + if m != nil { + return m.ProviderClientId + } + return "" +} + +func (m *GenesisState) GetProviderChannelId() string { + if m != nil { + return m.ProviderChannelId + } + return "" +} + +func (m *GenesisState) GetNewChain() bool { + if m != nil { + return m.NewChain + } + return false +} + +// Deprecated: Do not use. +func (m *GenesisState) GetProviderClientState() *_07_tendermint.ClientState { + if m != nil { + return m.ProviderClientState + } + return nil +} + +// Deprecated: Do not use. +func (m *GenesisState) GetProviderConsensusState() *_07_tendermint.ConsensusState { + if m != nil { + return m.ProviderConsensusState + } + return nil +} + +func (m *GenesisState) GetMaturingPackets() []MaturingVSCPacket { + if m != nil { + return m.MaturingPackets + } + return nil +} + +// Deprecated: Do not use. +func (m *GenesisState) GetInitialValSet() []types1.ValidatorUpdate { + if m != nil { + return m.InitialValSet + } + return nil +} + +func (m *GenesisState) GetHeightToValsetUpdateId() []HeightToValsetUpdateID { + if m != nil { + return m.HeightToValsetUpdateId + } + return nil +} + +func (m *GenesisState) GetOutstandingDowntimeSlashing() []OutstandingDowntime { + if m != nil { + return m.OutstandingDowntimeSlashing + } + return nil +} + +func (m *GenesisState) GetPendingConsumerPackets() ConsumerPacketDataList { + if m != nil { + return m.PendingConsumerPackets + } + return ConsumerPacketDataList{} +} + +func (m *GenesisState) GetLastTransmissionBlockHeight() LastTransmissionBlockHeight { + if m != nil { + return m.LastTransmissionBlockHeight + } + return LastTransmissionBlockHeight{} +} + +func (m *GenesisState) GetPreCCV() bool { + if m != nil { + return m.PreCCV + } + return false +} + +func (m *GenesisState) GetProvider() types.ProviderInfo { + if m != nil { + return m.Provider + } + return types.ProviderInfo{} +} + +// HeightValsetUpdateID represents a mapping internal to the consumer CCV module +// which links a block height to each recv valset update id. +type HeightToValsetUpdateID struct { + Height uint64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` + ValsetUpdateId uint64 `protobuf:"varint,2,opt,name=valset_update_id,json=valsetUpdateId,proto3" json:"valset_update_id,omitempty"` +} + +func (m *HeightToValsetUpdateID) Reset() { *m = HeightToValsetUpdateID{} } +func (m *HeightToValsetUpdateID) String() string { return proto.CompactTextString(m) } +func (*HeightToValsetUpdateID) ProtoMessage() {} +func (*HeightToValsetUpdateID) Descriptor() ([]byte, []int) { + return fileDescriptor_2db73a6057a27482, []int{1} +} +func (m *HeightToValsetUpdateID) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HeightToValsetUpdateID) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HeightToValsetUpdateID.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 *HeightToValsetUpdateID) XXX_Merge(src proto.Message) { + xxx_messageInfo_HeightToValsetUpdateID.Merge(m, src) +} +func (m *HeightToValsetUpdateID) XXX_Size() int { + return m.Size() +} +func (m *HeightToValsetUpdateID) XXX_DiscardUnknown() { + xxx_messageInfo_HeightToValsetUpdateID.DiscardUnknown(m) +} + +var xxx_messageInfo_HeightToValsetUpdateID proto.InternalMessageInfo + +func (m *HeightToValsetUpdateID) GetHeight() uint64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *HeightToValsetUpdateID) GetValsetUpdateId() uint64 { + if m != nil { + return m.ValsetUpdateId + } + return 0 +} + +// OutstandingDowntime defines the type used internally to the consumer CCV +// module and is used in order to not send multiple slashing requests for +// the same downtime infraction. +type OutstandingDowntime struct { + ValidatorConsensusAddress string `protobuf:"bytes,1,opt,name=validator_consensus_address,json=validatorConsensusAddress,proto3" json:"validator_consensus_address,omitempty"` +} + +func (m *OutstandingDowntime) Reset() { *m = OutstandingDowntime{} } +func (m *OutstandingDowntime) String() string { return proto.CompactTextString(m) } +func (*OutstandingDowntime) ProtoMessage() {} +func (*OutstandingDowntime) Descriptor() ([]byte, []int) { + return fileDescriptor_2db73a6057a27482, []int{2} +} +func (m *OutstandingDowntime) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *OutstandingDowntime) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_OutstandingDowntime.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 *OutstandingDowntime) XXX_Merge(src proto.Message) { + xxx_messageInfo_OutstandingDowntime.Merge(m, src) +} +func (m *OutstandingDowntime) XXX_Size() int { + return m.Size() +} +func (m *OutstandingDowntime) XXX_DiscardUnknown() { + xxx_messageInfo_OutstandingDowntime.DiscardUnknown(m) +} + +var xxx_messageInfo_OutstandingDowntime proto.InternalMessageInfo + +func (m *OutstandingDowntime) GetValidatorConsensusAddress() string { + if m != nil { + return m.ValidatorConsensusAddress + } + return "" +} + +// LastTransmissionBlockHeight is the last time validator holding +// pools were transmitted to the provider chain. This type is used internally +// to the consumer CCV modul. +type LastTransmissionBlockHeight struct { + Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` +} + +func (m *LastTransmissionBlockHeight) Reset() { *m = LastTransmissionBlockHeight{} } +func (m *LastTransmissionBlockHeight) String() string { return proto.CompactTextString(m) } +func (*LastTransmissionBlockHeight) ProtoMessage() {} +func (*LastTransmissionBlockHeight) Descriptor() ([]byte, []int) { + return fileDescriptor_2db73a6057a27482, []int{3} +} +func (m *LastTransmissionBlockHeight) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LastTransmissionBlockHeight) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LastTransmissionBlockHeight.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 *LastTransmissionBlockHeight) XXX_Merge(src proto.Message) { + xxx_messageInfo_LastTransmissionBlockHeight.Merge(m, src) +} +func (m *LastTransmissionBlockHeight) XXX_Size() int { + return m.Size() +} +func (m *LastTransmissionBlockHeight) XXX_DiscardUnknown() { + xxx_messageInfo_LastTransmissionBlockHeight.DiscardUnknown(m) +} + +var xxx_messageInfo_LastTransmissionBlockHeight proto.InternalMessageInfo + +func (m *LastTransmissionBlockHeight) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + +// MaturingVSCPacket represents a vsc packet that is maturing internal to the +// consumer CCV module, where the consumer has not yet relayed a VSCMatured +// packet back to the provider. +type MaturingVSCPacket struct { + VscId uint64 `protobuf:"varint,1,opt,name=vscId,proto3" json:"vscId,omitempty"` + MaturityTime time.Time `protobuf:"bytes,2,opt,name=maturity_time,json=maturityTime,proto3,stdtime" json:"maturity_time"` +} + +func (m *MaturingVSCPacket) Reset() { *m = MaturingVSCPacket{} } +func (m *MaturingVSCPacket) String() string { return proto.CompactTextString(m) } +func (*MaturingVSCPacket) ProtoMessage() {} +func (*MaturingVSCPacket) Descriptor() ([]byte, []int) { + return fileDescriptor_2db73a6057a27482, []int{4} +} +func (m *MaturingVSCPacket) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MaturingVSCPacket) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MaturingVSCPacket.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 *MaturingVSCPacket) XXX_Merge(src proto.Message) { + xxx_messageInfo_MaturingVSCPacket.Merge(m, src) +} +func (m *MaturingVSCPacket) XXX_Size() int { + return m.Size() +} +func (m *MaturingVSCPacket) XXX_DiscardUnknown() { + xxx_messageInfo_MaturingVSCPacket.DiscardUnknown(m) +} + +var xxx_messageInfo_MaturingVSCPacket proto.InternalMessageInfo + +func (m *MaturingVSCPacket) GetVscId() uint64 { + if m != nil { + return m.VscId + } + return 0 +} + +func (m *MaturingVSCPacket) GetMaturityTime() time.Time { + if m != nil { + return m.MaturityTime + } + return time.Time{} +} + +// ConsumerPacketDataList is a list of consumer packet data packets. +// +// Note this type is used internally to the consumer CCV module +// for exporting / importing state in InitGenesis and ExportGenesis. +type ConsumerPacketDataList struct { + List []types.ConsumerPacketData `protobuf:"bytes,1,rep,name=list,proto3" json:"list"` +} + +func (m *ConsumerPacketDataList) Reset() { *m = ConsumerPacketDataList{} } +func (m *ConsumerPacketDataList) String() string { return proto.CompactTextString(m) } +func (*ConsumerPacketDataList) ProtoMessage() {} +func (*ConsumerPacketDataList) Descriptor() ([]byte, []int) { + return fileDescriptor_2db73a6057a27482, []int{5} +} +func (m *ConsumerPacketDataList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ConsumerPacketDataList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ConsumerPacketDataList.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 *ConsumerPacketDataList) XXX_Merge(src proto.Message) { + xxx_messageInfo_ConsumerPacketDataList.Merge(m, src) +} +func (m *ConsumerPacketDataList) XXX_Size() int { + return m.Size() +} +func (m *ConsumerPacketDataList) XXX_DiscardUnknown() { + xxx_messageInfo_ConsumerPacketDataList.DiscardUnknown(m) +} + +var xxx_messageInfo_ConsumerPacketDataList proto.InternalMessageInfo + +func (m *ConsumerPacketDataList) GetList() []types.ConsumerPacketData { + if m != nil { + return m.List + } + return nil +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "interchain_security.ccv.consumer.v1.GenesisState") + proto.RegisterType((*HeightToValsetUpdateID)(nil), "interchain_security.ccv.consumer.v1.HeightToValsetUpdateID") + proto.RegisterType((*OutstandingDowntime)(nil), "interchain_security.ccv.consumer.v1.OutstandingDowntime") + proto.RegisterType((*LastTransmissionBlockHeight)(nil), "interchain_security.ccv.consumer.v1.LastTransmissionBlockHeight") + proto.RegisterType((*MaturingVSCPacket)(nil), "interchain_security.ccv.consumer.v1.MaturingVSCPacket") + proto.RegisterType((*ConsumerPacketDataList)(nil), "interchain_security.ccv.consumer.v1.ConsumerPacketDataList") +} + +func init() { + proto.RegisterFile("interchain_security/ccv/consumer/v1/genesis.proto", fileDescriptor_2db73a6057a27482) +} + +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, 0xba, 0x02, 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, 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, + 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, 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, 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, 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, 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, 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, + 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, 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, 0x67, 0xe0, 0x60, 0xc5, 0x10, + 0xc0, 0x6f, 0x40, 0x23, 0x2b, 0xf6, 0x61, 0xe1, 0x3e, 0xc0, 0x41, 0x90, 0x52, 0x99, 0xdf, 0xa6, + 0xb5, 0xe1, 0x7b, 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, 0xf5, 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, 0xf5, 0x75, 0xd3, 0x79, 0x73, 0xdd, 0x74, 0xfe, + 0xbd, 0x6e, 0x3a, 0xaf, 0x6e, 0x9a, 0x1b, 0x6f, 0x6e, 0x9a, 0x1b, 0x7f, 0xdd, 0x34, 0x37, 0x9e, + 0x7f, 0x1d, 0x32, 0x35, 0x99, 0x8e, 0x11, 0x11, 0xb1, 0x47, 0x84, 0x8c, 0x85, 0xf4, 0xe6, 0x34, + 0x9f, 0x96, 0x6f, 0x65, 0xf6, 0xd4, 0xfb, 0x65, 0xf9, 0x1f, 0x80, 0x79, 0xf9, 0xc6, 0x15, 0x53, + 0xe8, 0xd3, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x08, 0x63, 0x8d, 0x32, 0x08, 0x00, 0x00, +} + +func (m *GenesisState) 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 *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Provider.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x72 + if m.PreCCV { + i-- + if m.PreCCV { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x68 + } + { + size, err := m.LastTransmissionBlockHeight.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x62 + { + size, err := m.PendingConsumerPackets.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + if len(m.OutstandingDowntimeSlashing) > 0 { + for iNdEx := len(m.OutstandingDowntimeSlashing) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.OutstandingDowntimeSlashing[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x52 + } + } + if len(m.HeightToValsetUpdateId) > 0 { + for iNdEx := len(m.HeightToValsetUpdateId) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.HeightToValsetUpdateId[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x4a + } + } + if len(m.InitialValSet) > 0 { + for iNdEx := len(m.InitialValSet) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.InitialValSet[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + } + if len(m.MaturingPackets) > 0 { + for iNdEx := len(m.MaturingPackets) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MaturingPackets[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + } + if m.ProviderConsensusState != nil { + { + size, err := m.ProviderConsensusState.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + if m.ProviderClientState != nil { + { + size, err := m.ProviderClientState.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if m.NewChain { + i-- + if m.NewChain { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } + if len(m.ProviderChannelId) > 0 { + i -= len(m.ProviderChannelId) + copy(dAtA[i:], m.ProviderChannelId) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.ProviderChannelId))) + i-- + dAtA[i] = 0x1a + } + if len(m.ProviderClientId) > 0 { + i -= len(m.ProviderClientId) + copy(dAtA[i:], m.ProviderClientId) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.ProviderClientId))) + i-- + dAtA[i] = 0x12 + } + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *HeightToValsetUpdateID) 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 *HeightToValsetUpdateID) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HeightToValsetUpdateID) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ValsetUpdateId != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.ValsetUpdateId)) + i-- + dAtA[i] = 0x10 + } + if m.Height != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *OutstandingDowntime) 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 *OutstandingDowntime) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OutstandingDowntime) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ValidatorConsensusAddress) > 0 { + i -= len(m.ValidatorConsensusAddress) + copy(dAtA[i:], m.ValidatorConsensusAddress) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.ValidatorConsensusAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *LastTransmissionBlockHeight) 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 *LastTransmissionBlockHeight) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LastTransmissionBlockHeight) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Height != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MaturingVSCPacket) 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 *MaturingVSCPacket) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MaturingVSCPacket) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + n7, err7 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.MaturityTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.MaturityTime):]) + if err7 != nil { + return 0, err7 + } + i -= n7 + i = encodeVarintGenesis(dAtA, i, uint64(n7)) + i-- + dAtA[i] = 0x12 + if m.VscId != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.VscId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ConsumerPacketDataList) 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 *ConsumerPacketDataList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ConsumerPacketDataList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.List) > 0 { + for iNdEx := len(m.List) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.List[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + l = len(m.ProviderClientId) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = len(m.ProviderChannelId) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + if m.NewChain { + n += 2 + } + if m.ProviderClientState != nil { + l = m.ProviderClientState.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + if m.ProviderConsensusState != nil { + l = m.ProviderConsensusState.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + if len(m.MaturingPackets) > 0 { + for _, e := range m.MaturingPackets { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.InitialValSet) > 0 { + for _, e := range m.InitialValSet { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.HeightToValsetUpdateId) > 0 { + for _, e := range m.HeightToValsetUpdateId { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.OutstandingDowntimeSlashing) > 0 { + for _, e := range m.OutstandingDowntimeSlashing { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + l = m.PendingConsumerPackets.Size() + n += 1 + l + sovGenesis(uint64(l)) + l = m.LastTransmissionBlockHeight.Size() + n += 1 + l + sovGenesis(uint64(l)) + if m.PreCCV { + n += 2 + } + l = m.Provider.Size() + n += 1 + l + sovGenesis(uint64(l)) + return n +} + +func (m *HeightToValsetUpdateID) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Height != 0 { + n += 1 + sovGenesis(uint64(m.Height)) + } + if m.ValsetUpdateId != 0 { + n += 1 + sovGenesis(uint64(m.ValsetUpdateId)) + } + return n +} + +func (m *OutstandingDowntime) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ValidatorConsensusAddress) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} + +func (m *LastTransmissionBlockHeight) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Height != 0 { + n += 1 + sovGenesis(uint64(m.Height)) + } + return n +} + +func (m *MaturingVSCPacket) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.VscId != 0 { + n += 1 + sovGenesis(uint64(m.VscId)) + } + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.MaturityTime) + n += 1 + l + sovGenesis(uint64(l)) + return n +} + +func (m *ConsumerPacketDataList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.List) > 0 { + for _, e := range m.List { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) 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 ErrIntOverflowGenesis + } + 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: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: 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) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProviderClientId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + 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 ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProviderClientId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProviderChannelId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + 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 ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ProviderChannelId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NewChain", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.NewChain = bool(v != 0) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProviderClientState", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ProviderClientState == nil { + m.ProviderClientState = &_07_tendermint.ClientState{} + } + if err := m.ProviderClientState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProviderConsensusState", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ProviderConsensusState == nil { + m.ProviderConsensusState = &_07_tendermint.ConsensusState{} + } + if err := m.ProviderConsensusState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaturingPackets", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MaturingPackets = append(m.MaturingPackets, MaturingVSCPacket{}) + if err := m.MaturingPackets[len(m.MaturingPackets)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InitialValSet", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.InitialValSet = append(m.InitialValSet, types1.ValidatorUpdate{}) + if err := m.InitialValSet[len(m.InitialValSet)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HeightToValsetUpdateId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.HeightToValsetUpdateId = append(m.HeightToValsetUpdateId, HeightToValsetUpdateID{}) + if err := m.HeightToValsetUpdateId[len(m.HeightToValsetUpdateId)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OutstandingDowntimeSlashing", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OutstandingDowntimeSlashing = append(m.OutstandingDowntimeSlashing, OutstandingDowntime{}) + if err := m.OutstandingDowntimeSlashing[len(m.OutstandingDowntimeSlashing)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PendingConsumerPackets", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.PendingConsumerPackets.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LastTransmissionBlockHeight", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.LastTransmissionBlockHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 13: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PreCCV", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.PreCCV = bool(v != 0) + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Provider", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Provider.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HeightToValsetUpdateID) 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 ErrIntOverflowGenesis + } + 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: HeightToValsetUpdateID: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HeightToValsetUpdateID: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ValsetUpdateId", wireType) + } + m.ValsetUpdateId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ValsetUpdateId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *OutstandingDowntime) 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 ErrIntOverflowGenesis + } + 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: OutstandingDowntime: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OutstandingDowntime: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorConsensusAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + 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 ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorConsensusAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LastTransmissionBlockHeight) 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 ErrIntOverflowGenesis + } + 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: LastTransmissionBlockHeight: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LastTransmissionBlockHeight: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MaturingVSCPacket) 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 ErrIntOverflowGenesis + } + 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: MaturingVSCPacket: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MaturingVSCPacket: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field VscId", wireType) + } + m.VscId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.VscId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaturityTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.MaturityTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ConsumerPacketDataList) 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 ErrIntOverflowGenesis + } + 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: ConsumerPacketDataList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConsumerPacketDataList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field List", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.List = append(m.List, types.ConsumerPacketData{}) + if err := m.List[len(m.List)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/ccv/consumer/types/genesis_test.go b/x/ccv/consumer/types/genesis_test.go index d543c4df21..d8a8296762 100644 --- a/x/ccv/consumer/types/genesis_test.go +++ b/x/ccv/consumer/types/genesis_test.go @@ -16,7 +16,8 @@ import ( tmtypes "github.com/cometbft/cometbft/types" "github.com/cosmos/interchain-security/v3/testutil/crypto" - types "github.com/cosmos/interchain-security/v3/x/ccv/types" + "github.com/cosmos/interchain-security/v3/x/ccv/consumer/types" + ccv "github.com/cosmos/interchain-security/v3/x/ccv/types" ) const ( @@ -47,52 +48,54 @@ func TestValidateInitialGenesisState(t *testing.T) { cs := ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath) consensusState := ibctmtypes.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("apphash")), valHash) - params := types.DefaultParams() + params := ccv.DefaultParams() params.Enabled = true cases := []struct { name string - gs *types.ConsumerGenesisState + gs *types.GenesisState expError bool }{ { "valid new consumer genesis state", - types.NewInitialConsumerGenesisState(cs, consensusState, valUpdates, params), + types.NewInitialGenesisState(cs, consensusState, valUpdates, params), false, }, { "invalid new consumer genesis state: nil client state", - types.NewInitialConsumerGenesisState(nil, consensusState, valUpdates, params), + types.NewInitialGenesisState(nil, consensusState, valUpdates, params), true, }, { "invalid new consumer genesis state: invalid client state", - types.NewInitialConsumerGenesisState(&ibctmtypes.ClientState{ChainId: "badClientState"}, + types.NewInitialGenesisState(&ibctmtypes.ClientState{ChainId: "badClientState"}, consensusState, valUpdates, params), true, }, { "invalid new consumer genesis state: nil consensus state", - types.NewInitialConsumerGenesisState(cs, nil, valUpdates, params), + types.NewInitialGenesisState(cs, nil, valUpdates, params), true, }, { "invalid new consumer genesis state: invalid consensus state", - types.NewInitialConsumerGenesisState(cs, &ibctmtypes.ConsensusState{Timestamp: time.Now()}, + types.NewInitialGenesisState(cs, &ibctmtypes.ConsensusState{Timestamp: time.Now()}, valUpdates, params), true, }, { "invalid new consumer genesis state: client id not empty", - &types.ConsumerGenesisState{ - Params: params, - ProviderClientId: "ccvclient", - ProviderChannelId: "", - NewChain: true, - ProviderClientState: cs, - ProviderConsensusState: consensusState, + &types.GenesisState{ + Params: params, + ProviderClientId: "ccvclient", + ProviderChannelId: "", + NewChain: true, + Provider: ccv.ProviderInfo{ + ClientState: cs, + ConsensusState: consensusState, + InitialValSet: valUpdates, + }, MaturingPackets: nil, - InitialValSet: valUpdates, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, @@ -103,15 +106,17 @@ func TestValidateInitialGenesisState(t *testing.T) { }, { "invalid new consumer genesis state: channel id not empty", - &types.ConsumerGenesisState{ - Params: params, - ProviderClientId: "", - ProviderChannelId: "ccvchannel", - NewChain: true, - ProviderClientState: cs, - ProviderConsensusState: consensusState, + &types.GenesisState{ + Params: params, + ProviderClientId: "", + ProviderChannelId: "ccvchannel", + NewChain: true, + Provider: ccv.ProviderInfo{ + ClientState: cs, + ConsensusState: consensusState, + InitialValSet: valUpdates, + }, MaturingPackets: nil, - InitialValSet: valUpdates, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, @@ -122,15 +127,17 @@ func TestValidateInitialGenesisState(t *testing.T) { }, { "invalid new consumer genesis state: non-empty unbonding sequences", - &types.ConsumerGenesisState{ - Params: params, - ProviderClientId: "", - ProviderChannelId: "", - NewChain: true, - ProviderClientState: cs, - ProviderConsensusState: consensusState, + &types.GenesisState{ + Params: params, + ProviderClientId: "", + ProviderChannelId: "", + NewChain: true, + Provider: ccv.ProviderInfo{ + ClientState: cs, + ConsensusState: consensusState, + InitialValSet: valUpdates, + }, MaturingPackets: []types.MaturingVSCPacket{{}}, - InitialValSet: valUpdates, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, @@ -141,15 +148,17 @@ func TestValidateInitialGenesisState(t *testing.T) { }, { "invalid new consumer genesis state: non-empty last transmission packet", - &types.ConsumerGenesisState{ - Params: params, - ProviderClientId: "", - ProviderChannelId: "", - NewChain: true, - ProviderClientState: cs, - ProviderConsensusState: consensusState, + &types.GenesisState{ + Params: params, + ProviderClientId: "", + ProviderChannelId: "", + NewChain: true, + Provider: ccv.ProviderInfo{ + ClientState: cs, + ConsensusState: consensusState, + InitialValSet: valUpdates, + }, MaturingPackets: nil, - InitialValSet: valUpdates, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, @@ -160,18 +169,20 @@ func TestValidateInitialGenesisState(t *testing.T) { }, { "invalid new consumer genesis state: non-empty pending consumer packets", - &types.ConsumerGenesisState{ - Params: params, - ProviderClientId: "", - ProviderChannelId: "", - NewChain: true, - ProviderClientState: cs, - ProviderConsensusState: consensusState, + &types.GenesisState{ + Params: params, + ProviderClientId: "", + ProviderChannelId: "", + NewChain: true, + Provider: ccv.ProviderInfo{ + ClientState: cs, + ConsensusState: consensusState, + InitialValSet: valUpdates, + }, MaturingPackets: nil, - InitialValSet: valUpdates, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, - PendingConsumerPackets: types.ConsumerPacketDataList{List: []types.ConsumerPacketData{{}}}, + PendingConsumerPackets: types.ConsumerPacketDataList{List: []ccv.ConsumerPacketData{{}}}, LastTransmissionBlockHeight: types.LastTransmissionBlockHeight{}, PreCCV: false, }, @@ -179,12 +190,12 @@ func TestValidateInitialGenesisState(t *testing.T) { }, { "invalid new consumer genesis state: nil initial validator set", - types.NewInitialConsumerGenesisState(cs, consensusState, nil, params), + types.NewInitialGenesisState(cs, consensusState, nil, params), true, }, { "invalid new consumer genesis state: invalid consensus state validator set hash", - types.NewInitialConsumerGenesisState( + types.NewInitialGenesisState( cs, ibctmtypes.NewConsensusState( time.Now(), commitmenttypes.NewMerkleRoot([]byte("apphash")), []byte("wrong_length_hash")), valUpdates, params), @@ -192,7 +203,7 @@ func TestValidateInitialGenesisState(t *testing.T) { }, { "invalid new consumer genesis state: initial validator set does not match validator set hash", - types.NewInitialConsumerGenesisState( + types.NewInitialGenesisState( cs, ibctmtypes.NewConsensusState( time.Now(), commitmenttypes.NewMerkleRoot([]byte("apphash")), []byte("9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08")), valUpdates, params), @@ -200,7 +211,7 @@ func TestValidateInitialGenesisState(t *testing.T) { }, { "invalid new consumer genesis state: initial validator set does not match validator set hash", - types.NewInitialConsumerGenesisState( + types.NewInitialGenesisState( cs, ibctmtypes.NewConsensusState( time.Now(), commitmenttypes.NewMerkleRoot([]byte("apphash")), []byte("9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08")), valUpdates, params), @@ -208,39 +219,41 @@ func TestValidateInitialGenesisState(t *testing.T) { }, { "invalid new consumer genesis state: invalid params - ccvTimeoutPeriod", - types.NewInitialConsumerGenesisState(cs, consensusState, valUpdates, - types.NewParams( + types.NewInitialGenesisState(cs, consensusState, valUpdates, + ccv.NewParams( true, - types.DefaultBlocksPerDistributionTransmission, + ccv.DefaultBlocksPerDistributionTransmission, "", "", 0, // CCV timeout period cannot be 0 - types.DefaultTransferTimeoutPeriod, - types.DefaultConsumerRedistributeFrac, - types.DefaultHistoricalEntries, - types.DefaultConsumerUnbondingPeriod, - types.DefaultSoftOptOutThreshold, + ccv.DefaultTransferTimeoutPeriod, + ccv.DefaultConsumerRedistributeFrac, + ccv.DefaultHistoricalEntries, + ccv.DefaultConsumerUnbondingPeriod, + ccv.DefaultSoftOptOutThreshold, []string{}, []string{}, + ccv.DefaultRetryDelayPeriod, )), true, }, { "invalid new consumer genesis state: invalid params - distributionTransmissionChannel", - types.NewInitialConsumerGenesisState(cs, consensusState, valUpdates, - types.NewParams( + types.NewInitialGenesisState(cs, consensusState, valUpdates, + ccv.NewParams( true, - types.DefaultBlocksPerDistributionTransmission, + ccv.DefaultBlocksPerDistributionTransmission, "badchannel/", "", - types.DefaultCCVTimeoutPeriod, - types.DefaultTransferTimeoutPeriod, - types.DefaultConsumerRedistributeFrac, - types.DefaultHistoricalEntries, - types.DefaultConsumerUnbondingPeriod, - types.DefaultSoftOptOutThreshold, + ccv.DefaultCCVTimeoutPeriod, + ccv.DefaultTransferTimeoutPeriod, + ccv.DefaultConsumerRedistributeFrac, + ccv.DefaultHistoricalEntries, + ccv.DefaultConsumerUnbondingPeriod, + ccv.DefaultSoftOptOutThreshold, []string{}, []string{}, + ccv.DefaultRetryDelayPeriod, )), true, }, @@ -269,17 +282,17 @@ func TestValidateRestartConsumerGenesisState(t *testing.T) { valHash := valSet.Hash() valUpdates := tmtypes.TM2PB.ValidatorUpdates(valSet) - matConsumerPacket := types.ConsumerPacketData{ - Type: types.VscMaturedPacket, - Data: &types.ConsumerPacketData_VscMaturedPacketData{ - VscMaturedPacketData: types.NewVSCMaturedPacketData(1), + matConsumerPacket := ccv.ConsumerPacketData{ + Type: ccv.VscMaturedPacket, + Data: &ccv.ConsumerPacketData_VscMaturedPacketData{ + VscMaturedPacketData: ccv.NewVSCMaturedPacketData(1), }, } - slashConsumerPacket := types.ConsumerPacketData{ - Type: types.SlashPacket, - Data: &types.ConsumerPacketData_SlashPacketData{ - SlashPacketData: types.NewSlashPacketData( + slashConsumerPacket := ccv.ConsumerPacketData{ + Type: ccv.SlashPacket, + Data: &ccv.ConsumerPacketData_SlashPacketData{ + SlashPacketData: ccv.NewSlashPacketData( abci.Validator{Address: pubKey.Address(), Power: int64(1)}, 1, stakingtypes.Infraction_INFRACTION_DOWNTIME), @@ -294,30 +307,30 @@ func TestValidateRestartConsumerGenesisState(t *testing.T) { cs := ibctmtypes.NewClientState(chainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, height, commitmenttypes.GetSDKSpecs(), upgradePath) consensusState := ibctmtypes.NewConsensusState(time.Now(), commitmenttypes.NewMerkleRoot([]byte("apphash")), valHash) - params := types.DefaultParams() + params := ccv.DefaultParams() params.Enabled = true cases := []struct { name string - gs *types.ConsumerGenesisState + gs *types.GenesisState expError bool }{ { "valid restart consumer genesis state: empty maturing packets", - types.NewRestartConsumerGenesisState("ccvclient", "ccvchannel", nil, valUpdates, heightToValsetUpdateID, - types.ConsumerPacketDataList{List: []types.ConsumerPacketData{matConsumerPacket, slashConsumerPacket}}, + types.NewRestartGenesisState("ccvclient", "ccvchannel", nil, valUpdates, heightToValsetUpdateID, + types.ConsumerPacketDataList{List: []ccv.ConsumerPacketData{matConsumerPacket, slashConsumerPacket}}, nil, types.LastTransmissionBlockHeight{Height: 100}, params), false, }, { "valid restart consumer genesis state: handshake in progress ", - types.NewRestartConsumerGenesisState("ccvclient", "", nil, valUpdates, heightToValsetUpdateID, - types.ConsumerPacketDataList{List: []types.ConsumerPacketData{slashConsumerPacket}}, nil, types.LastTransmissionBlockHeight{}, params), + types.NewRestartGenesisState("ccvclient", "", nil, valUpdates, heightToValsetUpdateID, + types.ConsumerPacketDataList{List: []ccv.ConsumerPacketData{slashConsumerPacket}}, nil, types.LastTransmissionBlockHeight{}, params), false, }, { "valid restart consumer genesis state: maturing packets", - types.NewRestartConsumerGenesisState("ccvclient", "ccvchannel", []types.MaturingVSCPacket{ + types.NewRestartGenesisState("ccvclient", "ccvchannel", []types.MaturingVSCPacket{ {VscId: 1, MaturityTime: time.Now().UTC()}, {VscId: 3, MaturityTime: time.Now().UTC()}, {VscId: 5, MaturityTime: time.Now().UTC()}, @@ -328,34 +341,36 @@ func TestValidateRestartConsumerGenesisState(t *testing.T) { }, { "invalid restart consumer genesis state: provider id is empty", - types.NewRestartConsumerGenesisState("", "ccvchannel", nil, valUpdates, heightToValsetUpdateID, types.ConsumerPacketDataList{}, nil, types.LastTransmissionBlockHeight{}, params), + types.NewRestartGenesisState("", "ccvchannel", nil, valUpdates, heightToValsetUpdateID, types.ConsumerPacketDataList{}, nil, types.LastTransmissionBlockHeight{}, params), true, }, { "invalid restart consumer genesis state: maturing packet vscId is invalid", - types.NewRestartConsumerGenesisState("ccvclient", "ccvchannel", []types.MaturingVSCPacket{ + types.NewRestartGenesisState("ccvclient", "ccvchannel", []types.MaturingVSCPacket{ {VscId: 0, MaturityTime: time.Now().UTC()}, }, valUpdates, nil, types.ConsumerPacketDataList{}, nil, types.LastTransmissionBlockHeight{}, params), true, }, { "invalid restart consumer genesis state: maturing packet time is invalid", - types.NewRestartConsumerGenesisState("ccvclient", "ccvchannel", []types.MaturingVSCPacket{ + types.NewRestartGenesisState("ccvclient", "ccvchannel", []types.MaturingVSCPacket{ {VscId: 1, MaturityTime: time.Time{}}, }, valUpdates, nil, types.ConsumerPacketDataList{}, nil, types.LastTransmissionBlockHeight{}, params), true, }, { "invalid restart consumer genesis: client state defined", - &types.ConsumerGenesisState{ - Params: params, - ProviderClientId: "ccvclient", - ProviderChannelId: "ccvchannel", - NewChain: false, - ProviderClientState: cs, - ProviderConsensusState: nil, + &types.GenesisState{ + Params: params, + ProviderClientId: "ccvclient", + ProviderChannelId: "ccvchannel", + NewChain: false, + Provider: ccv.ProviderInfo{ + ClientState: cs, + ConsensusState: nil, + InitialValSet: valUpdates, + }, MaturingPackets: nil, - InitialValSet: valUpdates, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, @@ -366,15 +381,17 @@ func TestValidateRestartConsumerGenesisState(t *testing.T) { }, { "invalid restart consumer genesis: consensus state defined", - &types.ConsumerGenesisState{ - Params: params, - ProviderClientId: "ccvclient", - ProviderChannelId: "ccvchannel", - NewChain: false, - ProviderClientState: nil, - ProviderConsensusState: consensusState, + &types.GenesisState{ + Params: params, + ProviderClientId: "ccvclient", + ProviderChannelId: "ccvchannel", + NewChain: false, + Provider: ccv.ProviderInfo{ + ClientState: nil, + ConsensusState: consensusState, + InitialValSet: valUpdates, + }, MaturingPackets: nil, - InitialValSet: valUpdates, HeightToValsetUpdateId: nil, OutstandingDowntimeSlashing: nil, PendingConsumerPackets: types.ConsumerPacketDataList{}, @@ -385,42 +402,42 @@ func TestValidateRestartConsumerGenesisState(t *testing.T) { }, { "invalid restart consumer genesis state: nil initial validator set", - types.NewRestartConsumerGenesisState("ccvclient", "ccvchannel", nil, nil, nil, types.ConsumerPacketDataList{}, nil, types.LastTransmissionBlockHeight{}, params), + types.NewRestartGenesisState("ccvclient", "ccvchannel", nil, nil, nil, types.ConsumerPacketDataList{}, nil, types.LastTransmissionBlockHeight{}, params), true, }, { "invalid restart consumer genesis state: nil height to validator set id mapping", - types.NewRestartConsumerGenesisState("ccvclient", "", + types.NewRestartGenesisState("ccvclient", "", []types.MaturingVSCPacket{{VscId: 1, MaturityTime: time.Time{}}}, valUpdates, nil, types.ConsumerPacketDataList{}, nil, types.LastTransmissionBlockHeight{}, params), true, }, { "invalid restart consumer genesis state: maturing packet defined when handshake is still in progress", - types.NewRestartConsumerGenesisState("ccvclient", "", + types.NewRestartGenesisState("ccvclient", "", []types.MaturingVSCPacket{{VscId: 1, MaturityTime: time.Time{}}}, valUpdates, heightToValsetUpdateID, types.ConsumerPacketDataList{}, nil, types.LastTransmissionBlockHeight{}, params), true, }, { "invalid restart consumer genesis state: outstanding downtime defined when handshake is still in progress", - types.NewRestartConsumerGenesisState("ccvclient", "", + types.NewRestartGenesisState("ccvclient", "", nil, valUpdates, heightToValsetUpdateID, types.ConsumerPacketDataList{}, []types.OutstandingDowntime{{ValidatorConsensusAddress: "cosmosvalconsxxx"}}, types.LastTransmissionBlockHeight{}, params), true, }, { "invalid restart consumer genesis state: last transmission block height defined when handshake is still in progress", - types.NewRestartConsumerGenesisState("ccvclient", "", + types.NewRestartGenesisState("ccvclient", "", nil, valUpdates, heightToValsetUpdateID, types.ConsumerPacketDataList{}, nil, types.LastTransmissionBlockHeight{Height: int64(1)}, params), true, }, { "invalid restart consumer genesis state: pending maturing packets defined when handshake is still in progress", - types.NewRestartConsumerGenesisState("ccvclient", "", + types.NewRestartGenesisState("ccvclient", "", nil, valUpdates, heightToValsetUpdateID, types.ConsumerPacketDataList{ - List: []types.ConsumerPacketData{ + List: []ccv.ConsumerPacketData{ { - Type: types.VscMaturedPacket, - Data: &types.ConsumerPacketData_VscMaturedPacketData{VscMaturedPacketData: types.NewVSCMaturedPacketData(1)}, + Type: ccv.VscMaturedPacket, + Data: &ccv.ConsumerPacketData_VscMaturedPacketData{VscMaturedPacketData: ccv.NewVSCMaturedPacketData(1)}, }, }, }, nil, types.LastTransmissionBlockHeight{Height: int64(1)}, params), @@ -428,20 +445,21 @@ func TestValidateRestartConsumerGenesisState(t *testing.T) { }, { "invalid restart consumer genesis state: invalid params", - types.NewRestartConsumerGenesisState("ccvclient", "ccvchannel", nil, valUpdates, nil, types.ConsumerPacketDataList{}, nil, types.LastTransmissionBlockHeight{}, - types.NewParams( + types.NewRestartGenesisState("ccvclient", "ccvchannel", nil, valUpdates, nil, types.ConsumerPacketDataList{}, nil, types.LastTransmissionBlockHeight{}, + ccv.NewParams( true, - types.DefaultBlocksPerDistributionTransmission, + ccv.DefaultBlocksPerDistributionTransmission, "", "", 0, // CCV timeout period cannot be 0 - types.DefaultTransferTimeoutPeriod, - types.DefaultConsumerRedistributeFrac, - types.DefaultHistoricalEntries, - types.DefaultConsumerUnbondingPeriod, - types.DefaultSoftOptOutThreshold, + ccv.DefaultTransferTimeoutPeriod, + ccv.DefaultConsumerRedistributeFrac, + ccv.DefaultHistoricalEntries, + ccv.DefaultConsumerUnbondingPeriod, + ccv.DefaultSoftOptOutThreshold, []string{}, []string{}, + ccv.DefaultRetryDelayPeriod, )), true, }, diff --git a/x/ccv/consumer/types/params_test.go b/x/ccv/consumer/types/params_test.go index e401ba3e47..d0a6b49c25 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, "0.05", []string{"untrn"}, []string{"uatom"}), 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, "0.05", []string{"untrn"}, []string{"uatom"}), 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, "0.05", []string{"untrn"}, []string{"uatom"}), 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, "0.05", []string{"untrn"}, []string{"uatom"}), 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, "0.05", []string{"untrn"}, []string{"uatom"}), 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, "0.05", []string{"untrn"}, []string{"uatom"}), 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, "0.05", []string{"untrn"}, []string{"uatom"}), 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, "0.05", []string{"untrn"}, []string{"uatom"}), 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, "0.05", []string{"untrn"}, []string{"uatom"}), 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, "0.05", []string{"untrn"}, []string{"uatom"}), 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{}), 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 soft opt out threshold", - ccvtypes.NewParams(true, 5, "", "", 5, 1005, "0.5", 1000, 24*21*time.Hour, "0.5", []string{"u"}, []string{}), false, + 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{}), 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, "0.05", []string{}, []string{"a"}), 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, "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, "0.05", []string{}, []string{}, 0), false, }, } diff --git a/x/ccv/consumer/types/query.pb.go b/x/ccv/consumer/types/query.pb.go index 45e3586424..e1dd01af4b 100644 --- a/x/ccv/consumer/types/query.pb.go +++ b/x/ccv/consumer/types/query.pb.go @@ -384,6 +384,94 @@ func (m *QueryProviderInfoResponse) GetProvider() ChainInfo { return ChainInfo{} } +type QueryThrottleStateRequest struct { +} + +func (m *QueryThrottleStateRequest) Reset() { *m = QueryThrottleStateRequest{} } +func (m *QueryThrottleStateRequest) String() string { return proto.CompactTextString(m) } +func (*QueryThrottleStateRequest) ProtoMessage() {} +func (*QueryThrottleStateRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_f627751d3cc10225, []int{7} +} +func (m *QueryThrottleStateRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryThrottleStateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryThrottleStateRequest.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 *QueryThrottleStateRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryThrottleStateRequest.Merge(m, src) +} +func (m *QueryThrottleStateRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryThrottleStateRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryThrottleStateRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryThrottleStateRequest proto.InternalMessageInfo + +type QueryThrottleStateResponse struct { + SlashRecord *SlashRecord `protobuf:"bytes,1,opt,name=slash_record,json=slashRecord,proto3" json:"slash_record,omitempty"` + PacketDataQueue []types.ConsumerPacketData `protobuf:"bytes,2,rep,name=packet_data_queue,json=packetDataQueue,proto3" json:"packet_data_queue"` +} + +func (m *QueryThrottleStateResponse) Reset() { *m = QueryThrottleStateResponse{} } +func (m *QueryThrottleStateResponse) String() string { return proto.CompactTextString(m) } +func (*QueryThrottleStateResponse) ProtoMessage() {} +func (*QueryThrottleStateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f627751d3cc10225, []int{8} +} +func (m *QueryThrottleStateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryThrottleStateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryThrottleStateResponse.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 *QueryThrottleStateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryThrottleStateResponse.Merge(m, src) +} +func (m *QueryThrottleStateResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryThrottleStateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryThrottleStateResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryThrottleStateResponse proto.InternalMessageInfo + +func (m *QueryThrottleStateResponse) GetSlashRecord() *SlashRecord { + if m != nil { + return m.SlashRecord + } + return nil +} + +func (m *QueryThrottleStateResponse) GetPacketDataQueue() []types.ConsumerPacketData { + if m != nil { + return m.PacketDataQueue + } + return nil +} + type ChainInfo struct { ChainID string `protobuf:"bytes,1,opt,name=chainID,proto3" json:"chainID,omitempty"` ClientID string `protobuf:"bytes,2,opt,name=clientID,proto3" json:"clientID,omitempty"` @@ -395,7 +483,7 @@ func (m *ChainInfo) Reset() { *m = ChainInfo{} } func (m *ChainInfo) String() string { return proto.CompactTextString(m) } func (*ChainInfo) ProtoMessage() {} func (*ChainInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_f627751d3cc10225, []int{7} + return fileDescriptor_f627751d3cc10225, []int{9} } func (m *ChainInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -460,6 +548,8 @@ func init() { proto.RegisterType((*QueryParamsResponse)(nil), "interchain_security.ccv.consumer.v1.QueryParamsResponse") proto.RegisterType((*QueryProviderInfoRequest)(nil), "interchain_security.ccv.consumer.v1.QueryProviderInfoRequest") proto.RegisterType((*QueryProviderInfoResponse)(nil), "interchain_security.ccv.consumer.v1.QueryProviderInfoResponse") + proto.RegisterType((*QueryThrottleStateRequest)(nil), "interchain_security.ccv.consumer.v1.QueryThrottleStateRequest") + proto.RegisterType((*QueryThrottleStateResponse)(nil), "interchain_security.ccv.consumer.v1.QueryThrottleStateResponse") proto.RegisterType((*ChainInfo)(nil), "interchain_security.ccv.consumer.v1.ChainInfo") } @@ -468,51 +558,59 @@ func init() { } var fileDescriptor_f627751d3cc10225 = []byte{ - // 689 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x4f, 0x6b, 0x13, 0x41, - 0x14, 0xcf, 0xa6, 0x4d, 0xdb, 0x4c, 0xf5, 0xe0, 0x18, 0x61, 0x5d, 0xcb, 0x5a, 0x56, 0xc1, 0x58, - 0xc8, 0x6e, 0xd3, 0x1e, 0xaa, 0x87, 0xaa, 0xd8, 0x58, 0x1a, 0x50, 0xa9, 0x8b, 0x20, 0x78, 0x09, - 0xd3, 0xc9, 0x34, 0x59, 0x48, 0x66, 0xd2, 0x99, 0xd9, 0xa5, 0xbd, 0x89, 0xe2, 0x55, 0x04, 0xbf, - 0x89, 0x5f, 0xc0, 0x6b, 0xc1, 0x4b, 0xc1, 0x8b, 0x27, 0x91, 0xd6, 0x0f, 0xe1, 0x51, 0x76, 0x76, - 0x36, 0xdd, 0xd0, 0x3f, 0xd9, 0xaa, 0xb7, 0x99, 0xf7, 0x7b, 0xef, 0xf7, 0x7e, 0xef, 0xcd, 0x7b, - 0xbb, 0xc0, 0x0b, 0xa8, 0x24, 0x1c, 0x77, 0x51, 0x40, 0x5b, 0x82, 0xe0, 0x90, 0x07, 0x72, 0xcf, - 0xc3, 0x38, 0xf2, 0x30, 0xa3, 0x22, 0xec, 0x13, 0xee, 0x45, 0x75, 0x6f, 0x27, 0x24, 0x7c, 0xcf, - 0x1d, 0x70, 0x26, 0x19, 0xbc, 0x75, 0x4a, 0x80, 0x8b, 0x71, 0xe4, 0xa6, 0x01, 0x6e, 0x54, 0xb7, - 0x16, 0xcf, 0x62, 0x8d, 0xea, 0x9e, 0xe8, 0x22, 0x4e, 0xda, 0xad, 0xa1, 0xbb, 0xa2, 0xb5, 0x2a, - 0x1d, 0xd6, 0x61, 0xea, 0xe8, 0xc5, 0x27, 0x6d, 0x9d, 0xeb, 0x30, 0xd6, 0xe9, 0x11, 0x0f, 0x0d, - 0x02, 0x0f, 0x51, 0xca, 0x24, 0x92, 0x01, 0xa3, 0x42, 0xa3, 0x4b, 0x79, 0xb4, 0x8f, 0xe6, 0x71, - 0x3e, 0x14, 0xc1, 0x8d, 0xe7, 0x64, 0x57, 0xae, 0x13, 0xd2, 0x08, 0x84, 0xe4, 0xc1, 0x56, 0x18, - 0x53, 0x3e, 0x11, 0x32, 0xe8, 0x23, 0x49, 0xe0, 0x6d, 0x70, 0x19, 0x87, 0x9c, 0x13, 0x2a, 0x37, - 0x48, 0xd0, 0xe9, 0x4a, 0xd3, 0x98, 0x37, 0xaa, 0x13, 0xfe, 0xa8, 0x11, 0xda, 0x00, 0xf4, 0x90, - 0x48, 0x5d, 0x8a, 0xca, 0x25, 0x63, 0x89, 0x71, 0x4a, 0x76, 0x53, 0x7c, 0x22, 0xc1, 0x8f, 0x2d, - 0x70, 0x19, 0x5c, 0x6b, 0x67, 0xb2, 0xb7, 0xb6, 0x39, 0xc2, 0xf1, 0xc1, 0x9c, 0x9c, 0x37, 0xaa, - 0x65, 0xbf, 0x92, 0x05, 0xd7, 0x35, 0x06, 0x2b, 0xa0, 0x24, 0x99, 0x44, 0x3d, 0xb3, 0xa4, 0x9c, - 0x92, 0x4b, 0x9c, 0x4a, 0xb2, 0x4d, 0xce, 0xa2, 0xa0, 0x4d, 0xb8, 0x39, 0xa5, 0xa0, 0x8c, 0x25, - 0xc1, 0xd7, 0x74, 0x13, 0xcc, 0xe9, 0x14, 0x4f, 0x2d, 0xce, 0x5d, 0x70, 0xe7, 0x45, 0xfc, 0xbc, - 0xe7, 0x34, 0xc5, 0x27, 0x3b, 0x21, 0x11, 0xd2, 0x79, 0x63, 0x80, 0xea, 0x78, 0x5f, 0x31, 0x60, - 0x54, 0x10, 0xf8, 0x12, 0x4c, 0xb6, 0x91, 0x44, 0xaa, 0x7f, 0xb3, 0x4b, 0x8f, 0xdc, 0x1c, 0x63, - 0xe3, 0x9e, 0xc7, 0xab, 0xd8, 0x9c, 0x0a, 0x80, 0x4a, 0xc1, 0x26, 0xe2, 0xa8, 0x2f, 0x52, 0x61, - 0x2d, 0x70, 0x75, 0xc4, 0xaa, 0x25, 0x6c, 0x80, 0xa9, 0x81, 0xb2, 0x68, 0x11, 0x0b, 0x67, 0x8a, - 0x88, 0xea, 0x6e, 0xda, 0x90, 0x84, 0xe3, 0xf1, 0xe4, 0xfe, 0x8f, 0x9b, 0x05, 0x5f, 0xc7, 0x3b, - 0x16, 0x30, 0x93, 0x04, 0xba, 0xab, 0x4d, 0xba, 0xcd, 0xd2, 0xe4, 0x5f, 0x0c, 0x70, 0xfd, 0x14, - 0x50, 0x6b, 0xd8, 0x04, 0x33, 0x69, 0x85, 0x5a, 0x85, 0x9b, 0xab, 0x15, 0x6b, 0x31, 0x1c, 0x33, - 0x69, 0x25, 0x43, 0x96, 0x98, 0x71, 0x90, 0x3e, 0x77, 0xf1, 0x5f, 0x18, 0x53, 0x16, 0xe7, 0x9d, - 0x01, 0xca, 0x43, 0x14, 0x9a, 0x60, 0x5a, 0x31, 0x35, 0x1b, 0x4a, 0x70, 0xd9, 0x4f, 0xaf, 0xd0, - 0x02, 0x33, 0xb8, 0x17, 0x10, 0x2a, 0x9b, 0x0d, 0x95, 0xb9, 0xec, 0x0f, 0xef, 0xd0, 0x01, 0x97, - 0x30, 0xa3, 0x94, 0xa8, 0x51, 0x6d, 0x36, 0xd4, 0xcc, 0x97, 0xfd, 0x11, 0x1b, 0x9c, 0x03, 0x65, - 0xdc, 0x45, 0x94, 0x92, 0x5e, 0xb3, 0xa1, 0x27, 0xfd, 0xd8, 0xb0, 0xf4, 0xbe, 0x04, 0x4a, 0xaa, - 0x8f, 0xf0, 0xb7, 0xa1, 0xdb, 0x7d, 0xca, 0x3c, 0xc0, 0xa7, 0xb9, 0x8a, 0xcd, 0x39, 0xd2, 0xd6, - 0xb3, 0xff, 0xc4, 0x96, 0xbc, 0xb6, 0xf3, 0xf0, 0xed, 0xb7, 0x5f, 0x9f, 0x8a, 0xf7, 0xe1, 0xca, - 0xf8, 0xcf, 0x6a, 0xfc, 0x35, 0xa8, 0x6d, 0x13, 0x52, 0xcb, 0xee, 0x3a, 0xfc, 0x6c, 0x80, 0xd9, - 0xcc, 0x28, 0xc3, 0x95, 0xfc, 0xfa, 0x46, 0x56, 0xc2, 0xba, 0x77, 0xf1, 0x40, 0x5d, 0xc3, 0xa2, - 0xaa, 0x61, 0x01, 0x56, 0xc7, 0xd7, 0x90, 0x6c, 0x07, 0xfc, 0x6a, 0x80, 0x2b, 0x27, 0x36, 0x00, - 0xae, 0x5e, 0x40, 0xc1, 0xc9, 0xb5, 0xb2, 0x1e, 0xfc, 0x6d, 0xb8, 0x2e, 0x63, 0x45, 0x95, 0x51, - 0x87, 0x5e, 0x8e, 0x32, 0x74, 0x7c, 0x2d, 0x88, 0xb7, 0xe3, 0xd5, 0xfe, 0xa1, 0x6d, 0x1c, 0x1c, - 0xda, 0xc6, 0xcf, 0x43, 0xdb, 0xf8, 0x78, 0x64, 0x17, 0x0e, 0x8e, 0xec, 0xc2, 0xf7, 0x23, 0xbb, - 0xf0, 0x7a, 0xb5, 0x13, 0xc8, 0x6e, 0xb8, 0xe5, 0x62, 0xd6, 0xf7, 0x30, 0x13, 0x7d, 0x26, 0x32, - 0xdc, 0xb5, 0x21, 0x77, 0xb4, 0xec, 0xed, 0x8e, 0x26, 0x90, 0x7b, 0x03, 0x22, 0xb6, 0xa6, 0xd4, - 0x1f, 0x68, 0xf9, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x91, 0xe8, 0xb3, 0x96, 0x73, 0x07, 0x00, - 0x00, + // 825 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, 0xf4, 0xd0, 0xe5, 0xb0, 0x2c, 0xda, 0x86, 0xaa, 0x91, 0x00, 0xb5, 0x6e, + 0x25, 0x04, 0x17, 0x33, 0x9d, 0x4c, 0x13, 0x8b, 0xc4, 0xe3, 0xce, 0x8c, 0x4d, 0x7b, 0x43, 0x70, + 0x47, 0x48, 0x7c, 0x13, 0xbe, 0x00, 0xd7, 0x4a, 0x1c, 0xa8, 0xc4, 0x01, 0xb8, 0x20, 0xd4, 0xf2, + 0x21, 0x38, 0xa2, 0x19, 0x8f, 0x53, 0xa7, 0x4d, 0x13, 0xb7, 0xec, 0xcd, 0xf3, 0xfe, 0xfc, 0xde, + 0xef, 0xf7, 0x66, 0xde, 0x4b, 0x80, 0x1b, 0x84, 0x82, 0x30, 0x3c, 0x44, 0x41, 0xe8, 0x73, 0x82, + 0x63, 0x16, 0x88, 0x13, 0x17, 0xe3, 0xc4, 0xc5, 0x34, 0xe4, 0xf1, 0x98, 0x30, 0x37, 0x69, 0xbb, + 0x47, 0x31, 0x61, 0x27, 0x4e, 0xc4, 0xa8, 0xa0, 0xf0, 0xad, 0x19, 0x09, 0x0e, 0xc6, 0x89, 0x93, + 0x25, 0x38, 0x49, 0xdb, 0x6a, 0xdd, 0x84, 0x9a, 0xb4, 0x5d, 0x3e, 0x44, 0x8c, 0xf4, 0xfd, 0x49, + 0xb8, 0x82, 0xb5, 0x6a, 0x03, 0x3a, 0xa0, 0xea, 0xd3, 0x95, 0x5f, 0xda, 0xfa, 0x78, 0x40, 0xe9, + 0x60, 0x44, 0x5c, 0x14, 0x05, 0x2e, 0x0a, 0x43, 0x2a, 0x90, 0x08, 0x68, 0xc8, 0xb5, 0xb7, 0x53, + 0x84, 0xfb, 0x95, 0x3a, 0xef, 0xcc, 0x61, 0xf6, 0x75, 0xc0, 0x48, 0x1a, 0x66, 0x7f, 0x5f, 0x06, + 0x8f, 0x3e, 0x25, 0xc7, 0x62, 0x8b, 0x90, 0x6e, 0xc0, 0x05, 0x0b, 0x0e, 0x62, 0x59, 0xf9, 0x23, + 0x2e, 0x82, 0x31, 0x12, 0x04, 0xbe, 0x0d, 0x5e, 0xc1, 0x31, 0x63, 0x24, 0x14, 0xdb, 0x24, 0x18, + 0x0c, 0x85, 0x69, 0xac, 0x19, 0x8d, 0x25, 0x6f, 0xda, 0x08, 0xeb, 0x00, 0x8c, 0x10, 0xcf, 0x42, + 0xca, 0x2a, 0x24, 0x67, 0x91, 0xfe, 0x90, 0x1c, 0x67, 0xfe, 0xa5, 0xd4, 0x7f, 0x69, 0x81, 0xeb, + 0xe0, 0xf5, 0x7e, 0xae, 0xba, 0x7f, 0xc8, 0x10, 0x96, 0x1f, 0xe6, 0xf2, 0x9a, 0xd1, 0xa8, 0x7a, + 0xb5, 0xbc, 0x73, 0x4b, 0xfb, 0x60, 0x0d, 0xac, 0x08, 0x2a, 0xd0, 0xc8, 0x5c, 0x51, 0x41, 0xe9, + 0x41, 0x96, 0x12, 0x74, 0x87, 0xd1, 0x24, 0xe8, 0x13, 0x66, 0x56, 0x94, 0x2b, 0x67, 0x49, 0xfd, + 0x9b, 0xba, 0x57, 0xe6, 0xbd, 0xcc, 0x9f, 0x59, 0xec, 0xf7, 0xc0, 0xbb, 0xbb, 0xf2, 0x15, 0xcc, + 0x69, 0x8a, 0x47, 0x8e, 0x62, 0xc2, 0x85, 0xfd, 0x8d, 0x01, 0x1a, 0x8b, 0x63, 0x79, 0x44, 0x43, + 0x4e, 0xe0, 0x3e, 0x58, 0xee, 0x23, 0x81, 0x54, 0xff, 0x56, 0x3b, 0x1f, 0x3a, 0x05, 0x5e, 0x97, + 0x33, 0x0f, 0x57, 0xa1, 0xd9, 0x35, 0x00, 0x15, 0x83, 0x1d, 0xc4, 0xd0, 0x98, 0x67, 0xc4, 0x7c, + 0xf0, 0xda, 0x94, 0x55, 0x53, 0xd8, 0x06, 0x95, 0x48, 0x59, 0x34, 0x89, 0x27, 0x37, 0x92, 0x48, + 0xda, 0x4e, 0xd6, 0x90, 0x14, 0xe3, 0xc5, 0xf2, 0xe9, 0x5f, 0x6f, 0x96, 0x3c, 0x9d, 0x6f, 0x5b, + 0xc0, 0x4c, 0x0b, 0xe8, 0xae, 0xf6, 0xc2, 0x43, 0x9a, 0x15, 0xff, 0xd9, 0x00, 0x6f, 0xcc, 0x70, + 0x6a, 0x0e, 0x3b, 0xe0, 0x7e, 0xa6, 0x50, 0xb3, 0x70, 0x0a, 0xb5, 0x62, 0x53, 0xba, 0x25, 0x92, + 0x66, 0x32, 0x41, 0x91, 0x88, 0x51, 0x76, 0xdd, 0xe5, 0xff, 0x83, 0x98, 0xa1, 0xd8, 0x8f, 0xb4, + 0x80, 0xfd, 0x21, 0xa3, 0x42, 0x8c, 0xc8, 0x9e, 0xc8, 0x5d, 0xfa, 0x9f, 0x06, 0xb0, 0x66, 0x79, + 0xb5, 0xbe, 0xcf, 0xc1, 0x03, 0x3e, 0x42, 0x7c, 0xe8, 0x33, 0x82, 0x29, 0xeb, 0x6b, 0x8d, 0xad, + 0x42, 0x8c, 0xf6, 0x64, 0xa2, 0xa7, 0xf2, 0x14, 0x27, 0xc3, 0x5b, 0xe5, 0x97, 0x26, 0xf8, 0x25, + 0x78, 0x18, 0x21, 0xfc, 0x15, 0x11, 0xbe, 0xbc, 0x7a, 0xff, 0x28, 0x26, 0x31, 0x31, 0xcb, 0x6b, + 0x4b, 0x73, 0x15, 0x4f, 0xdd, 0xa4, 0x4c, 0xee, 0x22, 0x81, 0xb4, 0xe2, 0x57, 0xa3, 0x89, 0x65, + 0x57, 0x82, 0xd9, 0xdf, 0x19, 0xa0, 0x3a, 0x69, 0x0b, 0x34, 0xc1, 0x3d, 0x05, 0xd8, 0xeb, 0x2a, + 0x15, 0x55, 0x2f, 0x3b, 0x42, 0x0b, 0xdc, 0xc7, 0xa3, 0x80, 0x84, 0xa2, 0xd7, 0x55, 0x2d, 0xaf, + 0x7a, 0x93, 0x33, 0xb4, 0xc1, 0x03, 0x4c, 0xc3, 0x90, 0xa8, 0x19, 0xed, 0x75, 0xd5, 0xb0, 0x57, + 0xbd, 0x29, 0x1b, 0x7c, 0x0c, 0xaa, 0x78, 0x88, 0xc2, 0x90, 0x8c, 0x7a, 0x5d, 0x3d, 0xe2, 0x97, + 0x86, 0xce, 0xef, 0x15, 0xb0, 0xa2, 0x3a, 0x0c, 0xff, 0x35, 0xf4, 0x3b, 0x9b, 0x31, 0x08, 0xf0, + 0xe3, 0x42, 0x3d, 0x2d, 0x38, 0xcb, 0xd6, 0x27, 0x2f, 0x09, 0x2d, 0x7d, 0x06, 0xf6, 0xf3, 0x6f, + 0x7f, 0xfb, 0xe7, 0xc7, 0xf2, 0xfb, 0x70, 0x63, 0xf1, 0xcf, 0x8e, 0x5c, 0x83, 0xcd, 0x43, 0x42, + 0x9a, 0xf9, 0x25, 0x07, 0x7f, 0x32, 0xc0, 0x6a, 0x6e, 0x86, 0xe1, 0x46, 0x71, 0x7e, 0x53, 0xbb, + 0xc0, 0x7a, 0x7a, 0xfb, 0x44, 0xad, 0xa1, 0xa5, 0x34, 0x3c, 0x81, 0x8d, 0xc5, 0x1a, 0xd2, 0xb5, + 0x00, 0x7f, 0x31, 0xc0, 0xc3, 0x6b, 0xa3, 0x0f, 0x9f, 0xdd, 0x82, 0xc1, 0xf5, 0x7d, 0x62, 0x7d, + 0x70, 0xd7, 0x74, 0x2d, 0x63, 0x43, 0xc9, 0x68, 0x43, 0xb7, 0x80, 0x0c, 0x9d, 0xdf, 0x0c, 0x24, + 0xef, 0x5f, 0x0d, 0xbd, 0x5c, 0xa7, 0x26, 0x1d, 0xde, 0x82, 0xcf, 0xac, 0x05, 0x62, 0x3d, 0xbf, + 0x73, 0xbe, 0x16, 0xf4, 0x54, 0x09, 0xea, 0xc0, 0xd6, 0x62, 0x41, 0x42, 0x03, 0xf8, 0x5c, 0x22, + 0xbc, 0xf8, 0xec, 0xf4, 0xbc, 0x6e, 0x9c, 0x9d, 0xd7, 0x8d, 0xbf, 0xcf, 0xeb, 0xc6, 0x0f, 0x17, + 0xf5, 0xd2, 0xd9, 0x45, 0xbd, 0xf4, 0xc7, 0x45, 0xbd, 0xf4, 0xc5, 0xb3, 0x41, 0x20, 0x86, 0xf1, + 0x81, 0x83, 0xe9, 0xd8, 0xc5, 0x94, 0x8f, 0x29, 0xcf, 0x81, 0x37, 0x27, 0xe0, 0xc9, 0xba, 0x7b, + 0x7c, 0xa5, 0xc2, 0x49, 0x44, 0xf8, 0x41, 0x45, 0xfd, 0x99, 0x58, 0xff, 0x2f, 0x00, 0x00, 0xff, + 0xff, 0x0e, 0x14, 0x5a, 0xa9, 0x65, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -533,6 +631,8 @@ type QueryClient interface { // QueryParams queries the ccv/consumer module parameters. QueryParams(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) QueryProviderInfo(ctx context.Context, in *QueryProviderInfoRequest, opts ...grpc.CallOption) (*QueryProviderInfoResponse, error) + // QueryThrottleState returns on-chain state relevant to throttled consumer packets + QueryThrottleState(ctx context.Context, in *QueryThrottleStateRequest, opts ...grpc.CallOption) (*QueryThrottleStateResponse, error) } type queryClient struct { @@ -570,6 +670,15 @@ func (c *queryClient) QueryProviderInfo(ctx context.Context, in *QueryProviderIn return out, nil } +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.consumer.v1.Query/QueryThrottleState", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // ConsumerGenesis queries the genesis state needed to start a consumer chain @@ -578,6 +687,8 @@ type QueryServer interface { // QueryParams queries the ccv/consumer module parameters. QueryParams(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) QueryProviderInfo(context.Context, *QueryProviderInfoRequest) (*QueryProviderInfoResponse, error) + // QueryThrottleState returns on-chain state relevant to throttled consumer packets + QueryThrottleState(context.Context, *QueryThrottleStateRequest) (*QueryThrottleStateResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -593,6 +704,9 @@ func (*UnimplementedQueryServer) QueryParams(ctx context.Context, req *QueryPara func (*UnimplementedQueryServer) QueryProviderInfo(ctx context.Context, req *QueryProviderInfoRequest) (*QueryProviderInfoResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryProviderInfo not implemented") } +func (*UnimplementedQueryServer) QueryThrottleState(ctx context.Context, req *QueryThrottleStateRequest) (*QueryThrottleStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryThrottleState not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -652,6 +766,24 @@ func _Query_QueryProviderInfo_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +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.consumer.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) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "interchain_security.ccv.consumer.v1.Query", HandlerType: (*QueryServer)(nil), @@ -668,6 +800,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "QueryProviderInfo", Handler: _Query_QueryProviderInfo_Handler, }, + { + MethodName: "QueryThrottleState", + Handler: _Query_QueryThrottleState_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "interchain_security/ccv/consumer/v1/query.proto", @@ -919,6 +1055,78 @@ func (m *QueryProviderInfoResponse) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } +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 + if len(m.PacketDataQueue) > 0 { + for iNdEx := len(m.PacketDataQueue) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.PacketDataQueue[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.SlashRecord != nil { + { + size, err := m.SlashRecord.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 *ChainInfo) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1079,6 +1287,34 @@ func (m *QueryProviderInfoResponse) Size() (n int) { 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.SlashRecord != nil { + l = m.SlashRecord.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if len(m.PacketDataQueue) > 0 { + for _, e := range m.PacketDataQueue { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + func (m *ChainInfo) Size() (n int) { if m == nil { return 0 @@ -1780,6 +2016,176 @@ func (m *QueryProviderInfoResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryThrottleStateRequest) 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: QueryThrottleStateRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryThrottleStateRequest: 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 *QueryThrottleStateResponse) 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: QueryThrottleStateResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryThrottleStateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SlashRecord", 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.SlashRecord == nil { + m.SlashRecord = &SlashRecord{} + } + if err := m.SlashRecord.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PacketDataQueue", 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.PacketDataQueue = append(m.PacketDataQueue, types.ConsumerPacketData{}) + if err := m.PacketDataQueue[len(m.PacketDataQueue)-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 *ChainInfo) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/ccv/consumer/types/query.pb.gw.go b/x/ccv/consumer/types/query.pb.gw.go index 1151ab0b60..46ad461324 100644 --- a/x/ccv/consumer/types/query.pb.gw.go +++ b/x/ccv/consumer/types/query.pb.gw.go @@ -87,6 +87,24 @@ func local_request_Query_QueryProviderInfo_0(ctx context.Context, marshaler runt } +func request_Query_QueryThrottleState_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryThrottleStateRequest + var metadata runtime.ServerMetadata + + msg, err := client.QueryThrottleState(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_QueryThrottleState_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryThrottleStateRequest + var metadata runtime.ServerMetadata + + msg, err := server.QueryThrottleState(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. @@ -162,6 +180,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_QueryThrottleState_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_QueryThrottleState_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_QueryThrottleState_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -263,6 +304,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_QueryThrottleState_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_QueryThrottleState_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_QueryThrottleState_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -272,6 +333,8 @@ var ( pattern_Query_QueryParams_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"interchain_security", "ccv", "consumer", "params"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_QueryProviderInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"interchain_security", "ccv", "consumer", "provider-info"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_QueryThrottleState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"interchain_security", "ccv", "consumer", "throttle_state"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -280,4 +343,6 @@ var ( forward_Query_QueryParams_0 = runtime.ForwardResponseMessage forward_Query_QueryProviderInfo_0 = runtime.ForwardResponseMessage + + forward_Query_QueryThrottleState_0 = runtime.ForwardResponseMessage ) diff --git a/x/ccv/provider/client/cli/query.go b/x/ccv/provider/client/cli/query.go index 1240e242f0..2b1d0e1dee 100644 --- a/x/ccv/provider/client/cli/query.go +++ b/x/ccv/provider/client/cli/query.go @@ -31,8 +31,8 @@ func NewQueryCmd() *cobra.Command { cmd.AddCommand(CmdConsumerValidatorKeyAssignment()) cmd.AddCommand(CmdProviderValidatorKey()) cmd.AddCommand(CmdThrottleState()) - cmd.AddCommand(CmdThrottledConsumerPacketData()) cmd.AddCommand(CmdRegisteredConsumerRewardDenoms()) + cmd.AddCommand(CmdProposedConsumerChains()) return cmd } @@ -93,6 +93,33 @@ func CmdConsumerChains() *cobra.Command { return cmd } +func CmdProposedConsumerChains() *cobra.Command { + cmd := &cobra.Command{ + Use: "list-proposed-consumer-chains", + Short: "Query chainIDs in consumer addition proposal before voting finishes", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + req := &types.QueryProposedChainIDsRequest{} + res, err := queryClient.QueryProposedConsumerChainIDs(cmd.Context(), req) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + func CmdConsumerStartProposals() *cobra.Command { cmd := &cobra.Command{ Use: "list-start-proposals", @@ -286,42 +313,6 @@ $ %s query provider throttle-state return cmd } -func CmdThrottledConsumerPacketData() *cobra.Command { - cmd := &cobra.Command{ - Use: "throttled-consumer-packet-data [chainid]", - Short: "Query pending VSCMatured and slash packet data for a consumer chainId", - Long: strings.TrimSpace( - fmt.Sprintf(`Returns the current pending VSCMatured and slash packet data instances for a consumer chainId. - Queue is ordered by ibc sequence number. -Example: -$ %s query provider throttled-consumer-packet-data foochain -`, - version.AppName, - ), - ), - Args: cobra.ExactArgs(1), - 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.QueryThrottledConsumerPacketDataRequest{ChainId: args[0]} - res, err := queryClient.QueryThrottledConsumerPacketData(cmd.Context(), req) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} - func CmdRegisteredConsumerRewardDenoms() *cobra.Command { cmd := &cobra.Command{ Use: "registered-consumer-reward-denoms", diff --git a/x/ccv/provider/client/cli/tx.go b/x/ccv/provider/client/cli/tx.go index 0d37ef52a9..78fbaaf9df 100644 --- a/x/ccv/provider/client/cli/tx.go +++ b/x/ccv/provider/client/cli/tx.go @@ -1,14 +1,21 @@ package cli import ( + "encoding/json" "fmt" + "os" + "strings" + ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" "github.com/spf13/cobra" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/version" + + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" ) @@ -24,6 +31,8 @@ func GetTxCmd() *cobra.Command { } cmd.AddCommand(NewAssignConsumerKeyCmd()) + cmd.AddCommand(NewSubmitConsumerMisbehaviourCmd()) + cmd.AddCommand(NewSubmitConsumerDoubleVotingCmd()) return cmd } @@ -65,3 +74,121 @@ func NewAssignConsumerKeyCmd() *cobra.Command { return cmd } + +func NewSubmitConsumerMisbehaviourCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "submit-consumer-misbehaviour [misbehaviour]", + Short: "submit an IBC misbehaviour for a consumer chain", + Long: strings.TrimSpace( + fmt.Sprintf(`Submit an IBC misbehaviour detected on a consumer chain. +An IBC misbehaviour contains two conflicting IBC client headers, which are used to form a light client attack evidence. +The misbehaviour type definition can be found in the IBC client messages, see ibc-go/proto/ibc/core/client/v1/tx.proto. + +Example: +%s tx provider submit-consumer-misbehaviour [path/to/misbehaviour.json] --from node0 --home ../node0 --chain-id $CID + `, version.AppName)), + 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) + + submitter := clientCtx.GetFromAddress() + var misbehaviour ibctmtypes.Misbehaviour + if err := clientCtx.Codec.UnmarshalInterfaceJSON([]byte(args[1]), &misbehaviour); err != nil { + return err + } + + msg, err := types.NewMsgSubmitConsumerMisbehaviour(submitter, &misbehaviour) + 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 NewSubmitConsumerDoubleVotingCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "submit-consumer-double-voting [evidence] [infraction_header]", + Short: "submit a double voting evidence for a consumer chain", + Long: strings.TrimSpace( + fmt.Sprintf(`Submit a Tendermint duplicate vote evidence detected on a consumer chain with + the IBC light client header for the infraction height. + The DuplicateVoteEvidence type definition can be found in the Tendermint messages, + see cometbft/proto/tendermint/types/evidence.proto and the IBC header + definition can be found in the IBC messages, see ibc-go/proto/ibc/lightclients/tendermint/v1/tendermint.proto. + +Example: +%s tx provider submit-consumer-double-voting [path/to/evidence.json] [path/to/infraction_header.json] --from node0 --home ../node0 --chain-id $CID +`, 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) + + submitter := clientCtx.GetFromAddress() + + ev := tmproto.DuplicateVoteEvidence{} + evidenceJson, err := os.ReadFile(args[0]) + if err != nil { + return err + } + + if err := json.Unmarshal(evidenceJson, &ev); err != nil { + return fmt.Errorf("duplicate vote evidence unmarshalling failed: %s", err) + } + + headerRaw, err := os.ReadFile(args[1]) + if err != nil { + return err + } + + header := ibctmtypes.Header{} + if err := types.ModuleCdc.UnmarshalJSON(headerRaw, &header); err != nil { + return fmt.Errorf("infraction IBC header unmarshalling failed: %s", err) + } + + msg, err := types.NewMsgSubmitConsumerDoubleVoting(submitter, &ev, &header) + 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 +} diff --git a/x/ccv/provider/client/proposal_handler.go b/x/ccv/provider/client/proposal_handler.go index 2b28c63466..bfd04af4c2 100644 --- a/x/ccv/provider/client/proposal_handler.go +++ b/x/ccv/provider/client/proposal_handler.go @@ -26,7 +26,6 @@ import ( var ( ConsumerAdditionProposalHandler = govclient.NewProposalHandler(SubmitConsumerAdditionPropTxCmd) ConsumerRemovalProposalHandler = govclient.NewProposalHandler(SubmitConsumerRemovalProposalTxCmd) - EquivocationProposalHandler = govclient.NewProposalHandler(SubmitEquivocationProposalTxCmd) ChangeRewardDenomsProposalHandler = govclient.NewProposalHandler(SubmitChangeRewardDenomsProposalTxCmd) ) @@ -167,69 +166,6 @@ Where proposal.json contains: } } -// SubmitEquivocationProposalTxCmd returns a CLI command handler for submitting -// a equivocation proposal via a transaction. -func SubmitEquivocationProposalTxCmd() *cobra.Command { - return &cobra.Command{ - Use: "equivocation [proposal-file]", - Args: cobra.ExactArgs(1), - Short: "Submit an equivocation proposal", - Long: fmt.Sprintf(`Submit an equivocation proposal along with an initial deposit. -The proposal details must be supplied via a JSON file. - -Example: -$ tx gov submit-legacy-proposal equivocation --from= - -Where proposal.json contains: -{ - "title": "Equivoque Foo validator", - "summary": "He double-signs on the Foobar consumer chain", - "equivocations": [ - { - "height": 10420042, - "time": "2023-01-27T15:59:50.121607-08:00", - "power": 10, - "consensus_address": "%s1s5afhd6gxevu37mkqcvvsj8qeylhn0rz46zdlq" - } - ], - "deposit": "10000stake" -} -`, sdk.GetConfig().GetBech32ConsensusAddrPrefix()), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - proposal, err := ParseEquivocationProposalJSON(args[0]) - if err != nil { - return err - } - - content := types.NewEquivocationProposal(proposal.Title, proposal.Summary, proposal.Equivocations) - - 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 { @@ -378,38 +314,6 @@ func ParseConsumerRemovalProposalJSON(proposalFile string) (ConsumerRemovalPropo return proposal, nil } -type EquivocationProposalJSON struct { - // evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" - Summary string `json:"summary"` - types.EquivocationProposal - - Deposit string `json:"deposit"` -} - -type EquivocationProposalReq struct { - Proposer sdk.AccAddress `json:"proposer"` - - // evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" - types.EquivocationProposal - - Deposit sdk.Coins `json:"deposit"` -} - -func ParseEquivocationProposalJSON(proposalFile string) (EquivocationProposalJSON, error) { - proposal := EquivocationProposalJSON{} - - 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 @@ -535,34 +439,4 @@ func postConsumerRemovalProposalHandlerFn(clientCtx client.Context) http.Handler tx.WriteGeneratedTxResponse(clientCtx, w, req.BaseReq, msg) } } - -func postEquivocationProposalHandlerFn(clientCtx client.Context) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - var req EquivocationProposalReq - if !rest.ReadRESTReq(w, r, clientCtx.LegacyAmino, &req) { - return - } - - req.BaseReq = req.BaseReq.Sanitize() - if !req.BaseReq.ValidateBasic(w) { - return - } - - content := types.NewEquivocationProposal(req.Title, req.Description, req.Equivocations) - - 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 067d896cda..69b18e9af1 100644 --- a/x/ccv/provider/handler.go +++ b/x/ccv/provider/handler.go @@ -20,6 +20,12 @@ func NewHandler(k *keeper.Keeper) sdk.Handler { case *types.MsgAssignConsumerKey: res, err := msgServer.AssignConsumerKey(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgSubmitConsumerMisbehaviour: + res, err := msgServer.SubmitConsumerMisbehaviour(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgSubmitConsumerDoubleVoting: + res, err := msgServer.SubmitConsumerDoubleVoting(sdk.WrapSDKContext(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 e4835cf14a..3ff2d5a26a 100644 --- a/x/ccv/provider/handler_test.go +++ b/x/ccv/provider/handler_test.go @@ -51,6 +51,9 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { setup: func(ctx sdk.Context, k keeper.Keeper, mocks testkeeper.MockedKeepers, ) { + k.SetPendingConsumerAdditionProp(ctx, &providertypes.ConsumerAdditionProposal{ + ChainId: "chainid", + }) gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidator( ctx, providerCryptoId.SDKValOpAddress(), @@ -64,11 +67,29 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { expError: false, chainID: "chainid", }, + { + name: "fail: chain ID not registered", + setup: func(ctx sdk.Context, + k keeper.Keeper, mocks testkeeper.MockedKeepers, + ) { + gomock.InOrder( + mocks.MockStakingKeeper.EXPECT().GetValidator( + ctx, providerCryptoId.SDKValOpAddress(), + // Return a valid validator, found! + ).Return(providerCryptoId.SDKStakingValidator(), true).Times(1), + ) + }, + expError: true, + chainID: "chainid", + }, { name: "fail: missing validator", setup: func(ctx sdk.Context, k keeper.Keeper, mocks testkeeper.MockedKeepers, ) { + k.SetPendingConsumerAdditionProp(ctx, &providertypes.ConsumerAdditionProposal{ + ChainId: "chainid", + }) gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidator( ctx, providerCryptoId.SDKValOpAddress(), @@ -84,6 +105,9 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { setup: func(ctx sdk.Context, k keeper.Keeper, mocks testkeeper.MockedKeepers, ) { + k.SetPendingConsumerAdditionProp(ctx, &providertypes.ConsumerAdditionProposal{ + ChainId: "chainid", + }) // Use the consumer key already k.SetValidatorByConsumerAddr(ctx, "chainid", consumerConsAddr, providerConsAddr) diff --git a/x/ccv/provider/keeper/consumer_equivocation.go b/x/ccv/provider/keeper/consumer_equivocation.go new file mode 100644 index 0000000000..53232b4205 --- /dev/null +++ b/x/ccv/provider/keeper/consumer_equivocation.go @@ -0,0 +1,480 @@ +package keeper + +import ( + "bytes" + "encoding/binary" + "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" + + errorsmod "cosmossdk.io/errors" + "cosmossdk.io/math" + + 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/v3/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v3/x/ccv/types" +) + +// +// Double Voting section +// + +// HandleConsumerDoubleVoting verifies a double voting evidence for a given a consumer chain ID +// and a public key and, if successful, executes the slashing, jailing, and tombstoning of the malicious validator. +func (k Keeper) HandleConsumerDoubleVoting( + ctx sdk.Context, + evidence *tmtypes.DuplicateVoteEvidence, + chainID string, + pubkey cryptotypes.PubKey, +) error { + // verifies the double voting evidence using the consumer chain public key + if err := k.VerifyDoubleVotingEvidence(*evidence, chainID, pubkey); err != nil { + return err + } + + // get the validator's consensus address on the provider + providerAddr := k.GetProviderAddrFromConsumerAddr( + ctx, + chainID, + types.NewConsumerConsAddress(sdk.ConsAddress(evidence.VoteA.ValidatorAddress.Bytes())), + ) + + if err := k.SlashValidator(ctx, providerAddr); err != nil { + return err + } + if err := k.JailAndTombstoneValidator(ctx, providerAddr); err != nil { + return err + } + + k.Logger(ctx).Info( + "confirmed equivocation", + "byzantine validator address", providerAddr.String(), + ) + + return nil +} + +// VerifyDoubleVotingEvidence verifies a double voting evidence +// for a given chain id and a validator public key +func (k Keeper) VerifyDoubleVotingEvidence( + evidence tmtypes.DuplicateVoteEvidence, + chainID string, + pubkey cryptotypes.PubKey, +) error { + if pubkey == nil { + return fmt.Errorf("validator public key cannot be empty") + } + + // check that the validator address in the evidence is derived from the provided public key + if !bytes.Equal(pubkey.Address(), evidence.VoteA.ValidatorAddress) { + return errorsmod.Wrapf( + ccvtypes.ErrInvalidDoubleVotingEvidence, + "public key %s doesn't correspond to the validator address %s in double vote evidence", + pubkey.String(), evidence.VoteA.ValidatorAddress.String(), + ) + } + + // Note the age of the evidence isn't checked. + + // height/round/type must be the same + if evidence.VoteA.Height != evidence.VoteB.Height || + evidence.VoteA.Round != evidence.VoteB.Round || + evidence.VoteA.Type != evidence.VoteB.Type { + return errorsmod.Wrapf( + ccvtypes.ErrInvalidDoubleVotingEvidence, + "height/round/type are not the same: %d/%d/%v vs %d/%d/%v", + evidence.VoteA.Height, evidence.VoteA.Round, evidence.VoteA.Type, + evidence.VoteB.Height, evidence.VoteB.Round, evidence.VoteB.Type) + } + + // Addresses must be the same + if !bytes.Equal(evidence.VoteA.ValidatorAddress, evidence.VoteB.ValidatorAddress) { + return errorsmod.Wrapf( + ccvtypes.ErrInvalidDoubleVotingEvidence, + "validator addresses do not match: %X vs %X", + evidence.VoteA.ValidatorAddress, + evidence.VoteB.ValidatorAddress, + ) + } + + // BlockIDs must be different + if evidence.VoteA.BlockID.Equals(evidence.VoteB.BlockID) { + return errorsmod.Wrapf( + ccvtypes.ErrInvalidDoubleVotingEvidence, + "block IDs are the same (%v) - not a real duplicate vote", + evidence.VoteA.BlockID, + ) + } + + va := evidence.VoteA.ToProto() + vb := evidence.VoteB.ToProto() + + // signatures must be valid + if !pubkey.VerifySignature(tmtypes.VoteSignBytes(chainID, va), evidence.VoteA.Signature) { + return fmt.Errorf("verifying VoteA: %w", tmtypes.ErrVoteInvalidSignature) + } + if !pubkey.VerifySignature(tmtypes.VoteSignBytes(chainID, vb), evidence.VoteB.Signature) { + return fmt.Errorf("verifying VoteB: %w", tmtypes.ErrVoteInvalidSignature) + } + + return nil +} + +// +// Light Client Attack (IBC misbehavior) section +// + +// HandleConsumerMisbehaviour checks if the given IBC misbehaviour corresponds to an equivocation light client attack, +// and in this case, slashes, jails, and tombstones +func (k Keeper) HandleConsumerMisbehaviour(ctx sdk.Context, misbehaviour ibctmtypes.Misbehaviour) error { + logger := k.Logger(ctx) + + // Check that the misbehaviour is valid and that the client consensus states at trusted heights are within trusting period + if err := k.CheckMisbehaviour(ctx, misbehaviour); err != nil { + logger.Info("Misbehaviour rejected", err.Error()) + + return err + } + + // Since the misbehaviour packet was received within the trusting period + // w.r.t to the trusted consensus states the infraction age + // isn't too old. see ibc-go/modules/light-clients/07-tendermint/types/misbehaviour_handle.go + + // Get Byzantine validators from the conflicting headers + byzantineValidators, err := k.GetByzantineValidators(ctx, misbehaviour) + if err != nil { + return err + } + + provAddrs := make([]types.ProviderConsAddress, len(byzantineValidators)) + + // slash, jail, and tombstone the Byzantine validators + for _, v := range byzantineValidators { + providerAddr := k.GetProviderAddrFromConsumerAddr( + ctx, + misbehaviour.Header1.Header.ChainID, + types.NewConsumerConsAddress(sdk.ConsAddress(v.Address.Bytes())), + ) + err := k.SlashValidator(ctx, providerAddr) + if err != nil { + logger.Error("failed to slash validator: %s", err) + continue + } + err = k.JailAndTombstoneValidator(ctx, providerAddr) + // JailAndTombstoneValidator should never return an error if + // SlashValidator succeeded because both methods fail if the malicious + // validator is either or both !found, unbonded and tombstoned. + if err != nil { + panic(err) + } + + provAddrs = append(provAddrs, providerAddr) + } + + // Return an error if no validators were punished + if len(provAddrs) == 0 { + return fmt.Errorf("failed to slash, jail, or tombstone all validators: %v", byzantineValidators) + } + + logger.Info( + "confirmed equivocation light client attack", + "byzantine validators slashed, jailed and tombstoned", provAddrs, + ) + + return nil +} + +// GetByzantineValidators returns the validators that signed both headers. +// If the misbehavior is an equivocation light client attack, then these +// validators are the Byzantine validators. +func (k Keeper) GetByzantineValidators(ctx sdk.Context, misbehaviour ibctmtypes.Misbehaviour) (validators []*tmtypes.Validator, err error) { + // construct the trusted and conflicted light blocks + lightBlock1, err := headerToLightBlock(*misbehaviour.Header1) + if err != nil { + return validators, err + } + lightBlock2, err := headerToLightBlock(*misbehaviour.Header2) + if err != nil { + return validators, err + } + + // Check if the misbehaviour corresponds to an Amnesia attack, + // meaning that the conflicting headers have both valid state transitions + // and different commit rounds. In this case, we return no validators as + // we can't identify the byzantine validators. + // + // Note that we cannot differentiate which of the headers is trusted or malicious, + if !headersStateTransitionsAreConflicting(*lightBlock1.Header, *lightBlock2.Header) && lightBlock1.Commit.Round != lightBlock2.Commit.Round { + return validators, nil + } + + // compare the signatures of the headers + // and return the intersection of validators who signed both + + // create a map with the validators' address that signed header1 + header1Signers := map[string]int{} + for idx, sign := range lightBlock1.Commit.Signatures { + if sign.Absent() { + continue + } + header1Signers[sign.ValidatorAddress.String()] = idx + } + + // iterate over the header2 signers and check if they signed header1 + for sigIdxHeader2, sign := range lightBlock2.Commit.Signatures { + if sign.Absent() { + continue + } + if sigIdxHeader1, ok := header1Signers[sign.ValidatorAddress.String()]; ok { + if err := verifyLightBlockCommitSig(*lightBlock1, sigIdxHeader1); err != nil { + return nil, err + } + + if err := verifyLightBlockCommitSig(*lightBlock2, sigIdxHeader2); err != nil { + return nil, err + } + + _, val := lightBlock1.ValidatorSet.GetByAddress(sign.ValidatorAddress) + validators = append(validators, val) + } + } + + return validators, nil +} + +// headerToLightBlock returns a CometBFT light block from the given IBC header +func headerToLightBlock(h ibctmtypes.Header) (*tmtypes.LightBlock, error) { + sh, err := tmtypes.SignedHeaderFromProto(h.SignedHeader) + if err != nil { + return nil, err + } + + vs, err := tmtypes.ValidatorSetFromProto(h.ValidatorSet) + if err != nil { + return nil, err + } + + return &tmtypes.LightBlock{ + SignedHeader: sh, + ValidatorSet: vs, + }, nil +} + +// CheckMisbehaviour checks that headers in the given misbehaviour forms +// a valid light client attack on a light client that tracks an ICS consumer chain +func (k Keeper) CheckMisbehaviour(ctx sdk.Context, misbehaviour ibctmtypes.Misbehaviour) error { + // check that the misbehaviour is for an ICS consumer chain + clientId, found := k.GetConsumerClientId(ctx, misbehaviour.Header1.Header.ChainID) + if !found { + return fmt.Errorf("incorrect misbehaviour with conflicting headers from a non-existent consumer chain: %s", misbehaviour.Header1.Header.ChainID) + } else if misbehaviour.ClientId != clientId { + return fmt.Errorf("incorrect misbehaviour: expected client ID for consumer chain %s is %s got %s", + misbehaviour.Header1.Header.ChainID, + clientId, + misbehaviour.ClientId, + ) + } + + clientState, found := k.clientKeeper.GetClientState(ctx, clientId) + if !found { + return errorsmod.Wrapf(ibcclienttypes.ErrClientNotFound, "cannot find client state for client with ID %s", clientId) + } + + clientStore := k.clientKeeper.ClientStore(ctx, clientId) + + // Check that the headers are at the same height to ensure that + // the misbehaviour is for a light client attack and not a time violation, + // see CheckForMisbehaviour in ibc-go/blob/v7.3.0/modules/light-clients/07-tendermint/misbehaviour_handle.go#L73 + if !misbehaviour.Header1.GetHeight().EQ(misbehaviour.Header2.GetHeight()) { + return errorsmod.Wrap(ibcclienttypes.ErrInvalidMisbehaviour, "headers are not at same height") + } + + // CheckForMisbehaviour verifies that the headers have different blockID hashes + ok := clientState.CheckForMisbehaviour(ctx, k.cdc, clientStore, &misbehaviour) + if !ok { + return errorsmod.Wrapf(ibcclienttypes.ErrInvalidMisbehaviour, "invalid misbehaviour for client-id: %s", misbehaviour.ClientId) + } + + // VerifyClientMessage calls verifyMisbehaviour which verifies that the headers in the misbehaviour + // are valid against their respective trusted consensus states and that at least a TrustLevel of the validator set signed their commit, + // see checkMisbehaviourHeader in ibc-go/blob/v7.3.0/modules/light-clients/07-tendermint/misbehaviour_handle.go#L126 + if err := clientState.VerifyClientMessage(ctx, k.cdc, clientStore, &misbehaviour); err != nil { + return err + } + + return nil +} + +// Check if the given block headers have conflicting state transitions. +// Note that this method was copied from ConflictingHeaderIsInvalid in CometBFT, +// see https://github.com/cometbft/cometbft/blob/v0.34.27/types/evidence.go#L285 +func headersStateTransitionsAreConflicting(h1, h2 tmtypes.Header) bool { + return !bytes.Equal(h1.ValidatorsHash, h2.ValidatorsHash) || + !bytes.Equal(h1.NextValidatorsHash, h2.NextValidatorsHash) || + !bytes.Equal(h1.ConsensusHash, h2.ConsensusHash) || + !bytes.Equal(h1.AppHash, h2.AppHash) || + !bytes.Equal(h1.LastResultsHash, h2.LastResultsHash) +} + +func verifyLightBlockCommitSig(lightBlock tmtypes.LightBlock, sigIdx int) error { + // get signature + sig := lightBlock.Commit.Signatures[sigIdx] + + // get validator + idx, val := lightBlock.ValidatorSet.GetByAddress(sig.ValidatorAddress) + if idx == -1 { + return fmt.Errorf("incorrect signature: validator address %s isn't part of the validator set", sig.ValidatorAddress.String()) + } + + // verify validator pubkey corresponds to signature validator address + if !bytes.Equal(val.PubKey.Address(), sig.ValidatorAddress) { + return fmt.Errorf("validator public key doesn't correspond to signature validator address: %s!= %s", val.PubKey.Address(), sig.ValidatorAddress) + } + + // validate signature + voteSignBytes := lightBlock.Commit.VoteSignBytes(lightBlock.ChainID, int32(sigIdx)) + if !val.PubKey.VerifySignature(voteSignBytes, sig.Signature) { + return fmt.Errorf("wrong signature (#%d): %X", sigIdx, sig.Signature) + } + + return nil +} + +// +// Punish Validator section +// + +// 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 { + return errorsmod.Wrapf(slashingtypes.ErrNoValidatorForAddress, "provider consensus address: %s", providerAddr.String()) + } + + if validator.IsUnbonded() { + return fmt.Errorf("validator is unbonded. provider consensus address: %s", providerAddr.String()) + } + + if k.slashingKeeper.IsTombstoned(ctx, providerAddr.ToSdkConsAddr()) { + return fmt.Errorf("validator is tombstoned. provider consensus address: %s", providerAddr.String()) + } + + // jail validator if not already + if !validator.IsJailed() { + k.stakingKeeper.Jail(ctx, providerAddr.ToSdkConsAddr()) + } + + k.slashingKeeper.JailUntil(ctx, providerAddr.ToSdkConsAddr(), evidencetypes.DoubleSignJailEndTime) + + // 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 +} + +// ComputePowerToSlash computes the power to be slashed based on the tokens in non-matured `undelegations` and +// `redelegations`, as well as the current `power` of the validator. +// Note that this method does not perform any slashing. +func (k Keeper) ComputePowerToSlash(ctx sdk.Context, validator stakingtypes.Validator, undelegations []stakingtypes.UnbondingDelegation, + redelegations []stakingtypes.Redelegation, power int64, powerReduction math.Int, +) int64 { + // compute the total numbers of tokens currently being undelegated + undelegationsInTokens := sdk.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)) + undelegationsInTokens = undelegationsInTokens.Add(amountSlashed) + } + + // compute the total numbers of tokens currently being redelegated + redelegationsInTokens := sdk.NewInt(0) + for _, r := range redelegations { + amountSlashed := k.stakingKeeper.SlashRedelegation(cachedCtx, validator, r, 0, sdk.NewDec(1)) + redelegationsInTokens = redelegationsInTokens.Add(amountSlashed) + } + + // The power we pass to staking's keeper `Slash` method is the current power of the validator together with the total + // power of all the currently undelegated and redelegated tokens (see docs/docs/adrs/adr-013-equivocation-slashing.md). + undelegationsAndRedelegationsInPower := sdk.TokensToConsensusPower( + undelegationsInTokens.Add(redelegationsInTokens), powerReduction) + + return power + undelegationsAndRedelegationsInPower +} + +// 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 { + return errorsmod.Wrapf(slashingtypes.ErrNoValidatorForAddress, "provider consensus address: %s", providerAddr.String()) + } + + if validator.IsUnbonded() { + return fmt.Errorf("validator is unbonded. provider consensus address: %s", providerAddr.String()) + } + + if k.slashingKeeper.IsTombstoned(ctx, providerAddr.ToSdkConsAddr()) { + 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()) + powerReduction := k.stakingKeeper.PowerReduction(ctx) + totalPower := k.ComputePowerToSlash(ctx, validator, undelegations, redelegations, lastPower, powerReduction) + slashFraction := k.slashingKeeper.SlashFractionDoubleSign(ctx) + + consAdrr, err := validator.GetConsAddr() + if err != nil { + panic(err) + } + + k.stakingKeeper.SlashWithInfractionReason(ctx, consAdrr, 0, totalPower, slashFraction, stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN) + + return nil +} + +// +// CRUD section +// + +// SetEquivocationEvidenceMinHeight sets the 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) + heightBytes := make([]byte, 8) + binary.BigEndian.PutUint64(heightBytes, height) + + store.Set(types.EquivocationEvidenceMinHeightKey(chainID), heightBytes) +} + +// GetEquivocationEvidenceMinHeight returns the 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) + bz := store.Get(types.EquivocationEvidenceMinHeightKey(chainID)) + if bz == nil { + return 0 + } + + return binary.BigEndian.Uint64(bz) +} + +// DeleteEquivocationEvidenceMinHeight deletes the 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) + store.Delete(types.EquivocationEvidenceMinHeightKey(chainID)) +} diff --git a/x/ccv/provider/keeper/consumer_equivocation_test.go b/x/ccv/provider/keeper/consumer_equivocation_test.go new file mode 100644 index 0000000000..f7a736dff1 --- /dev/null +++ b/x/ccv/provider/keeper/consumer_equivocation_test.go @@ -0,0 +1,790 @@ +package keeper_test + +import ( + "fmt" + "testing" + "time" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + + "cosmossdk.io/math" + + 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/v3/testutil/crypto" + testkeeper "github.com/cosmos/interchain-security/v3/testutil/keeper" + "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" +) + +func TestVerifyDoubleVotingEvidence(t *testing.T) { + keeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + chainID := "consumer" + + signer1 := tmtypes.NewMockPV() + signer2 := tmtypes.NewMockPV() + + val1 := tmtypes.NewValidator(signer1.PrivKey.PubKey(), 1) + val2 := tmtypes.NewValidator(signer2.PrivKey.PubKey(), 1) + + valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{val1, val2}) + + blockID1 := cryptotestutil.MakeBlockID([]byte("blockhash"), 1000, []byte("partshash")) + blockID2 := cryptotestutil.MakeBlockID([]byte("blockhash2"), 1000, []byte("partshash")) + + ctx = ctx.WithBlockTime(time.Now()) + + valPubkey1, err := cryptocodec.FromTmPubKeyInterface(val1.PubKey) + require.NoError(t, err) + + valPubkey2, err := cryptocodec.FromTmPubKeyInterface(val2.PubKey) + require.NoError(t, err) + + testCases := []struct { + name string + votes []*tmtypes.Vote + chainID string + pubkey cryptotypes.PubKey + expPass bool + }{ + { + "invalid verifying public key - shouldn't pass", + []*tmtypes.Vote{ + cryptotestutil.MakeAndSignVote( + blockID1, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + chainID, + ), + cryptotestutil.MakeAndSignVote( + blockID2, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + chainID, + ), + }, + chainID, + nil, + false, + }, + { + "verifying public key doesn't correspond to validator address", + []*tmtypes.Vote{ + cryptotestutil.MakeAndSignVoteWithForgedValAddress( + blockID1, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + signer2, + chainID, + ), + cryptotestutil.MakeAndSignVoteWithForgedValAddress( + blockID2, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + signer2, + chainID, + ), + }, + chainID, + valPubkey1, + false, + }, + { + "evidence has votes with different block height - shouldn't pass", + []*tmtypes.Vote{ + cryptotestutil.MakeAndSignVote( + blockID1, + ctx.BlockHeight()+1, + ctx.BlockTime(), + valSet, + signer1, + chainID, + ), + cryptotestutil.MakeAndSignVote( + blockID2, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + chainID, + ), + }, + chainID, + valPubkey1, + false, + }, + { + "evidence has votes with different validator address - shouldn't pass", + []*tmtypes.Vote{ + cryptotestutil.MakeAndSignVote( + blockID1, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + chainID, + ), + cryptotestutil.MakeAndSignVote( + blockID2, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer2, + chainID, + ), + }, + chainID, + valPubkey1, + false, + }, + { + "evidence has votes with same block IDs - shouldn't pass", + []*tmtypes.Vote{ + cryptotestutil.MakeAndSignVote( + blockID1, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + chainID, + ), + cryptotestutil.MakeAndSignVote( + blockID1, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + chainID, + ), + }, + chainID, + valPubkey1, + false, + }, + { + "given chain ID isn't the same as the one used to sign the votes - shouldn't pass", + []*tmtypes.Vote{ + cryptotestutil.MakeAndSignVote( + blockID1, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + chainID, + ), + cryptotestutil.MakeAndSignVote( + blockID2, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + chainID, + ), + }, + "WrongChainID", + valPubkey1, + false, + }, + { + "voteA is signed using the wrong chain ID - shouldn't pass", + []*tmtypes.Vote{ + cryptotestutil.MakeAndSignVote( + blockID1, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + "WrongChainID", + ), + cryptotestutil.MakeAndSignVote( + blockID2, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + chainID, + ), + }, + chainID, + valPubkey1, + false, + }, + { + "voteB is signed using the wrong chain ID - shouldn't pass", + []*tmtypes.Vote{ + cryptotestutil.MakeAndSignVote( + blockID1, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + chainID, + ), + cryptotestutil.MakeAndSignVote( + blockID2, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + "WrongChainID", + ), + }, + chainID, + valPubkey1, + false, + }, + { + "wrong public key - shouldn't pass", + []*tmtypes.Vote{ + cryptotestutil.MakeAndSignVote( + blockID1, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + chainID, + ), + cryptotestutil.MakeAndSignVote( + blockID2, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + chainID, + ), + }, + chainID, + valPubkey2, + false, + }, + { + "valid double voting evidence should pass", + []*tmtypes.Vote{ + cryptotestutil.MakeAndSignVote( + blockID1, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + chainID, + ), + cryptotestutil.MakeAndSignVote( + blockID2, + ctx.BlockHeight(), + ctx.BlockTime(), + valSet, + signer1, + chainID, + ), + }, + chainID, + valPubkey1, + true, + }, + } + + for _, tc := range testCases { + err = keeper.VerifyDoubleVotingEvidence( + tmtypes.DuplicateVoteEvidence{ + VoteA: tc.votes[0], + VoteB: tc.votes[1], + ValidatorPower: val1.VotingPower, + TotalVotingPower: val1.VotingPower, + Timestamp: tc.votes[0].Timestamp, + }, + tc.chainID, + tc.pubkey, + ) + if tc.expPass { + require.NoError(t, err) + } else { + require.Error(t, err) + } + } +} + +// TestJailAndTombstoneValidator tests that the jailing of a validator is only executed +// under the conditions that the validator is neither unbonded, nor jailed, nor tombstoned. +func TestJailAndTombstoneValidator(t *testing.T) { + providerConsAddr := cryptotestutil.NewCryptoIdentityFromIntSeed(7842334).ProviderConsAddress() + testCases := []struct { + name string + provAddr types.ProviderConsAddress + expectedCalls func(sdk.Context, testkeeper.MockedKeepers, types.ProviderConsAddress) []*gomock.Call + }{ + { + "unfound validator", + providerConsAddr, + func(ctx sdk.Context, mocks testkeeper.MockedKeepers, + provAddr types.ProviderConsAddress, + ) []*gomock.Call { + return []*gomock.Call{ + // We only expect a single call to GetValidatorByConsAddr. + // Method will return once validator is not found. + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( + ctx, providerConsAddr.ToSdkConsAddr()).Return( + stakingtypes.Validator{}, false, // false = Not found. + ).Times(1), + } + }, + }, + { + "unbonded validator", + providerConsAddr, + func(ctx sdk.Context, mocks testkeeper.MockedKeepers, + provAddr types.ProviderConsAddress, + ) []*gomock.Call { + return []*gomock.Call{ + // We only expect a single call to GetValidatorByConsAddr. + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( + ctx, providerConsAddr.ToSdkConsAddr()).Return( + stakingtypes.Validator{Status: stakingtypes.Unbonded}, true, + ).Times(1), + } + }, + }, + { + "tombstoned validator", + providerConsAddr, + func(ctx sdk.Context, mocks testkeeper.MockedKeepers, + provAddr types.ProviderConsAddress, + ) []*gomock.Call { + return []*gomock.Call{ + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( + ctx, providerConsAddr.ToSdkConsAddr()).Return( + stakingtypes.Validator{}, true, + ).Times(1), + mocks.MockSlashingKeeper.EXPECT().IsTombstoned( + ctx, providerConsAddr.ToSdkConsAddr()).Return( + true, + ).Times(1), + } + }, + }, + { + "jailed validator", + providerConsAddr, + func(ctx sdk.Context, mocks testkeeper.MockedKeepers, + provAddr types.ProviderConsAddress, + ) []*gomock.Call { + return []*gomock.Call{ + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( + ctx, providerConsAddr.ToSdkConsAddr()).Return( + stakingtypes.Validator{Jailed: true}, true, + ).Times(1), + mocks.MockSlashingKeeper.EXPECT().IsTombstoned( + ctx, providerConsAddr.ToSdkConsAddr()).Return( + false, + ).Times(1), + mocks.MockSlashingKeeper.EXPECT().JailUntil( + ctx, providerConsAddr.ToSdkConsAddr(), evidencetypes.DoubleSignJailEndTime). + Times(1), + mocks.MockSlashingKeeper.EXPECT().Tombstone( + ctx, providerConsAddr.ToSdkConsAddr()). + Times(1), + } + }, + }, + { + "bonded validator", + providerConsAddr, + func(ctx sdk.Context, mocks testkeeper.MockedKeepers, + provAddr types.ProviderConsAddress, + ) []*gomock.Call { + return []*gomock.Call{ + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr( + ctx, providerConsAddr.ToSdkConsAddr()).Return( + stakingtypes.Validator{Status: stakingtypes.Bonded}, true, + ).Times(1), + mocks.MockSlashingKeeper.EXPECT().IsTombstoned( + ctx, providerConsAddr.ToSdkConsAddr()).Return( + false, + ).Times(1), + mocks.MockStakingKeeper.EXPECT().Jail( + ctx, providerConsAddr.ToSdkConsAddr()). + Times(1), + mocks.MockSlashingKeeper.EXPECT().JailUntil( + ctx, providerConsAddr.ToSdkConsAddr(), evidencetypes.DoubleSignJailEndTime). + Times(1), + mocks.MockSlashingKeeper.EXPECT().Tombstone( + ctx, providerConsAddr.ToSdkConsAddr()). + Times(1), + } + }, + }, + } + + for _, tc := range testCases { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx( + t, testkeeper.NewInMemKeeperParams(t)) + + // Setup expected mock calls + gomock.InOrder(tc.expectedCalls(ctx, mocks, tc.provAddr)...) + + // Execute method and assert expected mock calls + providerKeeper.JailAndTombstoneValidator(ctx, tc.provAddr) + + ctrl.Finish() + } +} + +// createUndelegation creates an undelegation with `len(initialBalances)` entries +func createUndelegation(initialBalances []int64, completionTimes []time.Time) stakingtypes.UnbondingDelegation { + var entries []stakingtypes.UnbondingDelegationEntry + for i, balance := range initialBalances { + entry := stakingtypes.UnbondingDelegationEntry{ + InitialBalance: sdk.NewInt(balance), + CompletionTime: completionTimes[i], + } + entries = append(entries, entry) + } + + return stakingtypes.UnbondingDelegation{Entries: entries} +} + +// createRedelegation creates a redelegation with `len(initialBalances)` entries +func createRedelegation(initialBalances []int64, completionTimes []time.Time) stakingtypes.Redelegation { + var entries []stakingtypes.RedelegationEntry + for i, balance := range initialBalances { + entry := stakingtypes.RedelegationEntry{ + InitialBalance: sdk.NewInt(balance), + CompletionTime: completionTimes[i], + } + entries = append(entries, entry) + } + + return stakingtypes.Redelegation{Entries: entries} +} + +// TestComputePowerToSlash tests that `ComputePowerToSlash` computes the correct power to be slashed based on +// the tokens in non-mature undelegation and redelegation entries, as well as the current power of the validator +func TestComputePowerToSlash(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + // undelegation or redelegation entries with completion time `now` have matured + now := ctx.BlockHeader().Time + // undelegation or redelegation entries with completion time one hour in the future have not yet matured + nowPlus1Hour := now.Add(time.Hour) + + testCases := []struct { + name string + undelegations []stakingtypes.UnbondingDelegation + redelegations []stakingtypes.Redelegation + power int64 + powerReduction math.Int + expectedPower int64 + }{ + { + "both undelegations and redelegations 1", + // 1000 total undelegation tokens + []stakingtypes.UnbondingDelegation{ + createUndelegation([]int64{250, 250}, []time.Time{nowPlus1Hour, nowPlus1Hour}), + createUndelegation([]int64{500}, []time.Time{nowPlus1Hour, nowPlus1Hour}), + }, + // 1000 total redelegation tokens + []stakingtypes.Redelegation{ + createRedelegation([]int64{500}, []time.Time{nowPlus1Hour, nowPlus1Hour}), + createRedelegation([]int64{250, 250}, []time.Time{nowPlus1Hour, nowPlus1Hour}), + }, + int64(1000), + sdk.NewInt(1), + int64(2000/1 + 1000), + }, + { + "both undelegations and redelegations 2", + // 2000 total undelegation tokens + []stakingtypes.UnbondingDelegation{ + createUndelegation([]int64{250, 250}, []time.Time{nowPlus1Hour, nowPlus1Hour}), + createUndelegation([]int64{}, []time.Time{}), + createUndelegation([]int64{100, 100}, []time.Time{nowPlus1Hour, nowPlus1Hour}), + createUndelegation([]int64{800}, []time.Time{nowPlus1Hour}), + createUndelegation([]int64{500}, []time.Time{nowPlus1Hour}), + }, + // 3500 total redelegation tokens + []stakingtypes.Redelegation{ + createRedelegation([]int64{}, []time.Time{}), + createRedelegation([]int64{1600}, []time.Time{nowPlus1Hour}), + createRedelegation([]int64{350, 250}, []time.Time{nowPlus1Hour, nowPlus1Hour}), + createRedelegation([]int64{700, 200}, []time.Time{nowPlus1Hour, nowPlus1Hour}), + createRedelegation([]int64{}, []time.Time{}), + createRedelegation([]int64{400}, []time.Time{nowPlus1Hour}), + }, + int64(8391), + sdk.NewInt(2), + int64((2000+3500)/2 + 8391), + }, + { + "no undelegations or redelegations, return provided power", + []stakingtypes.UnbondingDelegation{}, + []stakingtypes.Redelegation{}, + int64(3000), + sdk.NewInt(5), + int64(3000), // expectedPower is 0/5 + 3000 + }, + { + "no undelegations", + []stakingtypes.UnbondingDelegation{}, + // 2000 total redelegation tokens + []stakingtypes.Redelegation{ + createRedelegation([]int64{}, []time.Time{}), + createRedelegation([]int64{500}, []time.Time{nowPlus1Hour}), + createRedelegation([]int64{250, 250}, []time.Time{nowPlus1Hour, nowPlus1Hour}), + createRedelegation([]int64{700, 200}, []time.Time{nowPlus1Hour, nowPlus1Hour}), + createRedelegation([]int64{}, []time.Time{}), + createRedelegation([]int64{100}, []time.Time{nowPlus1Hour}), + }, + int64(17), + sdk.NewInt(3), + int64(2000/3 + 17), + }, + { + "no redelegations", + // 2000 total undelegation tokens + []stakingtypes.UnbondingDelegation{ + createUndelegation([]int64{250, 250}, []time.Time{nowPlus1Hour, nowPlus1Hour}), + createUndelegation([]int64{}, []time.Time{}), + createUndelegation([]int64{100, 100}, []time.Time{nowPlus1Hour, nowPlus1Hour}), + createUndelegation([]int64{800}, []time.Time{nowPlus1Hour}), + createUndelegation([]int64{500}, []time.Time{nowPlus1Hour}), + }, + []stakingtypes.Redelegation{}, + int64(1), + sdk.NewInt(3), + int64(2000/3 + 1), + }, + { + "both (mature) undelegations and redelegations", + // 2000 total undelegation tokens, 250 + 100 + 500 = 850 of those are from mature undelegations, + // so 2000 - 850 = 1150 + []stakingtypes.UnbondingDelegation{ + createUndelegation([]int64{250, 250}, []time.Time{nowPlus1Hour, now}), + createUndelegation([]int64{}, []time.Time{}), + createUndelegation([]int64{100, 100}, []time.Time{now, nowPlus1Hour}), + createUndelegation([]int64{800}, []time.Time{nowPlus1Hour}), + createUndelegation([]int64{500}, []time.Time{now}), + }, + // 3500 total redelegation tokens, 350 + 200 + 400 = 950 of those are from mature redelegations + // so 3500 - 950 = 2550 + []stakingtypes.Redelegation{ + createRedelegation([]int64{}, []time.Time{}), + createRedelegation([]int64{1600}, []time.Time{nowPlus1Hour}), + createRedelegation([]int64{350, 250}, []time.Time{now, nowPlus1Hour}), + createRedelegation([]int64{700, 200}, []time.Time{nowPlus1Hour, now}), + createRedelegation([]int64{}, []time.Time{}), + createRedelegation([]int64{400}, []time.Time{now}), + }, + int64(8391), + sdk.NewInt(2), + int64((1150+2550)/2 + 8391), + }, + } + + pubKey, _ := cryptocodec.FromTmPubKeyInterface(tmtypes.NewMockPV().PrivKey.PubKey()) + validator, _ := stakingtypes.NewValidator(pubKey.Address().Bytes(), pubKey, stakingtypes.Description{}) + + for _, tc := range testCases { + gomock.InOrder(mocks.MockStakingKeeper.EXPECT(). + SlashUnbondingDelegation(gomock.Any(), gomock.Any(), int64(0), sdk.NewDec(1)). + DoAndReturn( + func(_ sdk.Context, undelegation stakingtypes.UnbondingDelegation, _ int64, _ sdk.Dec) math.Int { + sum := sdk.NewInt(0) + for _, r := range undelegation.Entries { + if r.IsMature(ctx.BlockTime()) { + continue + } + sum = sum.Add(sdk.NewInt(r.InitialBalance.Int64())) + } + return sum + }).AnyTimes(), + mocks.MockStakingKeeper.EXPECT(). + SlashRedelegation(gomock.Any(), gomock.Any(), gomock.Any(), int64(0), sdk.NewDec(1)). + DoAndReturn( + func(ctx sdk.Context, _ stakingtypes.Validator, redelegation stakingtypes.Redelegation, _ int64, _ sdk.Dec) math.Int { + sum := sdk.NewInt(0) + for _, r := range redelegation.Entries { + if r.IsMature(ctx.BlockTime()) { + continue + } + sum = sum.Add(sdk.NewInt(r.InitialBalance.Int64())) + } + return sum + }).AnyTimes(), + ) + + actualPower := providerKeeper.ComputePowerToSlash(ctx, validator, + tc.undelegations, tc.redelegations, tc.power, tc.powerReduction) + + if tc.expectedPower != actualPower { + require.Fail(t, fmt.Sprintf("\"%s\" failed", tc.name), + "expected is %d but actual is %d", tc.expectedPower, actualPower) + } + } +} + +// TestSlashValidator asserts that `SlashValidator` calls the staking module's `Slash` method +// with the correct arguments (i.e., `infractionHeight` of 0 and the expected slash power) +func TestSlashValidator(t *testing.T) { + keeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + // undelegation or redelegation entries with completion time `now` have matured + now := ctx.BlockHeader().Time + // 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()), + pubKey, + stakingtypes.NewDescription("", "", "", "", ""), + ) + require.NoError(t, err) + validator.Status = stakingtypes.Bonded + + consAddr, _ := validator.GetConsAddr() + providerAddr := types.NewProviderConsAddress(consAddr) + + // we create 1000 tokens worth of undelegations, 750 of them are non-matured + // we also create 1000 tokens worth of redelegations, 750 of them are non-matured + undelegations := []stakingtypes.UnbondingDelegation{ + createUndelegation([]int64{250, 250}, []time.Time{nowPlus1Hour, now}), + createUndelegation([]int64{500}, []time.Time{nowPlus1Hour}), + } + redelegations := []stakingtypes.Redelegation{ + createRedelegation([]int64{250, 250}, []time.Time{now, nowPlus1Hour}), + createRedelegation([]int64{500}, []time.Time{nowPlus1Hour}), + } + + // validator's current power + currentPower := int64(3000) + + powerReduction := sdk.NewInt(2) + slashFraction, _ := sdk.NewDecFromStr("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) + + expectedCalls := []*gomock.Call{ + mocks.MockStakingKeeper.EXPECT(). + GetValidatorByConsAddr(ctx, gomock.Any()). + Return(validator, true), + mocks.MockSlashingKeeper.EXPECT(). + IsTombstoned(ctx, consAddr). + Return(false), + mocks.MockStakingKeeper.EXPECT(). + GetUnbondingDelegationsFromValidator(ctx, validator.GetOperator()). + Return(undelegations), + mocks.MockStakingKeeper.EXPECT(). + GetRedelegationsFromSrcValidator(ctx, validator.GetOperator()). + Return(redelegations), + mocks.MockStakingKeeper.EXPECT(). + GetLastValidatorPower(ctx, validator.GetOperator()). + Return(currentPower), + 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) + for _, r := range undelegation.Entries { + if r.IsMature(ctx.BlockTime()) { + continue + } + sum = sum.Add(sdk.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) + for _, r := range redelegation.Entries { + if r.IsMature(ctx.BlockTime()) { + continue + } + sum = sum.Add(sdk.NewInt(r.InitialBalance.Int64())) + } + return sum + }).AnyTimes(), + mocks.MockSlashingKeeper.EXPECT(). + SlashFractionDoubleSign(ctx). + Return(slashFraction), + mocks.MockStakingKeeper.EXPECT(). + SlashWithInfractionReason(ctx, consAddr, expectedInfractionHeight, expectedSlashPower, slashFraction, stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN). + Times(1), + } + + gomock.InOrder(expectedCalls...) + keeper.SlashValidator(ctx, providerAddr) +} + +// TestSlashValidatorDoesNotSlashIfValidatorIsUnbonded asserts that `SlashValidator` does not call +// the staking module's `Slash` method if the validator to be slashed is unbonded +func TestSlashValidatorDoesNotSlashIfValidatorIsUnbonded(t *testing.T) { + keeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + keeperParams := testkeeper.NewInMemKeeperParams(t) + testkeeper.NewInMemProviderKeeper(keeperParams, mocks) + + pubKey, _ := cryptocodec.FromTmPubKeyInterface(tmtypes.NewMockPV().PrivKey.PubKey()) + + // validator is initially unbonded + validator, _ := stakingtypes.NewValidator(pubKey.Address().Bytes(), pubKey, stakingtypes.Description{}) + + consAddr, _ := validator.GetConsAddr() + providerAddr := types.NewProviderConsAddress(consAddr) + + expectedCalls := []*gomock.Call{ + mocks.MockStakingKeeper.EXPECT(). + GetValidatorByConsAddr(ctx, gomock.Any()). + Return(validator, true), + } + + gomock.InOrder(expectedCalls...) + keeper.SlashValidator(ctx, providerAddr) +} + +func TestEquivocationEvidenceMinHeightCRUD(t *testing.T) { + chainID := consumer + expMinHeight := uint64(12) + keeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + height := keeper.GetEquivocationEvidenceMinHeight(ctx, chainID) + require.Zero(t, height, "equivocation evidence min height should be 0") + + keeper.SetEquivocationEvidenceMinHeight(ctx, chainID, expMinHeight) + height = keeper.GetEquivocationEvidenceMinHeight(ctx, chainID) + require.Equal(t, height, expMinHeight) + + keeper.DeleteEquivocationEvidenceMinHeight(ctx, chainID) + height = keeper.GetEquivocationEvidenceMinHeight(ctx, chainID) + require.Zero(t, height, "equivocation evidence min height should be 0") +} diff --git a/x/ccv/provider/keeper/grpc_query.go b/x/ccv/provider/keeper/grpc_query.go index 2b522ea9ef..d1f111e38e 100644 --- a/x/ccv/provider/keeper/grpc_query.go +++ b/x/ccv/provider/keeper/grpc_query.go @@ -2,7 +2,6 @@ package keeper import ( "context" - "fmt" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -148,108 +147,38 @@ func (k Keeper) QueryThrottleState(goCtx context.Context, req *types.QueryThrott meter := k.GetSlashMeter(ctx) allowance := k.GetSlashMeterAllowance(ctx) candidate := k.GetSlashMeterReplenishTimeCandidate(ctx) // always UTC - packets := []*types.ThrottledSlashPacket{} - - // iterate global slash entries from all consumer chains - // and fetch corresponding SlashPacketData from the per-chain throttled packet data queue - allGlobalEntries := k.GetAllGlobalSlashEntries(ctx) - - for _, entry := range allGlobalEntries { - // Obtain slash packet data instance for the given global entry - slashData, found := k.getSlashPacketData(ctx, entry.ConsumerChainID, entry.IbcSeqNum) - if !found { - // silently skip over invalid data - continue - } - - packets = append(packets, &types.ThrottledSlashPacket{ - GlobalEntry: entry, - Data: slashData, - }) - } return &types.QueryThrottleStateResponse{ SlashMeter: meter.Int64(), SlashMeterAllowance: allowance.Int64(), NextReplenishCandidate: candidate, - Packets: packets, }, nil } -func (k Keeper) QueryThrottledConsumerPacketData(goCtx context.Context, req *types.QueryThrottledConsumerPacketDataRequest) (*types.QueryThrottledConsumerPacketDataResponse, error) { +func (k Keeper) QueryRegisteredConsumerRewardDenoms(goCtx context.Context, req *types.QueryRegisteredConsumerRewardDenomsRequest) (*types.QueryRegisteredConsumerRewardDenomsResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") } - if req.ChainId == "" { - return nil, status.Error(codes.InvalidArgument, "invalid chain-id") - } - ctx := sdk.UnwrapSDKContext(goCtx) - if _, found := k.GetChainToChannel(ctx, req.ChainId); !found { - return nil, status.Error(codes.InvalidArgument, "invalid chain-id") - } - - packetDataInstances := []types.ThrottledPacketDataWrapper{} - _, _, rawOrderedData, _ := k.GetAllThrottledPacketData(ctx, req.ChainId) - - for _, raw := range rawOrderedData { - switch data := raw.(type) { - case ccvtypes.SlashPacketData: - w := &types.ThrottledPacketDataWrapper_SlashPacket{SlashPacket: &data} - packetDataInstances = append(packetDataInstances, types.ThrottledPacketDataWrapper{ - Data: w, - }) - case ccvtypes.VSCMaturedPacketData: - w := &types.ThrottledPacketDataWrapper_VscMaturedPacket{VscMaturedPacket: &data} - packetDataInstances = append(packetDataInstances, types.ThrottledPacketDataWrapper{ - Data: w, - }) - default: - k.Logger(ctx).Error(fmt.Sprintf("unexpected packet data type: %T", data)) - } - } - - return &types.QueryThrottledConsumerPacketDataResponse{ - ChainId: req.ChainId, - Size_: k.GetThrottledPacketDataSize(ctx, req.ChainId), - PacketDataInstances: packetDataInstances, - }, nil -} - -// getSlashPacketData fetches a slash packet data from the store using consumerChainId and ibcSeqNum (direct access) -// If the returned bytes do not unmarshal to SlashPacketData, the data is considered not found. -func (k Keeper) getSlashPacketData(ctx sdk.Context, consumerChainID string, ibcSeqNum uint64) (ccvtypes.SlashPacketData, bool) { - store := ctx.KVStore(k.storeKey) - bz := store.Get(types.ThrottledPacketDataKey(consumerChainID, ibcSeqNum)) - if len(bz) == 0 { - return ccvtypes.SlashPacketData{}, false - } - if bz[0] != slashPacketData { - return ccvtypes.SlashPacketData{}, false - } - - packet := ccvtypes.SlashPacketData{} - err := packet.Unmarshal(bz[1:]) - if err != nil { - // If the data cannot be unmarshaled, it is considered not found - return ccvtypes.SlashPacketData{}, false - } + denoms := k.GetAllConsumerRewardDenoms(ctx) - return packet, true + return &types.QueryRegisteredConsumerRewardDenomsResponse{ + Denoms: denoms, + }, nil } -func (k Keeper) QueryRegisteredConsumerRewardDenoms(goCtx context.Context, req *types.QueryRegisteredConsumerRewardDenomsRequest) (*types.QueryRegisteredConsumerRewardDenomsResponse, error) { +func (k Keeper) QueryProposedConsumerChainIDs(goCtx context.Context, req *types.QueryProposedChainIDsRequest) (*types.QueryProposedChainIDsResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") } ctx := sdk.UnwrapSDKContext(goCtx) - denoms := k.GetAllConsumerRewardDenoms(ctx) + chains := k.GetAllProposedConsumerChainIDs(ctx) - return &types.QueryRegisteredConsumerRewardDenomsResponse{ - Denoms: denoms, + return &types.QueryProposedChainIDsResponse{ + ProposedChains: chains, }, nil } diff --git a/x/ccv/provider/keeper/hooks.go b/x/ccv/provider/keeper/hooks.go index 35c9b96301..be7e5947a1 100644 --- a/x/ccv/provider/keeper/hooks.go +++ b/x/ccv/provider/keeper/hooks.go @@ -1,7 +1,11 @@ package keeper import ( + "fmt" + 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/v3/x/ccv/provider/types" @@ -13,13 +17,20 @@ type Hooks struct { k *Keeper } -var _ stakingtypes.StakingHooks = Hooks{} +var ( + _ stakingtypes.StakingHooks = Hooks{} + _ sdkgov.GovHooks = Hooks{} +) // Returns new provider hooks func (k *Keeper) Hooks() Hooks { return Hooks{k} } +// +// staking 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 { var consumerChainIDS []string @@ -80,38 +91,8 @@ func (h Hooks) AfterUnbondingInitiated(ctx sdk.Context, id uint64) error { return nil } -// ValidatorConsensusKeyInUse is called when a new validator is created -// in the x/staking module of cosmos-sdk. In case it panics, the TX aborts -// and thus, the validator is not created. See AfterValidatorCreated hook. -func ValidatorConsensusKeyInUse(k *Keeper, 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 { - // Abort TX, do NOT allow validator to be created - panic("did not find newly created validator in staking module") - } - - // Get the consensus address of the validator being added - consensusAddr, err := val.GetConsAddr() - if err != nil { - // Abort TX, do NOT allow validator to be created - panic("could not get validator cons addr ") - } - - inUse := false - - for _, validatorConsumerAddrs := range k.GetAllValidatorsByConsumerAddr(ctx, nil) { - if sdk.ConsAddress(validatorConsumerAddrs.ConsumerAddr).Equals(consensusAddr) { - inUse = true - break - } - } - - return inUse -} - func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) error { - if ValidatorConsensusKeyInUse(h.k, ctx, valAddr) { + 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") } @@ -167,3 +148,72 @@ func (h Hooks) AfterValidatorBeginUnbonding(_ sdk.Context, _ sdk.ConsAddress, _ func (h Hooks) BeforeDelegationRemoved(_ sdk.Context, _ sdk.AccAddress, _ sdk.ValAddress) error { return nil } + +// +// gov hooks +// + +// 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) { + if p, ok := h.GetConsumerAdditionLegacyPropFromProp(ctx, proposalID); ok { + h.k.SetProposedConsumerChain(ctx, p.ChainId, proposalID) + } +} + +// 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) { + if _, ok := h.GetConsumerAdditionLegacyPropFromProp(ctx, proposalID); ok { + h.k.DeleteProposedConsumerChainInStore(ctx, proposalID) + } +} + +func (h Hooks) AfterProposalDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) { +} + +func (h Hooks) AfterProposalVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress) { +} + +func (h Hooks) AfterProposalFailedMinDeposit(ctx sdk.Context, proposalID uint64) { +} + +// GetConsumerAdditionLegacyPropFromProp extracts a consumer addition legacy proposal from +// the proposal with the given ID +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)) + } + + // Iterate over the messages in the proposal + // Note that it's assumed that at most ONE message can contain a consumer addition proposal + for _, msg := range p.GetMessages() { + sdkMsg, isLegacyProposal := msg.GetCachedValue().(*v1.MsgExecLegacyContent) + if !isLegacyProposal { + continue + } + + content, err := v1.LegacyContentFromMessage(sdkMsg) + if err != nil { + panic(fmt.Errorf("failed to get legacy proposal %d from prop message", proposalID)) + } + + // returns if legacy prop is of ConsumerAddition proposal type + prop, ok := content.(*providertypes.ConsumerAdditionProposal) + if ok { + return *prop, true + } + } + 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 83dbfe9622..47175eb907 100644 --- a/x/ccv/provider/keeper/hooks_test.go +++ b/x/ccv/provider/keeper/hooks_test.go @@ -2,10 +2,18 @@ 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/v3/testutil/crypto" testkeeper "github.com/cosmos/interchain-security/v3/testutil/keeper" @@ -38,6 +46,7 @@ func TestValidatorConsensusKeyInUse(t *testing.T) { newValidator.ConsumerConsAddress(), anotherValidator0.ProviderConsAddress(), ) + k.SetConsumerClientId(ctx, "chainid", "clientID") }, expect: true, }, @@ -50,16 +59,20 @@ func TestValidatorConsensusKeyInUse(t *testing.T) { newValidator.ConsumerConsAddress(), anotherValidator0.ProviderConsAddress(), ) + k.SetConsumerClientId(ctx, "chainid0", "clientID0") + k.SetValidatorByConsumerAddr(ctx, "chainid1", anotherValidator1.ConsumerConsAddress(), anotherValidator1.ProviderConsAddress(), ) + k.SetConsumerClientId(ctx, "chainid1", "clientID1") }, expect: true, }, } for _, tt := range tests { - k, ctx, _, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + k, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidator(ctx, @@ -70,9 +83,143 @@ func TestValidatorConsensusKeyInUse(t *testing.T) { tt.setup(ctx, k) t.Run(tt.name, func(t *testing.T) { - if actual := providerkeeper.ValidatorConsensusKeyInUse(&k, ctx, newValidator.SDKStakingValidator().GetOperator()); actual != tt.expect { + if actual := k.ValidatorConsensusKeyInUse(ctx, newValidator.SDKStakingValidator().GetOperator()); 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) + }) + } +} diff --git a/x/ccv/provider/keeper/keeper.go b/x/ccv/provider/keeper/keeper.go index e9bb1d1bd0..cf2ba795d9 100644 --- a/x/ccv/provider/keeper/keeper.go +++ b/x/ccv/provider/keeper/keeper.go @@ -41,9 +41,9 @@ type Keeper struct { clientKeeper ccv.ClientKeeper stakingKeeper ccv.StakingKeeper slashingKeeper ccv.SlashingKeeper - evidenceKeeper ccv.EvidenceKeeper distributionKeeper ccv.DistributionKeeper bankKeeper ccv.BankKeeper + govKeeper ccv.GovKeeper feeCollectorName string } @@ -53,9 +53,9 @@ func NewKeeper( channelKeeper ccv.ChannelKeeper, portKeeper ccv.PortKeeper, connectionKeeper ccv.ConnectionKeeper, clientKeeper ccv.ClientKeeper, stakingKeeper ccv.StakingKeeper, slashingKeeper ccv.SlashingKeeper, - accountKeeper ccv.AccountKeeper, evidenceKeeper ccv.EvidenceKeeper, + accountKeeper ccv.AccountKeeper, distributionKeeper ccv.DistributionKeeper, bankKeeper ccv.BankKeeper, - feeCollectorName string, + govKeeper ccv.GovKeeper, feeCollectorName string, ) Keeper { // set KeyTable if it has not already been set if !paramSpace.HasKeyTable() { @@ -74,9 +74,9 @@ func NewKeeper( stakingKeeper: stakingKeeper, slashingKeeper: slashingKeeper, accountKeeper: accountKeeper, - evidenceKeeper: evidenceKeeper, distributionKeeper: distributionKeeper, bankKeeper: bankKeeper, + govKeeper: govKeeper, feeCollectorName: feeCollectorName, } @@ -109,9 +109,9 @@ func (k Keeper) mustValidateFields() { ccv.PanicIfZeroOrNil(k.clientKeeper, "clientKeeper") // 9 ccv.PanicIfZeroOrNil(k.stakingKeeper, "stakingKeeper") // 10 ccv.PanicIfZeroOrNil(k.slashingKeeper, "slashingKeeper") // 11 - ccv.PanicIfZeroOrNil(k.evidenceKeeper, "evidenceKeeper") // 12 - ccv.PanicIfZeroOrNil(k.distributionKeeper, "distributionKeeper") // 13 - ccv.PanicIfZeroOrNil(k.bankKeeper, "bankKeeper") // 14 + ccv.PanicIfZeroOrNil(k.distributionKeeper, "distributionKeeper") // 12 + ccv.PanicIfZeroOrNil(k.bankKeeper, "bankKeeper") // 13 + ccv.PanicIfZeroOrNil(k.govKeeper, "govKeeper") // 14 ccv.PanicIfZeroOrNil(k.feeCollectorName, "feeCollectorName") // 15 } @@ -178,6 +178,60 @@ func (k Keeper) DeleteChainToChannel(ctx sdk.Context, chainID string) { store.Delete(types.ChainToChannelKey(chainID)) } +// SetProposedConsumerChain stores a consumer chainId corresponding to a submitted consumer addition proposal +// This consumer chainId is deleted once the voting period for the proposal ends. +func (k Keeper) SetProposedConsumerChain(ctx sdk.Context, chainID string, proposalID uint64) { + store := ctx.KVStore(k.storeKey) + store.Set(types.ProposedConsumerChainKey(proposalID), []byte(chainID)) +} + +// GetProposedConsumerChain returns the proposed chainID for the given consumerAddition proposal ID. +func (k Keeper) GetProposedConsumerChain(ctx sdk.Context, proposalID uint64) string { + store := ctx.KVStore(k.storeKey) + return string(store.Get(types.ProposedConsumerChainKey(proposalID))) +} + +// DeleteProposedConsumerChainInStore deletes the consumer chainID from store +// which is in gov consumerAddition proposal +func (k Keeper) DeleteProposedConsumerChainInStore(ctx sdk.Context, proposalID uint64) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.ProposedConsumerChainKey(proposalID)) +} + +// GetAllProposedConsumerChainIDs 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}) + defer iterator.Close() + + proposedChains := []types.ProposedChain{} + for ; iterator.Valid(); iterator.Next() { + proposalID, err := types.ParseProposedConsumerChainKey(types.ProposedConsumerChainByteKey, iterator.Key()) + if err != nil { + panic(fmt.Errorf("proposed chains cannot be parsed: %w", err)) + } + + proposedChains = append(proposedChains, types.ProposedChain{ + ChainID: string(iterator.Value()), + ProposalID: proposalID, + }) + + } + + return proposedChains +} + +// GetAllPendingConsumerChainIDs gets pending consumer chains have not reach spawn time +func (k Keeper) GetAllPendingConsumerChainIDs(ctx sdk.Context) []string { + chainIDs := []string{} + props := k.GetAllPendingConsumerAdditionProps(ctx) + for _, prop := range props { + chainIDs = append(chainIDs, prop.ChainId) + } + + return chainIDs +} + // GetAllConsumerChains gets all of the consumer chains, for which the provider module // created IBC clients. Consumer chains with created clients are also referred to as registered. // @@ -299,7 +353,7 @@ func (k Keeper) VerifyConsumerChain(ctx sdk.Context, channelID string, connectio return errorsmod.Wrapf(ccv.ErrClientNotFound, "cannot find client for consumer chain %s", tmClient.ChainId) } if ccvClientId != clientID { - return errorsmod.Wrapf(ccv.ErrInvalidConsumerClient, "CCV channel must be built on top of CCV client. expected %s, got %s", ccvClientId, clientID) + return errorsmod.Wrapf(types.ErrInvalidConsumerClient, "CCV channel must be built on top of CCV client. expected %s, got %s", ccvClientId, clientID) } // Verify that there isn't already a CCV channel for the consumer chain @@ -1066,3 +1120,19 @@ func (k Keeper) GetSlashLog( func (k Keeper) BondDenom(ctx sdk.Context) string { return k.stakingKeeper.BondDenom(ctx) } + +func (k Keeper) GetAllRegisteredAndProposedChainIDs(ctx sdk.Context) []string { + allConsumerChains := []string{} + consumerChains := k.GetAllConsumerChains(ctx) + for _, consumerChain := range consumerChains { + allConsumerChains = append(allConsumerChains, consumerChain.ChainId) + } + proposedChains := k.GetAllProposedConsumerChainIDs(ctx) + for _, proposedChain := range proposedChains { + allConsumerChains = append(allConsumerChains, proposedChain.ChainID) + } + pendingChainIDs := k.GetAllPendingConsumerChainIDs(ctx) + allConsumerChains = append(allConsumerChains, pendingChainIDs...) + + return allConsumerChains +} diff --git a/x/ccv/provider/keeper/keeper_test.go b/x/ccv/provider/keeper/keeper_test.go index be3ef4001c..14c86fe775 100644 --- a/x/ccv/provider/keeper/keeper_test.go +++ b/x/ccv/provider/keeper/keeper_test.go @@ -533,3 +533,98 @@ func TestSetSlashLog(t *testing.T) { require.True(t, providerKeeper.GetSlashLog(ctx, addrWithDoubleSigns)) require.False(t, providerKeeper.GetSlashLog(ctx, addrWithoutDoubleSigns)) } + +func TestSetProposedConsumerChains(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + tests := []struct { + chainID string + proposalID uint64 + }{ + {chainID: "1", proposalID: 1}, + {chainID: "some other ID", proposalID: 12}, + {chainID: "some other other chain ID", proposalID: 123}, + {chainID: "", proposalID: 1234}, + } + + for _, test := range tests { + providerKeeper.SetProposedConsumerChain(ctx, test.chainID, test.proposalID) + cID := providerKeeper.GetProposedConsumerChain(ctx, test.proposalID) + require.Equal(t, cID, test.chainID) + } +} + +func TestDeleteProposedConsumerChainInStore(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + tests := []struct { + chainID string + proposalID uint64 + deleteProposalID uint64 + ok bool + }{ + {chainID: "1", proposalID: 1, deleteProposalID: 1, ok: true}, + {chainID: "", proposalID: 12, deleteProposalID: 12, ok: true}, + {chainID: "1", proposalID: 0, deleteProposalID: 1, ok: false}, + } + for _, test := range tests { + providerKeeper.SetProposedConsumerChain(ctx, test.chainID, test.proposalID) + providerKeeper.DeleteProposedConsumerChainInStore(ctx, test.deleteProposalID) + cID := providerKeeper.GetProposedConsumerChain(ctx, test.proposalID) + if test.ok { + require.Equal(t, cID, "") + } else { + require.Equal(t, cID, test.chainID) + } + } +} + +func TestGetAllProposedConsumerChainIDs(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + tests := [][]types.ProposedChain{ + {}, + { + { + ChainID: "1", + ProposalID: 1, + }, + }, + { + { + ChainID: "1", + ProposalID: 1, + }, + { + ChainID: "2", + ProposalID: 2, + }, + { + ChainID: "", + ProposalID: 3, + }, + }, + } + + for _, test := range tests { + for _, tc := range test { + providerKeeper.SetProposedConsumerChain(ctx, tc.ChainID, tc.ProposalID) + } + + chains := providerKeeper.GetAllProposedConsumerChainIDs(ctx) + + sort.Slice(chains, func(i, j int) bool { + return chains[i].ProposalID < chains[j].ProposalID + }) + sort.Slice(test, func(i, j int) bool { + return test[i].ProposalID < test[j].ProposalID + }) + require.Equal(t, chains, test) + + for _, tc := range test { + providerKeeper.DeleteProposedConsumerChainInStore(ctx, tc.ProposalID) + } + } +} diff --git a/x/ccv/provider/keeper/key_assignment.go b/x/ccv/provider/keeper/key_assignment.go index d440848bbf..46447790df 100644 --- a/x/ccv/provider/keeper/key_assignment.go +++ b/x/ccv/provider/keeper/key_assignment.go @@ -370,13 +370,22 @@ func (k Keeper) DeleteConsumerAddrsToPrune(ctx sdk.Context, chainID string, vscI } // AssignConsumerKey assigns the consumerKey to the validator with providerAddr -// on the consumer chain with ID chainID +// on the consumer chain with ID chainID, if it is either registered or currently +// voted on in a ConsumerAddition governance proposal func (k Keeper) AssignConsumerKey( ctx sdk.Context, chainID string, validator stakingtypes.Validator, consumerKey tmprotocrypto.PublicKey, ) error { + // check that the consumer chain is either registered or that + // a ConsumerAdditionProposal was submitted. + if !k.IsConsumerProposedOrRegistered(ctx, chainID) { + return errorsmod.Wrapf( + types.ErrUnknownConsumerChainId, chainID, + ) + } + consAddrTmp, err := ccvtypes.TMCryptoPublicKeyToConsAddr(consumerKey) if err != nil { return err @@ -390,15 +399,15 @@ func (k Keeper) AssignConsumerKey( providerAddr := types.NewProviderConsAddress(consAddrTmp) if existingVal, found := k.stakingKeeper.GetValidatorByConsAddr(ctx, consumerAddr.ToSdkConsAddr()); found { - // If there is a validator using the consumer key to validate on the provider - // we prevent assigning the consumer key, unless the validator is assigning validator. - // This ensures that a validator joining the active set who has not explicitly assigned - // a consumer key, will be able to use their provider key as consumer key (as per default). + // 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 { return errorsmod.Wrapf( types.ErrConsumerKeyInUse, "a different validator already uses the consumer key", ) } + // We prevent a validator from assigning the default provider key as a consumer key + // if it has not already assigned a different consumer key _, found := k.GetValidatorConsumerPubKey(ctx, chainID, providerAddr) if !found { return errorsmod.Wrapf( @@ -629,3 +638,47 @@ func (k Keeper) DeleteKeyAssignments(ctx sdk.Context, chainID string) { k.DeleteConsumerAddrsToPrune(ctx, chainID, consumerAddrsToPrune.VscId) } } + +// IsConsumerProposedOrRegistered checks if a consumer chain is either registered, meaning either already running +// or will run soon, or proposed its ConsumerAdditionProposal was submitted but the chain was not yet added to ICS yet. +func (k Keeper) IsConsumerProposedOrRegistered(ctx sdk.Context, chainID string) bool { + allConsumerChains := k.GetAllRegisteredAndProposedChainIDs(ctx) + for _, c := range allConsumerChains { + if c == chainID { + return true + } + } + + return false +} + +// ValidatorConsensusKeyInUse checks if the given consensus key is already +// used by validator in a consumer chain. +// Note that this method is called when a new validator is created in the x/staking module of cosmos-sdk. +// 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 { + // Abort TX, do NOT allow validator to be created + panic("did not find newly created validator in staking module") + } + + // Get the consensus address of the validator being added + consensusAddr, err := val.GetConsAddr() + if err != nil { + // Abort TX, do NOT allow validator to be created + panic("could not get validator cons addr ") + } + + allConsumerChains := k.GetAllRegisteredAndProposedChainIDs(ctx) + for _, c := range allConsumerChains { + if _, exist := k.GetValidatorByConsumerAddr(ctx, + c, + types.NewConsumerConsAddress(consensusAddr), + ); exist { + return true + } + } + return false +} diff --git a/x/ccv/provider/keeper/key_assignment_test.go b/x/ccv/provider/keeper/key_assignment_test.go index e9cb1dd646..0009680864 100644 --- a/x/ccv/provider/keeper/key_assignment_test.go +++ b/x/ccv/provider/keeper/key_assignment_test.go @@ -389,17 +389,32 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { doActions func(sdk.Context, providerkeeper.Keeper) }{ /* - 0. Consumer registered: Assign PK0->CK0 and retrieve PK0->CK0 - 1. Consumer registered: Assign PK0->CK0, PK0->CK1 and retrieve PK0->CK1 - 2. Consumer registered: Assign PK0->CK0, PK1->CK0 and error - 3. Consumer registered: Assign PK1->PK0 and error - 4. Consumer not registered: Assign PK0->CK0 and retrieve PK0->CK0 - 5. Consumer not registered: Assign PK0->CK0, PK0->CK1 and retrieve PK0->CK1 - 6. Consumer not registered: Assign PK0->CK0, PK1->CK0 and error - 7. Consumer not registered: Assign PK1->PK0 and error + 0. Consumer not registered: Assign PK0->CK0 and error + 1. Consumer registered: Assign PK0->CK0 and retrieve PK0->CK0 + 2. Consumer registered: Assign PK0->CK0, PK0->CK1 and retrieve PK0->CK1 + 3. Consumer registered: Assign PK0->CK0, PK1->CK0 and error + 4. Consumer registered: Assign PK1->PK0 and error + 5. Consumer proposed: Assign Assign PK0->CK0 and retrieve PK0->CK0 + 6. Consumer proposed: Assign PK0->CK0, PK0->CK1 and retrieve PK0->CK1 + 7. Consumer proposed: Assign PK0->CK0, PK1->CK0 and error + 8. Consumer proposed: Assign PK1->PK0 and error */ { - name: "0", + name: "0", + mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) {}, + doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { + err := k.AssignConsumerKey(ctx, chainID, + providerIdentities[0].SDKStakingValidator(), + consumerIdentities[0].TMProtoCryptoPublicKey(), + ) + require.Error(t, err) + _, found := k.GetValidatorByConsumerAddr(ctx, chainID, + consumerIdentities[0].ConsumerConsAddress()) + require.False(t, found) + }, + }, + { + name: "1", mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, @@ -424,7 +439,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { }, }, { - name: "1", + name: "2", mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, @@ -460,7 +475,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { }, }, { - name: "2", + name: "3", mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, @@ -493,7 +508,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { }, }, { - name: "3", + name: "4", mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, @@ -511,7 +526,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { }, }, { - name: "4", + name: "5", mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, @@ -520,6 +535,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { + k.SetProposedConsumerChain(ctx, chainID, 0) err := k.AssignConsumerKey(ctx, chainID, providerIdentities[0].SDKStakingValidator(), consumerIdentities[0].TMProtoCryptoPublicKey(), @@ -532,7 +548,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { }, }, { - name: "5", + name: "6", mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, @@ -544,6 +560,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { + k.SetProposedConsumerChain(ctx, chainID, 0) err := k.AssignConsumerKey(ctx, chainID, providerIdentities[0].SDKStakingValidator(), consumerIdentities[0].TMProtoCryptoPublicKey(), @@ -561,7 +578,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { }, }, { - name: "6", + name: "7", mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, @@ -573,6 +590,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { + k.SetProposedConsumerChain(ctx, chainID, 0) err := k.AssignConsumerKey(ctx, chainID, providerIdentities[0].SDKStakingValidator(), consumerIdentities[0].TMProtoCryptoPublicKey(), @@ -590,7 +608,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { }, }, { - name: "7", + name: "8", mockSetup: func(ctx sdk.Context, k providerkeeper.Keeper, mocks testkeeper.MockedKeepers) { gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, @@ -599,6 +617,7 @@ func TestAssignConsensusKeyForConsumerChain(t *testing.T) { ) }, doActions: func(ctx sdk.Context, k providerkeeper.Keeper) { + k.SetProposedConsumerChain(ctx, chainID, 0) err := k.AssignConsumerKey(ctx, chainID, providerIdentities[1].SDKStakingValidator(), providerIdentities[0].TMProtoCryptoPublicKey(), @@ -634,6 +653,10 @@ func TestCannotReassignDefaultKeyAssignment(t *testing.T) { providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() + providerKeeper.SetPendingConsumerAdditionProp(ctx, &types.ConsumerAdditionProposal{ + ChainId: "chain", + }) + // Mock that the validator is validating with the single key, as confirmed by provider's staking keeper gomock.InOrder( mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, diff --git a/x/ccv/provider/keeper/migration.go b/x/ccv/provider/keeper/migration.go new file mode 100644 index 0000000000..5d739c8bef --- /dev/null +++ b/x/ccv/provider/keeper/migration.go @@ -0,0 +1,138 @@ +package keeper + +import ( + "fmt" + + sdktypes "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + + providertypes "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" + ccvtypes "github.com/cosmos/interchain-security/v3/x/ccv/types" +) + +// Migrator is a struct for handling in-place store migrations. +type Migrator struct { + providerKeeper Keeper + paramSpace paramtypes.Subspace +} + +// NewMigrator returns a new Migrator. +func NewMigrator(providerKeeper Keeper, paramSpace paramtypes.Subspace) Migrator { + return Migrator{providerKeeper: providerKeeper, paramSpace: paramSpace} +} + +// Migrate2to3 migrates x/ccvprovider state from consensus version 2 to 3. +func (m Migrator) Migrate2to3(ctx sdktypes.Context) error { + return m.providerKeeper.MigrateQueuedPackets(ctx) +} + +func (k Keeper) MigrateQueuedPackets(ctx sdktypes.Context) error { + for _, consumer := range k.GetAllConsumerChains(ctx) { + slashData, vscmData := k.GetAllThrottledPacketData(ctx, consumer.ChainId) + 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.DeleteThrottledPacketDataForConsumer(ctx, consumer.ChainId) + } + return nil +} + +// Pending packet data type enum, used to encode the type of packet data stored at each entry in the mutual queue. +// Note this type is copy/pasted from throttle v1 code. +const ( + slashPacketData byte = iota + vscMaturedPacketData +) + +// GetAllThrottledPacketData returns all throttled packet data for a given consumer chain, only used for 2 -> 3 migration. +// Note this method is adapted from throttle v1 code. +func (k Keeper) GetAllThrottledPacketData(ctx sdktypes.Context, consumerChainID string) ( + slashData []ccvtypes.SlashPacketData, vscMaturedData []ccvtypes.VSCMaturedPacketData, +) { + slashData = []ccvtypes.SlashPacketData{} + vscMaturedData = []ccvtypes.VSCMaturedPacketData{} + + store := ctx.KVStore(k.storeKey) + iteratorPrefix := providertypes.ChainIdWithLenKey(providertypes.ThrottledPacketDataBytePrefix, consumerChainID) + iterator := sdktypes.KVStorePrefixIterator(store, iteratorPrefix) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + bz := iterator.Value() + switch bz[0] { + case slashPacketData: + d := ccvtypes.SlashPacketData{} + if err := d.Unmarshal(bz[1:]); err != nil { + k.Logger(ctx).Error(fmt.Sprintf("failed to unmarshal slash packet data: %v", err)) + continue + } + slashData = append(slashData, d) + case vscMaturedPacketData: + d := ccvtypes.VSCMaturedPacketData{} + if err := d.Unmarshal(bz[1:]); err != nil { + k.Logger(ctx).Error(fmt.Sprintf("failed to unmarshal vsc matured packet data: %v", err)) + continue + } + vscMaturedData = append(vscMaturedData, d) + default: + k.Logger(ctx).Error(fmt.Sprintf("invalid packet data type: %v", bz[0])) + continue + } + } + + return slashData, vscMaturedData +} + +// Note this method is copy/pasted from throttle v1 code. +func (k Keeper) DeleteThrottledPacketDataForConsumer(ctx sdktypes.Context, consumerChainID string) { + store := ctx.KVStore(k.storeKey) + iteratorPrefix := providertypes.ChainIdWithLenKey(providertypes.ThrottledPacketDataBytePrefix, consumerChainID) + iterator := sdktypes.KVStorePrefixIterator(store, iteratorPrefix) + defer iterator.Close() + + keysToDel := [][]byte{} + for ; iterator.Valid(); iterator.Next() { + keysToDel = append(keysToDel, iterator.Key()) + } + // Delete data for this consumer + for _, key := range keysToDel { + store.Delete(key) + } + + // Delete size of data queue for this consumer + store.Delete(providertypes.ThrottledPacketDataSizeKey(consumerChainID)) +} + +// Note this method is adapted from throttle v1 code. +func (k Keeper) QueueThrottledPacketDataOnlyForTesting( + ctx sdktypes.Context, consumerChainID string, ibcSeqNum uint64, packetData interface{}, +) error { + store := ctx.KVStore(k.storeKey) + + var bz []byte + var err error + switch data := packetData.(type) { + case ccvtypes.SlashPacketData: + bz, err = data.Marshal() + if err != nil { + return fmt.Errorf("failed to marshal slash packet data: %v", err) + } + bz = append([]byte{slashPacketData}, bz...) + case ccvtypes.VSCMaturedPacketData: + bz, err = data.Marshal() + if err != nil { + return fmt.Errorf("failed to marshal vsc matured packet data: %v", err) + } + bz = append([]byte{vscMaturedPacketData}, bz...) + default: + // Indicates a developer error, this method should only be called + // by tests, QueueThrottledSlashPacketData, or QueueThrottledVSCMaturedPacketData. + panic(fmt.Sprintf("unexpected packet data type: %T", data)) + } + + store.Set(providertypes.ThrottledPacketDataKey(consumerChainID, ibcSeqNum), bz) + return nil +} diff --git a/x/ccv/provider/keeper/migration_test.go b/x/ccv/provider/keeper/migration_test.go new file mode 100644 index 0000000000..a710e3979c --- /dev/null +++ b/x/ccv/provider/keeper/migration_test.go @@ -0,0 +1,117 @@ +package keeper_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + + testutil "github.com/cosmos/interchain-security/v3/testutil/keeper" +) + +func TestMigrate2To3(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testutil.GetProviderKeeperAndCtx(t, testutil.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + // Set consumer client ids to mock consumers being connected to provider + providerKeeper.SetConsumerClientId(ctx, "chain-1", "client-1") + providerKeeper.SetConsumerClientId(ctx, "chain-2", "client-2") + providerKeeper.SetConsumerClientId(ctx, "chain-3", "client-3") + + // Queue some data for chain-1 + providerKeeper.QueueThrottledPacketDataOnlyForTesting( + ctx, "chain-1", 66, testutil.GetNewSlashPacketData()) + providerKeeper.QueueThrottledPacketDataOnlyForTesting( + ctx, "chain-1", 67, testutil.GetNewVSCMaturedPacketData()) + providerKeeper.QueueThrottledPacketDataOnlyForTesting( + ctx, "chain-1", 68, testutil.GetNewSlashPacketData()) + providerKeeper.QueueThrottledPacketDataOnlyForTesting( + ctx, "chain-1", 69, testutil.GetNewVSCMaturedPacketData()) + + // Queue some data for chain-2 + providerKeeper.QueueThrottledPacketDataOnlyForTesting( + ctx, "chain-2", 789, testutil.GetNewVSCMaturedPacketData()) + providerKeeper.QueueThrottledPacketDataOnlyForTesting( + ctx, "chain-2", 790, testutil.GetNewSlashPacketData()) + providerKeeper.QueueThrottledPacketDataOnlyForTesting( + ctx, "chain-2", 791, testutil.GetNewVSCMaturedPacketData()) + + // Queue some data for chain-3 + providerKeeper.QueueThrottledPacketDataOnlyForTesting( + ctx, "chain-3", 123, testutil.GetNewSlashPacketData()) + providerKeeper.QueueThrottledPacketDataOnlyForTesting( + ctx, "chain-3", 124, testutil.GetNewVSCMaturedPacketData()) + providerKeeper.QueueThrottledPacketDataOnlyForTesting( + ctx, "chain-3", 125, testutil.GetNewVSCMaturedPacketData()) + + // Confirm getter methods return expected values + slash1, vscm1 := providerKeeper.GetAllThrottledPacketData(ctx, "chain-1") + require.Len(t, slash1, 2) + require.Len(t, vscm1, 2) + + slash2, vscm2 := providerKeeper.GetAllThrottledPacketData(ctx, "chain-2") + require.Len(t, slash2, 1) + require.Len(t, vscm2, 2) + + slash3, vscm3 := providerKeeper.GetAllThrottledPacketData(ctx, "chain-3") + require.Len(t, slash3, 1) + require.Len(t, vscm3, 2) + + // Set vsc send timestamp for every queued vsc matured packet, + // as a way to assert that the vsc matured packets are handled in the migration. + // + // That is, timestamp should exist before a vsc matured packet is handled, + // and deleted after handling. + for _, data := range vscm1 { + providerKeeper.SetVscSendTimestamp(ctx, "chain-1", data.ValsetUpdateId, time.Now()) + } + for _, data := range vscm2 { + providerKeeper.SetVscSendTimestamp(ctx, "chain-2", data.ValsetUpdateId, time.Now()) + } + for _, data := range vscm3 { + providerKeeper.SetVscSendTimestamp(ctx, "chain-3", data.ValsetUpdateId, time.Now()) + } + + // Confirm timestamps are set + for _, data := range vscm1 { + _, found := providerKeeper.GetVscSendTimestamp(ctx, "chain-1", data.ValsetUpdateId) + require.True(t, found) + } + for _, data := range vscm2 { + _, found := providerKeeper.GetVscSendTimestamp(ctx, "chain-2", data.ValsetUpdateId) + require.True(t, found) + } + for _, data := range vscm3 { + _, found := providerKeeper.GetVscSendTimestamp(ctx, "chain-3", data.ValsetUpdateId) + require.True(t, found) + } + + // Run migration + err := providerKeeper.MigrateQueuedPackets(ctx) + require.NoError(t, err) + + // Confirm throttled data is now deleted + slash1, vscm1 = providerKeeper.GetAllThrottledPacketData(ctx, "chain-1") + require.Empty(t, slash1) + require.Empty(t, vscm1) + slash2, vscm2 = providerKeeper.GetAllThrottledPacketData(ctx, "chain-2") + require.Empty(t, slash2) + require.Empty(t, vscm2) + slash3, vscm3 = providerKeeper.GetAllThrottledPacketData(ctx, "chain-3") + require.Empty(t, slash3) + require.Empty(t, vscm3) + + // Confirm timestamps are deleted, meaning vsc matured packets were handled + for _, data := range vscm1 { + _, found := providerKeeper.GetVscSendTimestamp(ctx, "chain-1", data.ValsetUpdateId) + require.False(t, found) + } + for _, data := range vscm2 { + _, found := providerKeeper.GetVscSendTimestamp(ctx, "chain-2", data.ValsetUpdateId) + require.False(t, found) + } + for _, data := range vscm3 { + _, found := providerKeeper.GetVscSendTimestamp(ctx, "chain-3", data.ValsetUpdateId) + require.False(t, found) + } +} diff --git a/x/ccv/provider/keeper/msg_server.go b/x/ccv/provider/keeper/msg_server.go index 2aa0fed46c..cd9b2c2c07 100644 --- a/x/ccv/provider/keeper/msg_server.go +++ b/x/ccv/provider/keeper/msg_server.go @@ -6,10 +6,12 @@ import ( errorsmod "cosmossdk.io/errors" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/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/v3/x/ccv/provider/types" ccvtypes "github.com/cosmos/interchain-security/v3/x/ccv/types" @@ -27,16 +29,11 @@ func NewMsgServerImpl(keeper *Keeper) types.MsgServer { var _ types.MsgServer = msgServer{} -// CreateValidator defines a method for creating a new validator +// 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) { ctx := sdk.UnwrapSDKContext(goCtx) - // It is possible to assign keys for consumer chains that are not yet approved. - // TODO: In future, a mechanism will be added to limit assigning keys to chains - // which are approved or pending approval, only. - // Note that current attack potential is restricted because validators must sign - // the transaction, and the chainID size is limited. - providerValidatorAddr, err := sdk.ValAddressFromBech32(msg.ProviderAddr) if err != nil { return nil, err @@ -100,11 +97,80 @@ func (k msgServer) AssignConsumerKey(goCtx context.Context, msg *types.MsgAssign ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( - ccvtypes.EventTypeAssignConsumerKey, - sdk.NewAttribute(ccvtypes.AttributeProviderValidatorAddress, msg.ProviderAddr), - sdk.NewAttribute(ccvtypes.AttributeConsumerConsensusPubKey, consumerTMPublicKey.String()), + types.EventTypeAssignConsumerKey, + sdk.NewAttribute(types.AttributeProviderValidatorAddress, msg.ProviderAddr), + sdk.NewAttribute(types.AttributeConsumerConsensusPubKey, consumerTMPublicKey.String()), ), }) return &types.MsgAssignConsumerKeyResponse{}, 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 { + return nil, err + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + ccvtypes.EventTypeSubmitConsumerMisbehaviour, + sdk.NewAttribute(ccvtypes.AttributeConsumerMisbehaviour, msg.Misbehaviour.String()), + sdk.NewAttribute(ccvtypes.AttributeSubmitterAddress, msg.Submitter), + sdk.NewAttribute(ccvtypes.AttributeMisbehaviourClientId, msg.Misbehaviour.ClientId), + sdk.NewAttribute(ccvtypes.AttributeMisbehaviourHeight1, msg.Misbehaviour.Header1.GetHeight().String()), + sdk.NewAttribute(ccvtypes.AttributeMisbehaviourHeight2, msg.Misbehaviour.Header2.GetHeight().String()), + ), + }) + + return &types.MsgSubmitConsumerMisbehaviourResponse{}, nil +} + +func (k msgServer) SubmitConsumerDoubleVoting(goCtx context.Context, msg *types.MsgSubmitConsumerDoubleVoting) (*types.MsgSubmitConsumerDoubleVotingResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + evidence, err := tmtypes.DuplicateVoteEvidenceFromProto(msg.DuplicateVoteEvidence) + if err != nil { + return nil, err + } + + // parse the validator set of the infraction block header in order + // to find the public key of the validator who double voted + + // get validator set + valset, err := tmtypes.ValidatorSetFromProto(msg.InfractionBlockHeader.ValidatorSet) + if err != nil { + return nil, err + } + + // look for the malicious validator in the validator set + _, validator := valset.GetByAddress(evidence.VoteA.ValidatorAddress) + if validator == nil { + return nil, errorsmod.Wrapf( + ccvtypes.ErrInvalidDoubleVotingEvidence, + "misbehaving validator %s cannot be found in the infraction block header validator set", + evidence.VoteA.ValidatorAddress) + } + + pubkey, err := cryptocodec.FromTmPubKeyInterface(validator.PubKey) + if err != nil { + return nil, err + } + + // handle the double voting evidence using the chain ID of the infraction block header + // and the malicious validator's public key + if err := k.Keeper.HandleConsumerDoubleVoting(ctx, evidence, msg.InfractionBlockHeader.Header.ChainID, pubkey); err != nil { + return nil, err + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + ccvtypes.EventTypeSubmitConsumerDoubleVoting, + sdk.NewAttribute(ccvtypes.AttributeConsumerDoubleVoting, msg.DuplicateVoteEvidence.String()), + sdk.NewAttribute(ccvtypes.AttributeChainID, msg.InfractionBlockHeader.Header.ChainID), + sdk.NewAttribute(ccvtypes.AttributeSubmitterAddress, msg.Submitter), + ), + }) + + return &types.MsgSubmitConsumerDoubleVotingResponse{}, nil +} diff --git a/x/ccv/provider/keeper/params.go b/x/ccv/provider/keeper/params.go index b7b53b245b..2dbe8ca40d 100644 --- a/x/ccv/provider/keeper/params.go +++ b/x/ccv/provider/keeper/params.go @@ -69,14 +69,6 @@ func (k Keeper) GetSlashMeterReplenishFraction(ctx sdk.Context) string { return f } -// GetMaxThrottledPackets returns the maximum amount of throttled slash or vsc matured packets -// that can be queued for a single consumer before the provider chain halts. -func (k Keeper) GetMaxThrottledPackets(ctx sdk.Context) int64 { - var p int64 - k.paramSpace.Get(ctx, types.KeyMaxThrottledPackets, &p) - return p -} - 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 @@ -96,7 +88,6 @@ func (k Keeper) GetParams(ctx sdk.Context) types.Params { k.GetVscTimeoutPeriod(ctx), k.GetSlashMeterReplenishPeriod(ctx), k.GetSlashMeterReplenishFraction(ctx), - k.GetMaxThrottledPackets(ctx), k.GetConsumerRewardDenomRegistrationFee(ctx), ) } diff --git a/x/ccv/provider/keeper/params_test.go b/x/ccv/provider/keeper/params_test.go index 05b3964bb7..c057079e59 100644 --- a/x/ccv/provider/keeper/params_test.go +++ b/x/ccv/provider/keeper/params_test.go @@ -44,7 +44,6 @@ func TestParams(t *testing.T) { 10*time.Minute, time.Hour, "0.4", - 100, sdk.Coin{ Denom: "stake", Amount: sdk.NewInt(10000000), diff --git a/x/ccv/provider/keeper/proposal.go b/x/ccv/provider/keeper/proposal.go index 7ea7433770..395d372517 100644 --- a/x/ccv/provider/keeper/proposal.go +++ b/x/ccv/provider/keeper/proposal.go @@ -56,7 +56,7 @@ func (k Keeper) CreateConsumerClient(ctx sdk.Context, prop *types.ConsumerAdditi chainID := prop.ChainId // check that a client for this chain does not exist if _, found := k.GetConsumerClientId(ctx, chainID); found { - return errorsmod.Wrap(ccv.ErrDuplicateConsumerChain, + return errorsmod.Wrap(types.ErrDuplicateConsumerChain, fmt.Sprintf("cannot create client for existent consumer chain: %s", chainID)) } @@ -108,14 +108,14 @@ func (k Keeper) CreateConsumerClient(ctx sdk.Context, prop *types.ConsumerAdditi ctx.EventManager().EmitEvent( sdk.NewEvent( - ccv.EventTypeConsumerClientCreated, + types.EventTypeConsumerClientCreated, sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), sdk.NewAttribute(ccv.AttributeChainID, chainID), sdk.NewAttribute(clienttypes.AttributeKeyClientID, clientID), - sdk.NewAttribute(ccv.AttributeInitialHeight, prop.InitialHeight.String()), - sdk.NewAttribute(ccv.AttributeInitializationTimeout, strconv.Itoa(int(ts.UnixNano()))), - sdk.NewAttribute(ccv.AttributeTrustingPeriod, clientState.TrustingPeriod.String()), - sdk.NewAttribute(ccv.AttributeUnbondingPeriod, clientState.UnbondingPeriod.String()), + sdk.NewAttribute(types.AttributeInitialHeight, prop.InitialHeight.String()), + sdk.NewAttribute(types.AttributeInitializationTimeout, strconv.Itoa(int(ts.UnixNano()))), + sdk.NewAttribute(types.AttributeTrustingPeriod, clientState.TrustingPeriod.String()), + sdk.NewAttribute(types.AttributeUnbondingPeriod, clientState.UnbondingPeriod.String()), ), ) @@ -155,7 +155,7 @@ func (k Keeper) HandleConsumerRemovalProposal(ctx sdk.Context, p *types.Consumer func (k Keeper) StopConsumerChain(ctx sdk.Context, chainID string, closeChan bool) (err error) { // check that a client for chainID exists if _, found := k.GetConsumerClientId(ctx, chainID); !found { - return errorsmod.Wrap(ccv.ErrConsumerChainNotFound, + return errorsmod.Wrap(types.ErrConsumerChainNotFound, fmt.Sprintf("cannot stop non-existent consumer chain: %s", chainID)) } @@ -214,21 +214,6 @@ func (k Keeper) StopConsumerChain(ctx sdk.Context, chainID string, closeChan boo k.DeleteUnbondingOpIndex(ctx, chainID, unbondingOpsIndex.VscId) } - // Remove any existing throttling related entries from the global queue, - // only for this consumer. - // Note: this call panics if the throttling state is invalid - k.DeleteGlobalSlashEntriesForConsumer(ctx, chainID) - - if k.GetThrottledPacketDataSize(ctx, chainID) > 0 { - k.Logger(ctx).Info("There are throttled slash and/or vsc matured packet data instances queued,"+ - " from a consumer that is being removed. This packet data will be thrown out!", "chainID", chainID) - } - - // Remove all throttled slash packets and vsc matured packets queued for this consumer. - // Note: queued VSC matured packets can be safely removed from the per-chain queue, - // since all unbonding operations for this consumer are release above. - k.DeleteThrottledPacketDataForConsumer(ctx, chainID) - k.Logger(ctx).Info("consumer chain removed from provider", "chainID", chainID) return nil @@ -314,6 +299,7 @@ func (k Keeper) MakeConsumerGenesis( "0.05", []string{}, []string{}, + ccv.DefaultRetryDelayPeriod, ) gen = *ccv.NewInitialConsumerGenesisState( @@ -605,18 +591,6 @@ func (k Keeper) StopConsumerChainInCachedCtx(ctx sdk.Context, p types.ConsumerRe return } -// HandleEquivocationProposal handles an equivocation proposal. -// Proposal will be accepted if a record in the SlashLog exists for a given validator address. -func (k Keeper) HandleEquivocationProposal(ctx sdk.Context, p *types.EquivocationProposal) error { - for _, ev := range p.Equivocations { - if !k.GetSlashLog(ctx, types.NewProviderConsAddress(ev.GetConsensusAddress())) { - return fmt.Errorf("no equivocation record found for validator %s", ev.GetConsensusAddress().String()) - } - k.evidenceKeeper.HandleEquivocationEvidence(ctx, ev) - } - return nil -} - 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 @@ -626,8 +600,8 @@ func (k Keeper) HandleConsumerRewardDenomProposal(ctx sdk.Context, p *types.Chan } k.SetConsumerRewardDenom(ctx, denomToAdd) ctx.EventManager().EmitEvent(sdk.NewEvent( - ccv.EventTypeAddConsumerRewardDenom, - sdk.NewAttribute(ccv.AttributeConsumerRewardDenom, denomToAdd), + types.EventTypeAddConsumerRewardDenom, + sdk.NewAttribute(types.AttributeConsumerRewardDenom, denomToAdd), )) } for _, denomToRemove := range p.DenomsToRemove { @@ -638,8 +612,8 @@ func (k Keeper) HandleConsumerRewardDenomProposal(ctx sdk.Context, p *types.Chan } k.DeleteConsumerRewardDenom(ctx, denomToRemove) ctx.EventManager().EmitEvent(sdk.NewEvent( - ccv.EventTypeRemoveConsumerRewardDenom, - sdk.NewAttribute(ccv.AttributeConsumerRewardDenom, denomToRemove), + 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 135e16eaae..a5f0e6d536 100644 --- a/x/ccv/provider/keeper/proposal_test.go +++ b/x/ccv/provider/keeper/proposal_test.go @@ -14,11 +14,9 @@ import ( "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" abci "github.com/cometbft/cometbft/abci/types" - cryptoutil "github.com/cosmos/interchain-security/v3/testutil/crypto" testkeeper "github.com/cosmos/interchain-security/v3/testutil/keeper" providerkeeper "github.com/cosmos/interchain-security/v3/x/ccv/provider/keeper" providertypes "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" @@ -232,6 +230,7 @@ func TestPendingConsumerAdditionPropDeletion(t *testing.T) { defer ctrl.Finish() for _, tc := range testCases { + tc := tc providerKeeper.SetPendingConsumerAdditionProp(ctx, &tc.ConsumerAdditionProposal) } @@ -525,28 +524,6 @@ func TestStopConsumerChain(t *testing.T) { }, expErr: true, }, - { - description: "valid stop of consumer chain, throttle related queues are cleaned", - setup: func(ctx sdk.Context, providerKeeper *providerkeeper.Keeper, mocks testkeeper.MockedKeepers) { - testkeeper.SetupForStoppingConsumerChain(t, ctx, providerKeeper, mocks) - - // assert mocks for expected calls to `StopConsumerChain` when closing the underlying channel - gomock.InOrder(testkeeper.GetMocksForStopConsumerChainWithCloseChannel(ctx, &mocks)...) - - providerKeeper.QueueGlobalSlashEntry(ctx, providertypes.NewGlobalSlashEntry( - ctx.BlockTime(), "chainID", 1, cryptoutil.NewCryptoIdentityFromIntSeed(90).ProviderConsAddress())) - - err := providerKeeper.QueueThrottledSlashPacketData(ctx, "chainID", 1, testkeeper.GetNewSlashPacketData()) - if err != nil { - t.Fatal(err) - } - err = providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "chainID", 2, testkeeper.GetNewVSCMaturedPacketData()) - if err != nil { - t.Fatal(err) - } - }, - expErr: false, - }, { description: "valid stop of consumer chain, all mock calls hit", setup: func(ctx sdk.Context, providerKeeper *providerkeeper.Keeper, mocks testkeeper.MockedKeepers) { @@ -603,6 +580,7 @@ func TestPendingConsumerRemovalPropDeletion(t *testing.T) { defer ctrl.Finish() for _, tc := range testCases { + tc := tc providerKeeper.SetPendingConsumerRemovalProp(ctx, &tc.ConsumerRemovalProposal) } @@ -793,7 +771,6 @@ func TestMakeConsumerGenesis(t *testing.T) { VscTimeoutPeriod: providertypes.DefaultVscTimeoutPeriod, SlashMeterReplenishPeriod: providertypes.DefaultSlashMeterReplenishPeriod, SlashMeterReplenishFraction: providertypes.DefaultSlashMeterReplenishFraction, - MaxThrottledPackets: providertypes.DefaultMaxThrottledPackets, ConsumerRewardDenomRegistrationFee: sdk.Coin{ Denom: "stake", Amount: sdk.NewInt(1000000), @@ -836,75 +813,77 @@ func TestMakeConsumerGenesis(t *testing.T) { "unbonding_period": 1728000000000000, "soft_opt_out_threshold": "0.05", "reward_denoms": [], - "provider_reward_denoms": [] + "provider_reward_denoms": [], + "retry_delay_period": 3600000000000 }, "new_chain": true, - "provider_client_state": { - "chain_id": "testchain1", - "trust_level": { - "numerator": 1, - "denominator": 3 - }, - "trusting_period": 1197504000000000, - "unbonding_period": 1814400000000000, - "max_clock_drift": 10000000000, - "frozen_height": {}, - "latest_height": { - "revision_height": 5 - }, - "proof_specs": [ - { - "leaf_spec": { - "hash": 1, - "prehash_value": 1, - "length": 1, - "prefix": "AA==" + "provider" : { + "client_state": { + "chain_id": "testchain1", + "trust_level": { + "numerator": 1, + "denominator": 3 + }, + "trusting_period": 1197504000000000, + "unbonding_period": 1814400000000000, + "max_clock_drift": 10000000000, + "frozen_height": {}, + "latest_height": { + "revision_height": 5 + }, + "proof_specs": [ + { + "leaf_spec": { + "hash": 1, + "prehash_value": 1, + "length": 1, + "prefix": "AA==" + }, + "inner_spec": { + "child_order": [0, 1], + "child_size": 33, + "min_prefix_length": 4, + "max_prefix_length": 12, + "hash": 1 + } }, - "inner_spec": { - "child_order": [0, 1], - "child_size": 33, - "min_prefix_length": 4, - "max_prefix_length": 12, - "hash": 1 + { + "leaf_spec": { + "hash": 1, + "prehash_value": 1, + "length": 1, + "prefix": "AA==" + }, + "inner_spec": { + "child_order": [0, 1], + "child_size": 32, + "min_prefix_length": 1, + "max_prefix_length": 1, + "hash": 1 + } } + ], + "upgrade_path": ["upgrade", "upgradedIBCState"], + "allow_update_after_expiry": true, + "allow_update_after_misbehaviour": true + }, + "consensus_state": { + "timestamp": "2020-01-02T00:00:10Z", + "root": { + "hash": "LpGpeyQVLUo9HpdsgJr12NP2eCICspcULiWa5u9udOA=" }, + "next_validators_hash": "E30CE736441FB9101FADDAF7E578ABBE6DFDB67207112350A9A904D554E1F5BE" + }, + "initial_val_set": [ { - "leaf_spec": { - "hash": 1, - "prehash_value": 1, - "length": 1, - "prefix": "AA==" + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "dcASx5/LIKZqagJWN0frOlFtcvz91frYmj/zmoZRWro=" }, - "inner_spec": { - "child_order": [0, 1], - "child_size": 32, - "min_prefix_length": 1, - "max_prefix_length": 1, - "hash": 1 - } + "power": 1 } - ], - "upgrade_path": ["upgrade", "upgradedIBCState"], - "allow_update_after_expiry": true, - "allow_update_after_misbehaviour": true - }, - "provider_consensus_state": { - "timestamp": "2020-01-02T00:00:10Z", - "root": { - "hash": "LpGpeyQVLUo9HpdsgJr12NP2eCICspcULiWa5u9udOA=" - }, - "next_validators_hash": "E30CE736441FB9101FADDAF7E578ABBE6DFDB67207112350A9A904D554E1F5BE" - }, - "unbonding_sequences": null, - "initial_val_set": [ - { - "pub_key": { - "type": "tendermint/PubKeyEd25519", - "value": "dcASx5/LIKZqagJWN0frOlFtcvz91frYmj/zmoZRWro=" - }, - "power": 1 - } - ] + ] + } }` var expectedGenesis ccvtypes.ConsumerGenesisState @@ -912,10 +891,10 @@ func TestMakeConsumerGenesis(t *testing.T) { require.NoError(t, err) // Zeroing out different fields that are challenging to mock - actualGenesis.InitialValSet = []abci.ValidatorUpdate{} - expectedGenesis.InitialValSet = []abci.ValidatorUpdate{} - actualGenesis.ProviderConsensusState = &ibctmtypes.ConsensusState{} - expectedGenesis.ProviderConsensusState = &ibctmtypes.ConsensusState{} + actualGenesis.Provider.InitialValSet = []abci.ValidatorUpdate{} + expectedGenesis.Provider.InitialValSet = []abci.ValidatorUpdate{} + actualGenesis.Provider.ConsensusState = &ibctmtypes.ConsensusState{} + expectedGenesis.Provider.ConsensusState = &ibctmtypes.ConsensusState{} require.Equal(t, expectedGenesis, actualGenesis, "consumer chain genesis created incorrectly") } @@ -1094,63 +1073,3 @@ func TestBeginBlockCCR(t *testing.T) { ctx, invalidProp.ChainId, invalidProp.StopTime) require.False(t, found) } - -func TestHandleEquivocationProposal(t *testing.T) { - equivocations := []*evidencetypes.Equivocation{ - { - Time: time.Now(), - Height: 1, - Power: 1, - ConsensusAddress: "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk", - }, - { - Time: time.Now(), - Height: 1, - Power: 1, - ConsensusAddress: "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6", - }, - } - - prop := &providertypes.EquivocationProposal{ - Equivocations: []*evidencetypes.Equivocation{equivocations[0], equivocations[1]}, - } - - testCases := []struct { - name string - setSlashLogs bool - expectEquivsHandled bool - expectErr bool - }{ - {name: "slash logs not set", setSlashLogs: false, expectEquivsHandled: false, expectErr: true}, - {name: "slash logs set", setSlashLogs: true, expectEquivsHandled: true, expectErr: false}, - } - for _, tc := range testCases { - - keeperParams := testkeeper.NewInMemKeeperParams(t) - keeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, keeperParams) - - if tc.setSlashLogs { - // Set slash logs according to cons addrs in equivocations - consAddr := equivocations[0].GetConsensusAddress() - require.NotNil(t, consAddr, "consensus address could not be parsed") - keeper.SetSlashLog(ctx, providertypes.NewProviderConsAddress(consAddr)) - consAddr = equivocations[1].GetConsensusAddress() - require.NotNil(t, consAddr, "consensus address could not be parsed") - keeper.SetSlashLog(ctx, providertypes.NewProviderConsAddress(consAddr)) - } - - if tc.expectEquivsHandled { - mocks.MockEvidenceKeeper.EXPECT().HandleEquivocationEvidence(ctx, equivocations[0]) - mocks.MockEvidenceKeeper.EXPECT().HandleEquivocationEvidence(ctx, equivocations[1]) - } - - err := keeper.HandleEquivocationProposal(ctx, prop) - - if tc.expectErr { - require.Error(t, err) - } else { - require.NoError(t, err) - } - ctrl.Finish() - } -} diff --git a/x/ccv/provider/keeper/relay.go b/x/ccv/provider/keeper/relay.go index d63594dad1..0cbce718a7 100644 --- a/x/ccv/provider/keeper/relay.go +++ b/x/ccv/provider/keeper/relay.go @@ -17,7 +17,7 @@ import ( ccv "github.com/cosmos/interchain-security/v3/x/ccv/types" ) -// OnRecvVSCMaturedPacket handles a VSCMatured packet +// OnRecvVSCMaturedPacket handles a VSCMatured packet and returns a no-op result ack. func (k Keeper) OnRecvVSCMaturedPacket( ctx sdk.Context, packet channeltypes.Packet, @@ -34,12 +34,9 @@ func (k Keeper) OnRecvVSCMaturedPacket( panic(fmt.Errorf("VSCMaturedPacket received on unknown channel %s", packet.DestinationChannel)) } - if err := k.QueueThrottledVSCMaturedPacketData(ctx, chainID, packet.Sequence, data); err != nil { - return ccv.NewErrorAcknowledgementWithLog(ctx, fmt.Errorf( - "failed to queue VSCMatured packet data: %s", err.Error())) - } + k.HandleVSCMaturedPacket(ctx, chainID, data) - k.Logger(ctx).Info("VSCMaturedPacket received and enqueued", + k.Logger(ctx).Info("VSCMaturedPacket handled", "chainID", chainID, "vscID", data.ValsetUpdateId, ) @@ -48,35 +45,6 @@ func (k Keeper) OnRecvVSCMaturedPacket( return ack } -// HandleLeadingVSCMaturedPackets handles all VSCMatured packet data that has been queued this block, -// but does not need to be throttled. The handled data is then removed from the queue. -// -// Note: VSC matured packet data which is queued behind slash packet data CANNOT be -// handled until the leading slash packet data has been handled. This is to maintain -// the "VSC Maturity and Slashing Order" CCV property. If VSC matured packet data DOES NOT -// trail slash packet data for that consumer, it will be handled in this method, -// bypassing HandleThrottleQueues. -func (k Keeper) HandleLeadingVSCMaturedPackets(ctx sdk.Context) (vscMaturedHandledThisBlock int) { - vscMaturedHandledThisBlock = 0 - for _, chain := range k.GetAllConsumerChains(ctx) { - // Note: it's assumed the order of the vsc matured slice matches the order of the ibc seq nums slice, - // in that a vsc matured packet data at index i is associated with the ibc seq num at index i. - leadingVscMatured, ibcSeqNums := k.GetLeadingVSCMaturedData(ctx, chain.ChainId) - ibcSeqNumsHandled := []uint64{} - for idx, data := range leadingVscMatured { - if vscMaturedHandledThisBlock >= vscMaturedHandledPerBlockLimit { - // Break from inner for-loop, DeleteThrottledPacketData will still be called for this consumer - break - } - k.HandleVSCMaturedPacket(ctx, chain.ChainId, data) - vscMaturedHandledThisBlock++ - ibcSeqNumsHandled = append(ibcSeqNumsHandled, ibcSeqNums[idx]) - } - k.DeleteThrottledPacketData(ctx, chain.ChainId, ibcSeqNumsHandled...) - } - return vscMaturedHandledThisBlock -} - // HandleVSCMaturedPacket handles a VSCMatured packet. // // Note: This method should only panic for a system critical error like a @@ -270,18 +238,10 @@ func (k Keeper) QueueVSCPackets(ctx sdk.Context) { k.IncrementValidatorSetUpdateId(ctx) } -// EndBlockCIS contains the EndBlock logic needed for -// the Consumer Initiated Slashing sub-protocol -func (k Keeper) EndBlockCIS(ctx sdk.Context) { - // set the ValsetUpdateBlockHeight - blockHeight := uint64(ctx.BlockHeight()) + 1 - valUpdateID := k.GetValidatorSetUpdateId(ctx) - k.SetValsetUpdateBlockHeight(ctx, valUpdateID, blockHeight) - k.Logger(ctx).Debug("vscID was mapped to block height", "vscID", valUpdateID, "height", blockHeight) - - // Replenish slash meter if necessary, BEFORE executing slash packet throttling logic. - // This ensures the meter value is replenished, and not greater than the allowance (max value) - // for the block, before the throttling logic is executed. +// BeginBlockCIS contains the BeginBlock logic needed for the Consumer Initiated Slashing sub-protocol. +func (k Keeper) BeginBlockCIS(ctx sdk.Context) { + // Replenish slash meter if necessary. This ensures the meter value is replenished before handling any slash packets, + // and ensures the meter value is not greater than the allowance (max value) for the block. // // Note: CheckForSlashMeterReplenishment contains panics for the following scenarios, any of which should never occur // if the protocol is correct and external data is properly validated: @@ -291,23 +251,16 @@ func (k Keeper) EndBlockCIS(ctx sdk.Context) { // - Marshaling and/or store corruption errors. // - Setting invalid slash meter values (see SetSlashMeter). k.CheckForSlashMeterReplenishment(ctx) +} - // Handle leading vsc matured packets before throttling logic. - // - // Note: HandleLeadingVSCMaturedPackets contains panics for the following scenarios, any of which should never occur - // if the protocol is correct and external data is properly validated: - // - // - Marshaling and/or store corruption errors. - vscMaturedHandledThisBlock := k.HandleLeadingVSCMaturedPackets(ctx) - // Handle queue entries considering throttling logic. - // - // Note: HandleThrottleQueues contains panics for the following scenarios, any of which should never occur - // if the protocol is correct and external data is properly validated: - // - // - SlashMeter has not been set (which should be set in InitGenesis, see InitializeSlashMeter). - // - Marshaling and/or store corruption errors. - // - Setting invalid slash meter values (see SetSlashMeter). - k.HandleThrottleQueues(ctx, vscMaturedHandledThisBlock) +// EndBlockCIS contains the EndBlock logic needed for +// the Consumer Initiated Slashing sub-protocol +func (k Keeper) EndBlockCIS(ctx sdk.Context) { + // set the ValsetUpdateBlockHeight + blockHeight := uint64(ctx.BlockHeight()) + 1 + valUpdateID := k.GetValidatorSetUpdateId(ctx) + k.SetValsetUpdateBlockHeight(ctx, valUpdateID, blockHeight) + k.Logger(ctx).Debug("vscID was mapped to block height", "vscID", valUpdateID, "height", blockHeight) } // OnRecvSlashPacket delivers a received slash packet, validates it and @@ -358,20 +311,27 @@ func (k Keeper) OnRecvSlashPacket(ctx sdk.Context, packet channeltypes.Packet, d return channeltypes.NewResultAcknowledgement(ccv.V1Result) } - // Queue a slash entry to the global queue, which will be seen by the throttling logic - k.QueueGlobalSlashEntry(ctx, providertypes.NewGlobalSlashEntry( - ctx.BlockTime(), // recv time - chainID, // consumer chain id that sent the packet - packet.Sequence, // IBC sequence number of the packet - providerConsAddr)) // Provider consensus address of val to be slashed - - // Queue slash packet data in the same (consumer chain specific) queue as vsc matured packet data, - // to enforce order of handling between the two packet data types. - if err := k.QueueThrottledSlashPacketData(ctx, chainID, packet.Sequence, data); err != nil { - return ccv.NewErrorAcknowledgementWithLog(ctx, fmt.Errorf("failed to queue slash packet data: %s", err.Error())) + meter := k.GetSlashMeter(ctx) + // Return bounce ack if meter is negative in value + if meter.IsNegative() { + k.Logger(ctx).Info("SlashPacket received, but meter is negative. Packet will be bounced", + "chainID", chainID, + "consumer cons addr", consumerConsAddr.String(), + "provider cons addr", providerConsAddr.String(), + "vscID", data.ValsetUpdateId, + "infractionType", data.Infraction, + ) + return channeltypes.NewResultAcknowledgement(ccv.SlashPacketBouncedResult) } - k.Logger(ctx).Info("slash packet received and enqueued", + // Subtract voting power that will be jailed/tombstoned from the slash meter, + // BEFORE handling slash packet. + meter = meter.Sub(k.GetEffectiveValPower(ctx, providerConsAddr)) + k.SetSlashMeter(ctx, meter) + + k.HandleSlashPacket(ctx, chainID, data) + + k.Logger(ctx).Info("slash packet received and handled", "chainID", chainID, "consumer cons addr", consumerConsAddr.String(), "provider cons addr", providerConsAddr.String(), @@ -379,7 +339,8 @@ func (k Keeper) OnRecvSlashPacket(ctx sdk.Context, packet channeltypes.Packet, d "infractionType", data.Infraction, ) - return channeltypes.NewResultAcknowledgement(ccv.V1Result) + // Return result ack that the packet was handled successfully + return channeltypes.NewResultAcknowledgement(ccv.SlashPacketHandledResult) } // ValidateSlashPacket validates a recv slash packet before it is @@ -465,11 +426,11 @@ func (k Keeper) HandleSlashPacket(ctx sdk.Context, chainID string, data ccv.Slas ctx.EventManager().EmitEvent( sdk.NewEvent( - ccv.EventTypeExecuteConsumerChainSlash, + providertypes.EventTypeExecuteConsumerChainSlash, sdk.NewAttribute(sdk.AttributeKeyModule, providertypes.ModuleName), sdk.NewAttribute(ccv.AttributeValidatorAddress, providerConsAddr.String()), sdk.NewAttribute(ccv.AttributeInfractionType, data.Infraction.String()), - sdk.NewAttribute(ccv.AttributeInfractionHeight, strconv.Itoa(int(infractionHeight))), + sdk.NewAttribute(providertypes.AttributeInfractionHeight, strconv.Itoa(int(infractionHeight))), sdk.NewAttribute(ccv.AttributeValSetUpdateID, strconv.Itoa(int(data.ValsetUpdateId))), ), ) @@ -491,7 +452,7 @@ func (k Keeper) EndBlockCCR(ctx sdk.Context) { "chainID", initTimeoutTimestamp.ChainId) err := k.StopConsumerChain(ctx, initTimeoutTimestamp.ChainId, false) if err != nil { - if ccv.ErrConsumerChainNotFound.Is(err) { + if providertypes.ErrConsumerChainNotFound.Is(err) { // consumer chain not found continue } @@ -518,7 +479,7 @@ func (k Keeper) EndBlockCCR(ctx sdk.Context) { ) err := k.StopConsumerChain(ctx, channelToChain.ChainId, true) if err != nil { - if ccv.ErrConsumerChainNotFound.Is(err) { + if providertypes.ErrConsumerChainNotFound.Is(err) { // consumer chain not found continue } diff --git a/x/ccv/provider/keeper/relay_test.go b/x/ccv/provider/keeper/relay_test.go index d3fdcaa21e..bc482d30a2 100644 --- a/x/ccv/provider/keeper/relay_test.go +++ b/x/ccv/provider/keeper/relay_test.go @@ -3,7 +3,6 @@ package keeper_test import ( "strings" "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" @@ -12,6 +11,8 @@ import ( "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" @@ -93,10 +94,8 @@ func TestQueueVSCPackets(t *testing.T) { } // TestOnRecvVSCMaturedPacket tests the OnRecvVSCMaturedPacket method of the keeper. -// Particularly the behavior that VSC matured packet data should be handled immediately -// if the pending packet data queue is empty, and should be queued otherwise. // -// Note: Handling logic itself is not testing in here, just queueing behavior. +// Note: Handling logic itself is not tested here. func TestOnRecvVSCMaturedPacket(t *testing.T) { providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() @@ -106,131 +105,69 @@ func TestOnRecvVSCMaturedPacket(t *testing.T) { providerKeeper.SetChannelToChain(ctx, "channel-1", "chain-1") providerKeeper.SetChannelToChain(ctx, "channel-2", "chain-2") - // Execute on recv for chain-1 + // Execute on recv for chain-1, confirm v1 result ack is returned ack := executeOnRecvVSCMaturedPacket(t, &providerKeeper, ctx, "channel-1", 1) require.Equal(t, channeltypes.NewResultAcknowledgement([]byte{byte(1)}), ack) - // Assert that the packet data was queued for chain-1 - require.Equal(t, uint64(1), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-1")) - - // chain-2 queue empty - require.Equal(t, uint64(0), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-2")) - - // Now queue a slash packet data instance for chain-2, then confirm the on recv method - // queues the vsc matured behind the slash packet data - err := providerKeeper.QueueThrottledSlashPacketData(ctx, "chain-2", 1, testkeeper.GetNewSlashPacketData()) - require.NoError(t, err) + // Now queue a slash packet data instance for chain-2, confirm v1 result ack is returned ack = executeOnRecvVSCMaturedPacket(t, &providerKeeper, ctx, "channel-2", 2) require.Equal(t, channeltypes.NewResultAcknowledgement([]byte{byte(1)}), ack) - require.Equal(t, uint64(2), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-2")) - - // Chain-1 still has 1 packet data queued - require.Equal(t, uint64(1), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-1")) - - // Receive 5 more vsc matured packets for chain-2, then confirm chain-2 queue size is 7, chain-1 still size 1 - for i := 0; i < 5; i++ { - ack = executeOnRecvVSCMaturedPacket(t, &providerKeeper, ctx, "channel-2", uint64(i+3)) - require.Equal(t, channeltypes.NewResultAcknowledgement([]byte{byte(1)}), ack) - } - require.Equal(t, uint64(7), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-2")) - require.Equal(t, uint64(1), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-1")) - - // Delete chain-2's data from its queue, then confirm the queue size is 0 - providerKeeper.DeleteThrottledPacketData(ctx, "chain-2", []uint64{1, 2, 3, 4, 5, 6, 7}...) - require.Equal(t, uint64(0), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-2")) } -func TestHandleLeadingVSCMaturedPackets(t *testing.T) { - providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) +// TestOnRecvDowntimeSlashPacket tests the OnRecvSlashPacket method specifically for downtime slash packets. +func TestOnRecvDowntimeSlashPacket(t *testing.T) { + providerKeeper, ctx, ctrl, mocks := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() providerKeeper.SetParams(ctx, providertypes.DefaultParams()) - vscData := getTenSampleVSCMaturedPacketData() - - // Set channel to chain, and chain to client mappings - // (faking multiple established consumer channels) + // Set channel to chain (faking multiple established channels) providerKeeper.SetChannelToChain(ctx, "channel-1", "chain-1") - providerKeeper.SetConsumerClientId(ctx, "chain-1", "client-1") providerKeeper.SetChannelToChain(ctx, "channel-2", "chain-2") - providerKeeper.SetConsumerClientId(ctx, "chain-2", "client-2") - // Queue some leading vsc matured packet data for chain-1 - err := providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "chain-1", 1, vscData[0]) - require.NoError(t, err) - err = providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "chain-1", 2, vscData[1]) - require.NoError(t, err) - err = providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "chain-1", 3, vscData[2]) - require.NoError(t, err) + // Generate a new slash packet data instance with double sign infraction type + packetData := testkeeper.GetNewSlashPacketData() + packetData.Infraction = stakingtypes.Infraction_INFRACTION_DOWNTIME - // Queue some trailing slash packet data (and a couple more vsc matured) - err = providerKeeper.QueueThrottledSlashPacketData(ctx, "chain-1", 4, testkeeper.GetNewSlashPacketData()) - require.NoError(t, err) - err = providerKeeper.QueueThrottledSlashPacketData(ctx, "chain-1", 5, testkeeper.GetNewSlashPacketData()) - require.NoError(t, err) - err = providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "chain-1", 6, vscData[3]) - require.NoError(t, err) - err = providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "chain-1", 7, vscData[4]) - require.NoError(t, err) + // Set a block height for the valset update id in the generated packet data + providerKeeper.SetValsetUpdateBlockHeight(ctx, packetData.ValsetUpdateId, uint64(15)) - // Queue some leading vsc matured packet data for chain-2 - err = providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "chain-2", 1, vscData[5]) - require.NoError(t, err) - err = providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "chain-2", 2, vscData[6]) - require.NoError(t, err) + // Set slash meter to negative value and assert a bounce ack is returned + providerKeeper.SetSlashMeter(ctx, math.NewInt(-5)) + ack := executeOnRecvSlashPacket(t, &providerKeeper, ctx, "channel-1", 1, packetData) + require.Equal(t, channeltypes.NewResultAcknowledgement(ccv.SlashPacketBouncedResult), ack) - // And trailing slash packet data for chain-2 - err = providerKeeper.QueueThrottledSlashPacketData(ctx, "chain-2", 3, testkeeper.GetNewSlashPacketData()) - require.NoError(t, err) - err = providerKeeper.QueueThrottledSlashPacketData(ctx, "chain-2", 4, testkeeper.GetNewSlashPacketData()) - require.NoError(t, err) + // Also bounced for chain-2 + ack = executeOnRecvSlashPacket(t, &providerKeeper, ctx, "channel-2", 2, packetData) + require.Equal(t, channeltypes.NewResultAcknowledgement(ccv.SlashPacketBouncedResult), ack) + + // Now set slash meter to positive value and assert slash packet handled result is returned + providerKeeper.SetSlashMeter(ctx, math.NewInt(5)) + + // Mock call to GetEffectiveValPower, so that it returns 2. + providerAddr := providertypes.NewProviderConsAddress(packetData.Validator.Address) + calls := []*gomock.Call{ + mocks.MockStakingKeeper.EXPECT().GetValidatorByConsAddr(ctx, providerAddr.ToSdkConsAddr()). + Return(stakingtypes.Validator{}, true).Times(1), + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(ctx, gomock.Any()). + Return(int64(2)).Times(1), + } - // And one more trailing vsc matured packet for chain-2 - err = providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "chain-2", 5, vscData[7]) - require.NoError(t, err) + // Add mocks for slash packet handling + calls = append(calls, + testkeeper.GetMocksForHandleSlashPacket( + ctx, mocks, providerAddr, stakingtypes.Validator{Jailed: false}, true)..., + ) + gomock.InOrder(calls...) - // Set VSC Send timestamps for each recv vsc matured packet - providerKeeper.SetVscSendTimestamp(ctx, "chain-1", vscData[0].ValsetUpdateId, time.Now()) - providerKeeper.SetVscSendTimestamp(ctx, "chain-1", vscData[1].ValsetUpdateId, time.Now()) - providerKeeper.SetVscSendTimestamp(ctx, "chain-1", vscData[2].ValsetUpdateId, time.Now()) - providerKeeper.SetVscSendTimestamp(ctx, "chain-1", vscData[3].ValsetUpdateId, time.Now()) - providerKeeper.SetVscSendTimestamp(ctx, "chain-1", vscData[4].ValsetUpdateId, time.Now()) - providerKeeper.SetVscSendTimestamp(ctx, "chain-2", vscData[5].ValsetUpdateId, time.Now()) - providerKeeper.SetVscSendTimestamp(ctx, "chain-2", vscData[6].ValsetUpdateId, time.Now()) - providerKeeper.SetVscSendTimestamp(ctx, "chain-2", vscData[7].ValsetUpdateId, time.Now()) - - // Confirm each chain-specific queue has the expected number of packet data instances - require.Equal(t, uint64(7), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-1")) - require.Equal(t, uint64(5), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-2")) - - // Handle leading vsc matured packets and confirm queue sizes change for both chains - providerKeeper.HandleLeadingVSCMaturedPackets(ctx) - require.Equal(t, uint64(4), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-1")) - require.Equal(t, uint64(3), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-2")) - - // Confirm the leading vsc matured packet data was handled for both chains, - // but not the vsc matured packet data that trails slash data in the queue. - // This assertion is made by checking that VSC Send timestamps were deleted for - // handled vsc matured packet data. - _, found := providerKeeper.GetVscSendTimestamp(ctx, "chain-1", vscData[0].ValsetUpdateId) - require.False(t, found) - _, found = providerKeeper.GetVscSendTimestamp(ctx, "chain-1", vscData[1].ValsetUpdateId) - require.False(t, found) - _, found = providerKeeper.GetVscSendTimestamp(ctx, "chain-1", vscData[2].ValsetUpdateId) - require.False(t, found) - _, found = providerKeeper.GetVscSendTimestamp(ctx, "chain-1", vscData[3].ValsetUpdateId) - require.True(t, found) - _, found = providerKeeper.GetVscSendTimestamp(ctx, "chain-1", vscData[4].ValsetUpdateId) - require.True(t, found) + // Execute on recv and confirm slash packet handled result is returned + ack = executeOnRecvSlashPacket(t, &providerKeeper, ctx, "channel-1", 1, packetData) + require.Equal(t, channeltypes.NewResultAcknowledgement(ccv.SlashPacketHandledResult), ack) - _, found = providerKeeper.GetVscSendTimestamp(ctx, "chain-2", vscData[5].ValsetUpdateId) - require.False(t, found) - _, found = providerKeeper.GetVscSendTimestamp(ctx, "chain-2", vscData[6].ValsetUpdateId) - require.False(t, found) - _, found = providerKeeper.GetVscSendTimestamp(ctx, "chain-2", vscData[7].ValsetUpdateId) - require.True(t, found) + // Require slash meter was decremented appropriately, 5-2=3 + require.Equal(t, int64(3), providerKeeper.GetSlashMeter(ctx).Int64()) } -// TestOnRecvSlashPacket tests the OnRecvSlashPacket method specifically for double-sign slash packets. +// TestOnRecvDoubleSignSlashPacket tests the OnRecvSlashPacket method specifically for double-sign slash packets. func TestOnRecvDoubleSignSlashPacket(t *testing.T) { providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) defer ctrl.Finish() @@ -249,12 +186,8 @@ func TestOnRecvDoubleSignSlashPacket(t *testing.T) { // Receive the double-sign slash packet for chain-1 and confirm the expected acknowledgement ack := executeOnRecvSlashPacket(t, &providerKeeper, ctx, "channel-1", 1, packetData) - require.Equal(t, channeltypes.NewResultAcknowledgement([]byte{byte(1)}), ack) + require.Equal(t, channeltypes.NewResultAcknowledgement(ccv.V1Result), ack) - // Nothing should be queued - require.Equal(t, uint64(0), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-1")) - require.Equal(t, uint64(0), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-2")) - require.Equal(t, 0, len(providerKeeper.GetAllGlobalSlashEntries(ctx))) require.True(t, providerKeeper.GetSlashLog(ctx, providertypes.NewProviderConsAddress(packetData.Validator.Address))) @@ -263,56 +196,6 @@ func TestOnRecvDoubleSignSlashPacket(t *testing.T) { require.False(t, providerKeeper.GetSlashLog(ctx, randomAddress)) } -// TestOnRecvSlashPacket tests the OnRecvSlashPacket method specifically for downtime slash packets, -// and how the method interacts with the parent and per-chain slash packet queues. -func TestOnRecvDowntimeSlashPacket(t *testing.T) { - providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - providerKeeper.SetParams(ctx, providertypes.DefaultParams()) - - // Set channel to chain (faking multiple established channels) - providerKeeper.SetChannelToChain(ctx, "channel-1", "chain-1") - providerKeeper.SetChannelToChain(ctx, "channel-2", "chain-2") - - // Generate a new slash packet data instance with downtime infraction type - packetData := testkeeper.GetNewSlashPacketData() - packetData.Infraction = stakingtypes.Infraction_INFRACTION_DOWNTIME - - // Set a block height for the valset update id in the generated packet data - providerKeeper.SetValsetUpdateBlockHeight(ctx, packetData.ValsetUpdateId, uint64(15)) - - // Receive the downtime slash packet for chain-1 at time.Now() - ctx = ctx.WithBlockTime(time.Now()) - ack := executeOnRecvSlashPacket(t, &providerKeeper, ctx, "channel-1", 1, packetData) - require.Equal(t, channeltypes.NewResultAcknowledgement([]byte{byte(1)}), ack) - - // Confirm an entry was added to the global queue, and pending packet data was added to the per-chain queue - globalEntries := providerKeeper.GetAllGlobalSlashEntries(ctx) // parent queue - require.Equal(t, 1, len(globalEntries)) - require.Equal(t, "chain-1", globalEntries[0].ConsumerChainID) - require.Equal(t, uint64(1), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-1")) // per chain queue - - // Generate a new downtime packet data instance with downtime infraction type - packetData = testkeeper.GetNewSlashPacketData() - packetData.Infraction = stakingtypes.Infraction_INFRACTION_DOWNTIME - - // Set a block height for the valset update id in the generated packet data - providerKeeper.SetValsetUpdateBlockHeight(ctx, packetData.ValsetUpdateId, uint64(15)) - - // Receive a downtime slash packet for chain-2 at time.Now(Add(1 *time.Hour)) - ctx = ctx.WithBlockTime(time.Now().Add(1 * time.Hour)) - ack = executeOnRecvSlashPacket(t, &providerKeeper, ctx, "channel-2", 2, packetData) - require.Equal(t, channeltypes.NewResultAcknowledgement([]byte{byte(1)}), ack) - - // Confirm sizes of parent queue and both per-chain queues - globalEntries = providerKeeper.GetAllGlobalSlashEntries(ctx) - require.Equal(t, 2, len(globalEntries)) - require.Equal(t, "chain-1", globalEntries[0].ConsumerChainID) - require.Equal(t, "chain-2", globalEntries[1].ConsumerChainID) - require.Equal(t, uint64(1), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-1")) // per chain queue - require.Equal(t, uint64(1), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-2")) // per chain queue -} - func executeOnRecvVSCMaturedPacket(t *testing.T, providerKeeper *keeper.Keeper, ctx sdk.Context, channelID string, ibcSeqNum uint64, ) exported.Acknowledgement { diff --git a/x/ccv/provider/keeper/throttle.go b/x/ccv/provider/keeper/throttle.go index d8be629ee7..8232e37a25 100644 --- a/x/ccv/provider/keeper/throttle.go +++ b/x/ccv/provider/keeper/throttle.go @@ -11,64 +11,8 @@ import ( tmtypes "github.com/cometbft/cometbft/types" providertypes "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v3/x/ccv/types" ) -// This file contains functionality relevant to the throttling of slash and vsc matured packets, aka circuit breaker logic. - -const vscMaturedHandledPerBlockLimit = 100 - -// HandleThrottleQueues iterates over the global slash entry queue, and -// handles all or some portion of throttled (slash and/or VSC matured) packet data received from -// consumer chains. The slash meter is decremented appropriately in this method. -func (k Keeper) HandleThrottleQueues(ctx sdktypes.Context, vscMaturedHandledThisBlock int) { - meter := k.GetSlashMeter(ctx) - // Return if meter is negative in value - if meter.IsNegative() { - return - } - - // Return if vsc matured handle limit was already reached this block, during HandleLeadingVSCMaturedPackets. - // It makes no practical difference for throttling logic to execute next block. - // By doing this, we assure that all leading vsc matured packets were handled before any slash packets. - if vscMaturedHandledThisBlock >= vscMaturedHandledPerBlockLimit { - return - } - - // Obtain all global slash entries, where only some of them may be handled in this method, - // depending on the value of the slash meter. - allEntries := k.GetAllGlobalSlashEntries(ctx) - handledEntries := []providertypes.GlobalSlashEntry{} - - for _, globalEntry := range allEntries { - // Subtract voting power that will be jailed/tombstoned from the slash meter - providerAddr := providertypes.NewProviderConsAddress(globalEntry.ProviderValConsAddr) - meter = meter.Sub(k.GetEffectiveValPower(ctx, providerAddr)) - - // Handle one slash and any trailing vsc matured packet data instances by passing in - // chainID and appropriate callbacks, relevant packet data is deleted in this method. - - k.HandlePacketDataForChain(ctx, globalEntry.ConsumerChainID, k.HandleSlashPacket, k.HandleVSCMaturedPacket, vscMaturedHandledThisBlock) - handledEntries = append(handledEntries, globalEntry) - - // don't handle any more global entries if meter becomes negative in value - if meter.IsNegative() { - k.Logger(ctx).Info("negative slash meter value, no more slash packets will be handled", "meter", meter.Int64()) - break - } - } - - // Handled global entries are deleted after iteration is completed - k.DeleteGlobalSlashEntries(ctx, handledEntries...) - - // Persist current value for slash meter - k.SetSlashMeter(ctx, meter) - - if len(handledEntries) > 0 { - k.Logger(ctx).Info("handled global slash entries", "count", len(handledEntries), "meter", meter.Int64()) - } -} - // Obtains the effective validator power relevant to a validator consensus address. func (k Keeper) GetEffectiveValPower(ctx sdktypes.Context, valConsAddr providertypes.ProviderConsAddress, @@ -87,41 +31,6 @@ func (k Keeper) GetEffectiveValPower(ctx sdktypes.Context, } } -// HandlePacketDataForChain handles only the first queued slash packet relevant to the passed consumer chainID, -// and then handles any trailing vsc matured packets in that (consumer chain specific) throttled packet data queue. -// The handled data is then deleted from the queue. -// -// Note: Any packet data which is handled in this method is also deleted from the (consumer chain specific) queue. -func (k Keeper) HandlePacketDataForChain(ctx sdktypes.Context, consumerChainID string, - slashPacketHandler func(sdktypes.Context, string, ccvtypes.SlashPacketData), - vscMaturedPacketHandler func(sdktypes.Context, string, ccvtypes.VSCMaturedPacketData), - vscMaturedHandledThisBlock int, -) { - // Get slash packet data and trailing vsc matured packet data, handle it all. - slashFound, slashData, vscMaturedData, seqNums := k.GetSlashAndTrailingData(ctx, consumerChainID) - seqNumsHandled := []uint64{} - if slashFound { - slashPacketHandler(ctx, consumerChainID, slashData) - // Due to HandleLeadingVSCMaturedPackets() running before HandleThrottleQueues(), and the fact that - // HandleThrottleQueues() will return until all leading vsc matured have been handled, a slash packet - // should always be the first packet in the queue. So we can safely append the first seqNum here. - seqNumsHandled = append(seqNumsHandled, seqNums[0]) - } - for idx, vscMData := range vscMaturedData { - if vscMaturedHandledThisBlock >= vscMaturedHandledPerBlockLimit { - // Break from for-loop, DeleteThrottledPacketData will still be called for this consumer - break - } - vscMaturedPacketHandler(ctx, consumerChainID, vscMData) - vscMaturedHandledThisBlock++ - // Append seq num for this vsc matured packet - seqNumsHandled = append(seqNumsHandled, seqNums[idx+1]) // Note idx+1, since slash packet is at index 0 - } - - // Delete handled data after it has all been handled. - k.DeleteThrottledPacketData(ctx, consumerChainID, seqNumsHandled...) -} - // InitializeSlashMeter initializes the slash meter to it's max value (also its allowance), // and sets the replenish time candidate to one replenish period from current block time. func (k Keeper) InitializeSlashMeter(ctx sdktypes.Context) { @@ -206,353 +115,6 @@ func (k Keeper) GetSlashMeterAllowance(ctx sdktypes.Context) math.Int { return roundedInt } -// -// CRUD section -// - -// QueueGlobalSlashEntry queues an entry to the "global" slash packet queue, used for throttling val power changes -// related to jailing/tombstoning over time. This "global" queue is used to coordinate the order of slash packet handling -// between chains, whereas the chain-specific queue is used to coordinate the order of slash and vsc matured packets -// relevant to each chain. -func (k Keeper) QueueGlobalSlashEntry(ctx sdktypes.Context, entry providertypes.GlobalSlashEntry) { - store := ctx.KVStore(k.storeKey) - key := providertypes.GlobalSlashEntryKey(entry) - bz := entry.ProviderValConsAddr - store.Set(key, bz) -} - -// DeleteGlobalSlashEntriesForConsumer deletes all pending slash packet entries in the global queue, -// only relevant to a single consumer. -func (k Keeper) DeleteGlobalSlashEntriesForConsumer(ctx sdktypes.Context, consumerChainID string) { - allEntries := k.GetAllGlobalSlashEntries(ctx) - entriesToDel := []providertypes.GlobalSlashEntry{} - - for _, entry := range allEntries { - if entry.ConsumerChainID == consumerChainID { - entriesToDel = append(entriesToDel, entry) - } - } - k.DeleteGlobalSlashEntries(ctx, entriesToDel...) -} - -// GetAllGlobalSlashEntries returns all global slash entries from the queue. -// -// Note global slash entries are stored under keys with the following format: -// GlobalSlashEntryBytePrefix | uint64 recv time | ibc seq num | consumer chain id -// Thus, the returned array is ordered by recv time, then ibc seq num. -func (k Keeper) GetAllGlobalSlashEntries(ctx sdktypes.Context) []providertypes.GlobalSlashEntry { - store := ctx.KVStore(k.storeKey) - iterator := sdktypes.KVStorePrefixIterator(store, []byte{providertypes.GlobalSlashEntryBytePrefix}) - defer iterator.Close() - - entries := []providertypes.GlobalSlashEntry{} - - for ; iterator.Valid(); iterator.Next() { - // MustParseGlobalSlashEntryKey should not panic, since we should be iterating over keys that're - // assumed to be correctly serialized in QueueGlobalSlashEntry. - recvTime, chainID, ibcSeqNum := providertypes.MustParseGlobalSlashEntryKey(iterator.Key()) - valAddr := providertypes.NewProviderConsAddress(iterator.Value()) - entry := providertypes.NewGlobalSlashEntry(recvTime, chainID, ibcSeqNum, valAddr) - entries = append(entries, entry) - } - return entries -} - -// DeleteGlobalSlashEntries deletes the given global entries from the global slash queue -func (k Keeper) DeleteGlobalSlashEntries(ctx sdktypes.Context, entries ...providertypes.GlobalSlashEntry) { - store := ctx.KVStore(k.storeKey) - for _, entry := range entries { - store.Delete(providertypes.GlobalSlashEntryKey(entry)) - } -} - -// Pending packet data type enum, used to encode the type of packet data stored at each entry in the mutual queue. -const ( - slashPacketData byte = iota - vscMaturedPacketData -) - -// GetThrottledPacketDataSize returns the size of the throttled packet data queue for the given consumer chain -func (k Keeper) GetThrottledPacketDataSize(ctx sdktypes.Context, consumerChainID string) uint64 { - store := ctx.KVStore(k.storeKey) - key := providertypes.ThrottledPacketDataSizeKey(consumerChainID) - var size uint64 - bz := store.Get(key) - if bz == nil { - size = 0 - } else { - size = sdktypes.BigEndianToUint64(bz) - } - return size -} - -// SetThrottledPacketDataSize sets the size of the throttled packet data queue for the given consumer chain -func (k Keeper) SetThrottledPacketDataSize(ctx sdktypes.Context, consumerChainID string, size uint64) { - // Sanity check to ensure that the chain-specific throttled packet data queue does not grow too - // large for a single consumer chain. This check ensures that binaries would panic deterministically - // if the queue does grow too large. MaxThrottledPackets should be set accordingly (quite large). - if size >= uint64(k.GetMaxThrottledPackets(ctx)) { - panic(fmt.Sprintf("throttled packet data queue for chain %s is too large: %d", consumerChainID, size)) - } - - store := ctx.KVStore(k.storeKey) - key := providertypes.ThrottledPacketDataSizeKey(consumerChainID) - bz := sdktypes.Uint64ToBigEndian(size) - store.Set(key, bz) -} - -// IncrementThrottledPacketDataSize increments the size of the throttled packet data -// queue for the given consumer chain. -func (k Keeper) IncrementThrottledPacketDataSize(ctx sdktypes.Context, consumerChainID string) { - size := k.GetThrottledPacketDataSize(ctx, consumerChainID) - k.SetThrottledPacketDataSize(ctx, consumerChainID, size+1) - k.Logger(ctx).Debug("incremented throttled packets size", - "chainID", consumerChainID, - "size", size+1, - ) -} - -// QueueThrottledSlashPacketData queues the slash packet data for a chain-specific throttled packet data queue. -// -// Note: This queue is shared between pending slash packet data and pending vsc matured packet data. -func (k Keeper) QueueThrottledSlashPacketData( - ctx sdktypes.Context, consumerChainID string, ibcSeqNum uint64, data ccvtypes.SlashPacketData, -) error { - return k.QueueThrottledPacketData(ctx, consumerChainID, ibcSeqNum, data) -} - -// QueueThrottledVSCMaturedPacketData queues the vsc matured packet data for a chain-specific throttled packet data queue. -// -// Note: This queue is shared between pending slash packet data and pending vsc matured packet data. -func (k Keeper) QueueThrottledVSCMaturedPacketData( - ctx sdktypes.Context, consumerChainID string, ibcSeqNum uint64, data ccvtypes.VSCMaturedPacketData, -) error { - return k.QueueThrottledPacketData(ctx, consumerChainID, ibcSeqNum, data) -} - -// QueueThrottledPacketData queues a slash packet data or vsc matured packet data instance -// for the given consumer chain's queue. -// -// Note: This method returns an error because it is called from -// OnRecvSlashPacket and OnRecvVSCMaturedPacket, meaning we can return an ibc err ack to the -// counter party chain on error, instead of panicking this chain. -func (k Keeper) QueueThrottledPacketData( - ctx sdktypes.Context, consumerChainID string, ibcSeqNum uint64, packetData interface{}, -) error { - store := ctx.KVStore(k.storeKey) - - var bz []byte - var err error - switch data := packetData.(type) { - case ccvtypes.SlashPacketData: - bz, err = data.Marshal() - if err != nil { - return fmt.Errorf("failed to marshal slash packet data: %v", err) - } - bz = append([]byte{slashPacketData}, bz...) - case ccvtypes.VSCMaturedPacketData: - bz, err = data.Marshal() - if err != nil { - return fmt.Errorf("failed to marshal vsc matured packet data: %v", err) - } - bz = append([]byte{vscMaturedPacketData}, bz...) - default: - // Indicates a developer error, this method should only be called - // by tests, QueueThrottledSlashPacketData, or QueueThrottledVSCMaturedPacketData. - panic(fmt.Sprintf("unexpected packet data type: %T", data)) - } - - store.Set(providertypes.ThrottledPacketDataKey(consumerChainID, ibcSeqNum), bz) - k.IncrementThrottledPacketDataSize(ctx, consumerChainID) - return nil -} - -// GetLeadingVSCMaturedData returns the leading vsc matured packet data instances -// for a chain-specific throttled packet data queue. Ie the vsc matured packet data instances -// that do not have any slash packet data instances preceding them in the queue for consumerChainID. -func (k Keeper) GetLeadingVSCMaturedData(ctx sdktypes.Context, consumerChainID string) ( - vscMaturedData []ccvtypes.VSCMaturedPacketData, ibcSeqNums []uint64, -) { - store := ctx.KVStore(k.storeKey) - iteratorPrefix := providertypes.ChainIdWithLenKey(providertypes.ThrottledPacketDataBytePrefix, consumerChainID) - iterator := sdktypes.KVStorePrefixIterator(store, iteratorPrefix) - defer iterator.Close() - - // Iterate over the throttled packet data queue, - // and return vsc matured packet data instances until we encounter a slash packet data instance. - vscMaturedData = []ccvtypes.VSCMaturedPacketData{} - ibcSeqNums = []uint64{} - for ; iterator.Valid(); iterator.Next() { - - bz := iterator.Value() - if bz[0] == slashPacketData { - break - } else if bz[0] != vscMaturedPacketData { - // This case would indicate a developer error or store corruption, - // since QueueThrottledPacketData should only queue slash packet data or vsc matured packet data. - panic(fmt.Sprintf("unexpected packet data type: %d", bz[0])) - } - - var data ccvtypes.VSCMaturedPacketData - err := data.Unmarshal(bz[1:]) - if err != nil { - // An error here would indicate something is very wrong, - // vsc matured packet data is assumed to be correctly serialized in QueueThrottledPacketData. - panic(fmt.Sprintf("failed to unmarshal vsc matured packet data: %v", err)) - } - - vscMaturedData = append(vscMaturedData, data) - // The below func should not panic, since we should be iterating over keys that're - // assumed to be correctly serialized in QueueThrottledPacketData. - _, ibcSeqNum := providertypes.MustParseThrottledPacketDataKey(iterator.Key()) - ibcSeqNums = append(ibcSeqNums, ibcSeqNum) - } - return vscMaturedData, ibcSeqNums -} - -// GetSlashAndTrailingData returns the first slash packet data instance and any -// trailing vsc matured packet data instances in the chain-specific throttled packet data queue. -// -// Note that throttled packet data is stored under keys with the following format: -// ThrottledPacketDataBytePrefix | len(chainID) | chainID | ibcSeqNum -// Thus, the returned array is in ascending order of ibc seq numbers. -func (k Keeper) GetSlashAndTrailingData(ctx sdktypes.Context, consumerChainID string) ( - slashFound bool, slashData ccvtypes.SlashPacketData, vscMaturedData []ccvtypes.VSCMaturedPacketData, - // Note: this slice contains the IBC sequence numbers of the slash packet data - // and trailing vsc matured packet data instances. This is used by caller to delete the - // data after it has been handled. - ibcSeqNums []uint64, -) { - store := ctx.KVStore(k.storeKey) - iteratorPrefix := providertypes.ChainIdWithLenKey(providertypes.ThrottledPacketDataBytePrefix, consumerChainID) - iterator := sdktypes.KVStorePrefixIterator(store, iteratorPrefix) - defer iterator.Close() - - slashFound = false - slashData = ccvtypes.SlashPacketData{} - vscMaturedData = []ccvtypes.VSCMaturedPacketData{} - ibcSeqNums = []uint64{} - - for ; iterator.Valid(); iterator.Next() { - - bz := iterator.Value() - if bz[0] == slashPacketData { - if slashFound { - // Break for-loop, we've already found first slash packet data instance. - break - } else { - if err := slashData.Unmarshal(bz[1:]); err != nil { - // An error here would indicate something is very wrong, - // slash packet data is assumed to be correctly serialized in QueueThrottledPacketData. - panic(fmt.Sprintf("failed to unmarshal slash packet data: %v", err)) - } - slashFound = true - } - } else if bz[0] == vscMaturedPacketData { - vscMData := ccvtypes.VSCMaturedPacketData{} - if err := vscMData.Unmarshal(bz[1:]); err != nil { - // An error here would indicate something is very wrong, - // vsc matured packet data is assumed to be correctly serialized in QueueThrottledPacketData. - panic(fmt.Sprintf("failed to unmarshal vsc matured packet data: %v", err)) - } - vscMaturedData = append(vscMaturedData, vscMData) - } else { - // This case would indicate a developer error or store corruption, - // since QueueThrottledPacketData should only queue slash packet data or vsc matured packet data. - panic("invalid packet data type") - } - // The below func should not panic, since we should be iterating over keys that're - // assumed to be correctly serialized in QueueThrottledPacketData. - _, ibcSeqNum := providertypes.MustParseThrottledPacketDataKey(iterator.Key()) - ibcSeqNums = append(ibcSeqNums, ibcSeqNum) - } - return slashFound, slashData, vscMaturedData, ibcSeqNums -} - -// GetAllThrottledPacketData returns all throttled packet data for a specific consumer chain. -// -// Note: This method is only used by tests and queries, hence why it returns redundant data as different types. -// Since this method executes on query, no panics are explicitly included. -func (k Keeper) GetAllThrottledPacketData(ctx sdktypes.Context, consumerChainID string) ( - slashData []ccvtypes.SlashPacketData, vscMaturedData []ccvtypes.VSCMaturedPacketData, - rawOrderedData []interface{}, ibcSeqNums []uint64, -) { - slashData = []ccvtypes.SlashPacketData{} - vscMaturedData = []ccvtypes.VSCMaturedPacketData{} - rawOrderedData = []interface{}{} - ibcSeqNums = []uint64{} - - store := ctx.KVStore(k.storeKey) - iteratorPrefix := providertypes.ChainIdWithLenKey(providertypes.ThrottledPacketDataBytePrefix, consumerChainID) - iterator := sdktypes.KVStorePrefixIterator(store, iteratorPrefix) - defer iterator.Close() - - for ; iterator.Valid(); iterator.Next() { - bz := iterator.Value() - switch bz[0] { - case slashPacketData: - d := ccvtypes.SlashPacketData{} - if err := d.Unmarshal(bz[1:]); err != nil { - k.Logger(ctx).Error(fmt.Sprintf("failed to unmarshal slash packet data: %v", err)) - continue - } - slashData = append(slashData, d) - rawOrderedData = append(rawOrderedData, d) - case vscMaturedPacketData: - d := ccvtypes.VSCMaturedPacketData{} - if err := d.Unmarshal(bz[1:]); err != nil { - k.Logger(ctx).Error(fmt.Sprintf("failed to unmarshal vsc matured packet data: %v", err)) - continue - } - vscMaturedData = append(vscMaturedData, d) - rawOrderedData = append(rawOrderedData, d) - default: - k.Logger(ctx).Error(fmt.Sprintf("invalid packet data type: %v", bz[0])) - continue - } - _, ibcSeqNum, err := providertypes.ParseThrottledPacketDataKey(iterator.Key()) - if err != nil { - k.Logger(ctx).Error(fmt.Sprintf("failed to parse throttled packet data key: %v", err)) - continue - } - ibcSeqNums = append(ibcSeqNums, ibcSeqNum) - } - - return slashData, vscMaturedData, rawOrderedData, ibcSeqNums -} - -// DeleteAllPacketDataForConsumer deletes all queued packet data for the given consumer chain. -func (k Keeper) DeleteThrottledPacketDataForConsumer(ctx sdktypes.Context, consumerChainID string) { - store := ctx.KVStore(k.storeKey) - iteratorPrefix := providertypes.ChainIdWithLenKey(providertypes.ThrottledPacketDataBytePrefix, consumerChainID) - iterator := sdktypes.KVStorePrefixIterator(store, iteratorPrefix) - defer iterator.Close() - - keysToDel := [][]byte{} - for ; iterator.Valid(); iterator.Next() { - keysToDel = append(keysToDel, iterator.Key()) - } - // Delete data for this consumer - for _, key := range keysToDel { - store.Delete(key) - } - - // Delete size of data queue for this consumer - store.Delete(providertypes.ThrottledPacketDataSizeKey(consumerChainID)) -} - -// DeleteThrottledPacketData deletes the given throttled packet data instances -// (specified by their ibc seq number) from the chain-specific throttled packet data queue. -func (k Keeper) DeleteThrottledPacketData(ctx sdktypes.Context, consumerChainID string, ibcSeqNumbers ...uint64) { - store := ctx.KVStore(k.storeKey) - for _, ibcSeqNum := range ibcSeqNumbers { - store.Delete(providertypes.ThrottledPacketDataKey(consumerChainID, ibcSeqNum)) - } - // Decrement the size of the pending packet data queue - sizeBeforeDeletion := k.GetThrottledPacketDataSize(ctx, consumerChainID) - k.SetThrottledPacketDataSize(ctx, consumerChainID, sizeBeforeDeletion-uint64(len(ibcSeqNumbers))) -} - // GetSlashMeter returns a meter (persisted as a signed int) which stores an amount of voting power, corresponding // to an allowance of validators that can be jailed/tombstoned over time. // diff --git a/x/ccv/provider/keeper/throttle_test.go b/x/ccv/provider/keeper/throttle_test.go index a5356b0dc0..24e8c0ddde 100644 --- a/x/ccv/provider/keeper/throttle_test.go +++ b/x/ccv/provider/keeper/throttle_test.go @@ -1,13 +1,11 @@ package keeper_test import ( - "math/rand" "testing" "time" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" - "golang.org/x/exp/slices" "cosmossdk.io/math" @@ -15,168 +13,10 @@ import ( tmtypes "github.com/cometbft/cometbft/types" - cryptoutil "github.com/cosmos/interchain-security/v3/testutil/crypto" testkeeper "github.com/cosmos/interchain-security/v3/testutil/keeper" - "github.com/cosmos/interchain-security/v3/x/ccv/provider/keeper" providertypes "github.com/cosmos/interchain-security/v3/x/ccv/provider/types" - ccvtypes "github.com/cosmos/interchain-security/v3/x/ccv/types" ) -// TestHandlePacketDataForChain tests the HandlePacketDataForChain function. Note: Only one consumer is tested here, -// but multiple consumers are tested in TestPendingPacketData. -func TestHandlePacketDataForChain(t *testing.T) { - testCases := []struct { - name string - chainID string - // Pending packet data that will be queued in the order specified by the slice - dataToQueue []interface{} - // Indexes of packet data from dataToQueue that are expected to be handled and deleted from store - expectedHandledIndexes []int - }{ - { - "no packets", - "my-cool-chain", - []interface{}{}, - []int{}, - }, - { - "one slash packet should be handled", - "chain-37", - []interface{}{ - testkeeper.GetNewSlashPacketData(), - }, - []int{0}, - }, - { - "one slash packet followed by one vsc matured packet should all be handled", - "chain-222", - []interface{}{ - testkeeper.GetNewSlashPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - }, - []int{0, 1}, - }, - { - "one slash packet followed by multiple vsc matured packets should all be handled", - "chain-2223", - []interface{}{ - testkeeper.GetNewSlashPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - }, - []int{0, 1, 2, 3, 4, 5}, - }, - { - "multiple slash packets followed by multiple vsc matured packets should only handle first slash packet", - "chain-9", - []interface{}{ - testkeeper.GetNewSlashPacketData(), - testkeeper.GetNewSlashPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - }, - []int{0}, - }, - { - "vsc matured packets sandwiched between slash packets should handle everything but the last slash packet", - "chain-000", - []interface{}{ - testkeeper.GetNewSlashPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewSlashPacketData(), // 10th index not included in expectedHandledIndexes - }, - []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, - }, - { - "alternating slash and vsc matured packets should handle only the first slash, and trailing vsc matured packets", - "chain-00000", - []interface{}{ - testkeeper.GetNewSlashPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewSlashPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewSlashPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewSlashPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - testkeeper.GetNewSlashPacketData(), - testkeeper.GetNewVSCMaturedPacketData(), - }, - []int{0, 1, 2}, - }, - } - - for _, tc := range testCases { - providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - providerKeeper.SetParams(ctx, providertypes.DefaultParams()) - - // Queue throttled packet data, where chainID is arbitrary, and ibc seq number is index of the data instance - for i, data := range tc.dataToQueue { - err := providerKeeper.QueueThrottledPacketData(ctx, tc.chainID, uint64(i), data) - require.NoError(t, err) - } - - // Define our handler callbacks to simply store the data instances that are handled - handledData := []interface{}{} - slashHandleCounter := func(ctx sdktypes.Context, chainID string, data ccvtypes.SlashPacketData) { - handledData = append(handledData, data) - } - vscMaturedHandleCounter := func(ctx sdktypes.Context, chainID string, data ccvtypes.VSCMaturedPacketData) { - handledData = append(handledData, data) - } - - providerKeeper.HandlePacketDataForChain(ctx, tc.chainID, slashHandleCounter, vscMaturedHandleCounter, 0) - - // Assert number of handled data instances matches expected number - require.Equal(t, len(tc.expectedHandledIndexes), len(handledData)) - - // Assert handled data instances match expected value - for i, expectedIndex := range tc.expectedHandledIndexes { - require.Equal(t, tc.dataToQueue[expectedIndex], handledData[i]) - } - - // Sanity check, Assert that only the first handled packet is a slash packet, and the rest are vsc matured packets - for idx, instance := range handledData { - switch instance.(type) { - case ccvtypes.SlashPacketData: - require.Equal(t, 0, idx) - case ccvtypes.VSCMaturedPacketData: - default: - require.Fail(t, "unexpected data instance type") - } - } - - // Assert that the unhandled queued data instances are as expected (i.e no unexpected deletions) - expectedDataThatsLeft := []interface{}{} - for idx, data := range tc.dataToQueue { - if !slices.Contains(tc.expectedHandledIndexes, idx) { - expectedDataThatsLeft = append(expectedDataThatsLeft, data) - } - } - - _, _, dataThatsLeft, _ := providerKeeper.GetAllThrottledPacketData(ctx, tc.chainID) - require.Equal(t, expectedDataThatsLeft, dataThatsLeft) - - // Assert that each instance of handled data is deleted from the persisted queue (i.e deletions where expected) - for _, dataInstance := range handledData { - require.NotContains(t, dataThatsLeft, dataInstance) - } - } -} - // TestSlashMeterReplenishment tests the CheckForSlashMeterReplenishment, ReplenishSlashMeter, // and InitializeSlashMeter methods. func TestSlashMeterReplenishment(t *testing.T) { @@ -627,628 +467,6 @@ func TestGetSlashMeterAllowance(t *testing.T) { } } -// TestGlobalSlashEntries tests the queue and iteration functions for global slash entries, -// with assertion of FIFO ordering -func TestGlobalSlashEntries(t *testing.T) { - providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - - // Consistent time for "now" - now := time.Now().UTC() - - globalEntries := providerKeeper.GetAllGlobalSlashEntries(ctx) - require.Equal(t, 0, len(globalEntries)) - - // Queue 3 entries for chainIDs 0, 1, 2, note their respective ibc seq nums are - // ordered differently than the chainIDs would be iterated. - providerKeeper.QueueGlobalSlashEntry(ctx, providertypes.NewGlobalSlashEntry( - now.Local(), "chain-0", 15, cryptoutil.NewCryptoIdentityFromIntSeed(10).ProviderConsAddress())) - providerKeeper.QueueGlobalSlashEntry(ctx, providertypes.NewGlobalSlashEntry( - now.Local(), "chain-1", 10, cryptoutil.NewCryptoIdentityFromIntSeed(11).ProviderConsAddress())) - providerKeeper.QueueGlobalSlashEntry(ctx, providertypes.NewGlobalSlashEntry( - now.Local(), "chain-2", 5, cryptoutil.NewCryptoIdentityFromIntSeed(12).ProviderConsAddress())) - - globalEntries = providerKeeper.GetAllGlobalSlashEntries(ctx) - require.Equal(t, 3, len(globalEntries)) - - // Queue 3 entries for chainIDs 0, 1, 2 an hour later, with incremented ibc seq nums - providerKeeper.QueueGlobalSlashEntry(ctx, providertypes.NewGlobalSlashEntry( - now.Add(time.Hour).Local(), "chain-0", 16, // should appear last for this recv time - cryptoutil.NewCryptoIdentityFromIntSeed(20).ProviderConsAddress())) - providerKeeper.QueueGlobalSlashEntry(ctx, providertypes.NewGlobalSlashEntry( - now.Add(time.Hour).Local(), "chain-1", 11, // should appear middle for this recv time - cryptoutil.NewCryptoIdentityFromIntSeed(21).ProviderConsAddress())) - providerKeeper.QueueGlobalSlashEntry(ctx, providertypes.NewGlobalSlashEntry( - now.Add(time.Hour).Local(), "chain-2", 6, // should appear first for this recv time - cryptoutil.NewCryptoIdentityFromIntSeed(22).ProviderConsAddress())) - - // Retrieve entries from store - globalEntries = providerKeeper.GetAllGlobalSlashEntries(ctx) - require.Equal(t, 6, len(globalEntries)) - - // Assert that entries are obtained in FIFO order according to block time, then ibc seq num - require.Equal(t, "chain-2", globalEntries[0].ConsumerChainID) - require.Equal(t, "chain-1", globalEntries[1].ConsumerChainID) - require.Equal(t, "chain-0", globalEntries[2].ConsumerChainID) - require.Equal(t, "chain-2", globalEntries[3].ConsumerChainID) - require.Equal(t, "chain-1", globalEntries[4].ConsumerChainID) - require.Equal(t, "chain-0", globalEntries[5].ConsumerChainID) - - // Queue 3 entries for chainIDs 5, 6, 7 another hour later - providerKeeper.QueueGlobalSlashEntry(ctx, - providertypes.NewGlobalSlashEntry(now.Add(2*time.Hour).Local(), "chain-5", 50, // should appear middle for this recv time - cryptoutil.NewCryptoIdentityFromIntSeed(96).ProviderConsAddress())) - providerKeeper.QueueGlobalSlashEntry(ctx, - providertypes.NewGlobalSlashEntry(now.Add(2*time.Hour).Local(), "chain-6", 60, // should appear last for this recv time - cryptoutil.NewCryptoIdentityFromIntSeed(97).ProviderConsAddress())) - providerKeeper.QueueGlobalSlashEntry(ctx, - providertypes.NewGlobalSlashEntry(now.Add(2*time.Hour).Local(), "chain-7", 40, // should appear first for this recv time - cryptoutil.NewCryptoIdentityFromIntSeed(98).ProviderConsAddress())) - // Retrieve entries from store - globalEntries = providerKeeper.GetAllGlobalSlashEntries(ctx) - require.Equal(t, 9, len(globalEntries)) - - // Assert that entries are obtained in FIFO order according to block time, then ibc seq num - require.Equal(t, "chain-2", globalEntries[0].ConsumerChainID) - require.Equal(t, "chain-1", globalEntries[1].ConsumerChainID) - require.Equal(t, "chain-0", globalEntries[2].ConsumerChainID) - require.Equal(t, "chain-2", globalEntries[3].ConsumerChainID) - require.Equal(t, "chain-1", globalEntries[4].ConsumerChainID) - require.Equal(t, "chain-0", globalEntries[5].ConsumerChainID) - require.Equal(t, "chain-7", globalEntries[6].ConsumerChainID) - require.Equal(t, "chain-5", globalEntries[7].ConsumerChainID) - require.Equal(t, "chain-6", globalEntries[8].ConsumerChainID) - - // Assert each field is as expected for all 9 entries - require.Equal(t, uint64(5), globalEntries[0].IbcSeqNum) - require.Equal(t, uint64(10), globalEntries[1].IbcSeqNum) - require.Equal(t, uint64(15), globalEntries[2].IbcSeqNum) - require.Equal(t, uint64(6), globalEntries[3].IbcSeqNum) - require.Equal(t, uint64(11), globalEntries[4].IbcSeqNum) - require.Equal(t, uint64(16), globalEntries[5].IbcSeqNum) - require.Equal(t, uint64(40), globalEntries[6].IbcSeqNum) - require.Equal(t, uint64(50), globalEntries[7].IbcSeqNum) - require.Equal(t, uint64(60), globalEntries[8].IbcSeqNum) - - require.Equal(t, now, globalEntries[0].RecvTime) - require.Equal(t, now, globalEntries[1].RecvTime) - require.Equal(t, now, globalEntries[2].RecvTime) - require.Equal(t, now.Add(time.Hour).UTC(), globalEntries[3].RecvTime) - require.Equal(t, now.Add(time.Hour).UTC(), globalEntries[4].RecvTime) - require.Equal(t, now.Add(time.Hour).UTC(), globalEntries[5].RecvTime) - require.Equal(t, now.Add(2*time.Hour).UTC(), globalEntries[6].RecvTime) - require.Equal(t, now.Add(2*time.Hour).UTC(), globalEntries[7].RecvTime) - require.Equal(t, now.Add(2*time.Hour).UTC(), globalEntries[8].RecvTime) -} - -// Tests DeleteGlobalSlashEntriesForConsumer. -func TestDeleteGlobalSlashEntriesForConsumer(t *testing.T) { - providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx( - t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - - // Queue 2 global entries for a consumer chain ID - providerKeeper.QueueGlobalSlashEntry(ctx, - providertypes.NewGlobalSlashEntry(time.Now().Add(time.Hour), "chain-78", 1, - cryptoutil.NewCryptoIdentityFromIntSeed(78).ProviderConsAddress())) - providerKeeper.QueueGlobalSlashEntry(ctx, - providertypes.NewGlobalSlashEntry(time.Now().Add(time.Hour), "chain-78", 2, - cryptoutil.NewCryptoIdentityFromIntSeed(79).ProviderConsAddress())) - - // Queue 1 global entry for two other consumer chain IDs - providerKeeper.QueueGlobalSlashEntry(ctx, - providertypes.NewGlobalSlashEntry(time.Now().Add(2*time.Hour), "chain-79", 1, - cryptoutil.NewCryptoIdentityFromIntSeed(80).ProviderConsAddress())) - - providerKeeper.QueueGlobalSlashEntry(ctx, - providertypes.NewGlobalSlashEntry(time.Now().Add(3*time.Hour), "chain-80", 1, - cryptoutil.NewCryptoIdentityFromIntSeed(81).ProviderConsAddress())) - - // Delete entries for chain-78, confirm those are deleted, and the other two remain - providerKeeper.DeleteGlobalSlashEntriesForConsumer(ctx, "chain-78") - allEntries := providerKeeper.GetAllGlobalSlashEntries(ctx) - require.Equal(t, 2, len(allEntries)) - require.Equal(t, "chain-79", allEntries[0].ConsumerChainID) - require.Equal(t, "chain-80", allEntries[1].ConsumerChainID) -} - -// TestGlobalSlashEntryDeletion tests the deletion function for -// global slash entries with assertion of FIFO ordering. -func TestGlobalSlashEntryDeletion(t *testing.T) { - providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - - now := time.Now() - - entries := providerKeeper.GetAllGlobalSlashEntries(ctx) - require.Equal(t, 0, len(entries)) - - providerConsAddrs := []providertypes.ProviderConsAddress{ - cryptoutil.NewCryptoIdentityFromIntSeed(1).ProviderConsAddress(), - cryptoutil.NewCryptoIdentityFromIntSeed(2).ProviderConsAddress(), - cryptoutil.NewCryptoIdentityFromIntSeed(3).ProviderConsAddress(), - cryptoutil.NewCryptoIdentityFromIntSeed(4).ProviderConsAddress(), - cryptoutil.NewCryptoIdentityFromIntSeed(5).ProviderConsAddress(), - cryptoutil.NewCryptoIdentityFromIntSeed(6).ProviderConsAddress(), - cryptoutil.NewCryptoIdentityFromIntSeed(7).ProviderConsAddress(), - } - - // Instantiate entries in the expected order we wish to get them back as (ordered by recv time) - entries = []providertypes.GlobalSlashEntry{} - entries = append(entries, providertypes.NewGlobalSlashEntry(now, "chain-0", 1, providerConsAddrs[0])) - entries = append(entries, providertypes.NewGlobalSlashEntry(now.Add(time.Hour).UTC(), "chain-1", 178, providerConsAddrs[1])) - entries = append(entries, providertypes.NewGlobalSlashEntry(now.Add(2*time.Hour).Local(), "chain-2", 89, providerConsAddrs[2])) - entries = append(entries, providertypes.NewGlobalSlashEntry(now.Add(3*time.Hour).In(time.FixedZone("UTC-8", -8*60*60)), "chain-3", 23423, providerConsAddrs[3])) - entries = append(entries, providertypes.NewGlobalSlashEntry(now.Add(4*time.Hour).Local(), "chain-4", 323, providerConsAddrs[4])) - entries = append(entries, providertypes.NewGlobalSlashEntry(now.Add(5*time.Hour).UTC(), "chain-5", 18, providerConsAddrs[5])) - entries = append(entries, providertypes.NewGlobalSlashEntry(now.Add(6*time.Hour).Local(), "chain-6", 2, providerConsAddrs[6])) - - // Instantiate shuffled copy of above slice - shuffledEntries := append([]providertypes.GlobalSlashEntry{}, entries...) - seed := time.Now().UnixNano() - rng := rand.New(rand.NewSource(seed)) - rng.Shuffle(len(shuffledEntries), func(i, j int) { - shuffledEntries[i], shuffledEntries[j] = shuffledEntries[j], shuffledEntries[i] - }) - - // Queue 7 slash packets with various block times in random order - for _, entry := range shuffledEntries { - providerKeeper.QueueGlobalSlashEntry(ctx, entry) - } - - gotEntries := providerKeeper.GetAllGlobalSlashEntries(ctx) - require.Equal(t, 7, len(gotEntries)) - - // Assert obtained order is decided upon via packet recvTime, not insertion order - for i, gotEntry := range gotEntries { - expectedEntry := entries[i] - require.Equal(t, expectedEntry, gotEntry) - } - - // Confirm no mutations have occurred from test helper - gotEntries = providerKeeper.GetAllGlobalSlashEntries(ctx) - require.Equal(t, 7, len(gotEntries)) - - // Delete packets 1, 3, 5 (0-indexed) - providerKeeper.DeleteGlobalSlashEntries(ctx, gotEntries[1], gotEntries[3], gotEntries[5]) - - // Assert deletion and ordering - gotEntries = providerKeeper.GetAllGlobalSlashEntries(ctx) - require.Equal(t, 4, len(gotEntries)) - require.Equal(t, "chain-0", gotEntries[0].ConsumerChainID) - // entry 1 was deleted - require.Equal(t, "chain-2", gotEntries[1].ConsumerChainID) - // entry 3 was deleted - require.Equal(t, "chain-4", gotEntries[2].ConsumerChainID) - // entry 5 was deleted - require.Equal(t, "chain-6", gotEntries[3].ConsumerChainID) -} - -// TestThrottledPacketData tests chain-specific throttled packet data queuing, -// iteration and deletion functionality. -func TestThrottledPacketData(t *testing.T) { - providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - providerKeeper.SetParams(ctx, providertypes.DefaultParams()) - - packetDataForMultipleConsumers := []struct { - chainID string - instances []throttledPacketDataInstance - - // Expected order of data instances after retrieval from store, before deletion (specified by instance index) - expectedOrder []int - // Data instances to delete (specified by instance index) - toDelete []int - // Expected order of data instances after deletion (specified by instance index) - expectedOrderAfterDeletion []int - }{ - // Note, duplicate ibc sequence numbers are not tested, as we assume ibc behaves correctly - { - chainID: "chain-0", - instances: []throttledPacketDataInstance{ - {IbcSeqNum: 0, Data: testkeeper.GetNewSlashPacketData()}, - {IbcSeqNum: 1, Data: testkeeper.GetNewVSCMaturedPacketData()}, - {IbcSeqNum: 2, Data: testkeeper.GetNewSlashPacketData()}, - {IbcSeqNum: 3, Data: testkeeper.GetNewVSCMaturedPacketData()}, - {IbcSeqNum: 4, Data: testkeeper.GetNewSlashPacketData()}, - }, - expectedOrder: []int{0, 1, 2, 3, 4}, - toDelete: []int{0, 2, 4}, - expectedOrderAfterDeletion: []int{1, 3}, - }, - { - chainID: "chain-7", - instances: []throttledPacketDataInstance{ - {IbcSeqNum: 96, Data: testkeeper.GetNewSlashPacketData()}, - {IbcSeqNum: 78, Data: testkeeper.GetNewVSCMaturedPacketData()}, - {IbcSeqNum: 12, Data: testkeeper.GetNewSlashPacketData()}, - {IbcSeqNum: 0, Data: testkeeper.GetNewVSCMaturedPacketData()}, - {IbcSeqNum: 1, Data: testkeeper.GetNewSlashPacketData()}, - {IbcSeqNum: 78972, Data: testkeeper.GetNewVSCMaturedPacketData()}, - {IbcSeqNum: 9999999999999999999, Data: testkeeper.GetNewSlashPacketData()}, - }, - expectedOrder: []int{3, 4, 2, 1, 0, 5, 6}, - toDelete: []int{0, 1, 2, 3, 4, 5}, - expectedOrderAfterDeletion: []int{6}, - }, - { - chainID: "chain-thats-not-0-or-7", - instances: []throttledPacketDataInstance{ - {IbcSeqNum: 9, Data: testkeeper.GetNewSlashPacketData()}, - {IbcSeqNum: 8, Data: testkeeper.GetNewSlashPacketData()}, - {IbcSeqNum: 7, Data: testkeeper.GetNewSlashPacketData()}, - {IbcSeqNum: 6, Data: testkeeper.GetNewSlashPacketData()}, - {IbcSeqNum: 5, Data: testkeeper.GetNewVSCMaturedPacketData()}, - {IbcSeqNum: 1, Data: testkeeper.GetNewVSCMaturedPacketData()}, - }, - expectedOrder: []int{5, 4, 3, 2, 1, 0}, - toDelete: []int{1, 2, 3, 4, 5}, - expectedOrderAfterDeletion: []int{0}, - }, - } - - // Queue all packet data at once - for _, chainData := range packetDataForMultipleConsumers { - for _, dataInstance := range chainData.instances { - err := providerKeeper.QueueThrottledPacketData(ctx, chainData.chainID, dataInstance.IbcSeqNum, dataInstance.Data) - require.NoError(t, err) - } - } - - // Assert retrieval ordering for each chain - for _, chainData := range packetDataForMultipleConsumers { - expectedInstances := getOrderedInstances(chainData.instances, chainData.expectedOrder) - assertPendingPacketDataOrdering(t, &providerKeeper, ctx, chainData.chainID, expectedInstances) - } - - // Delete specified data all at once - for _, chainData := range packetDataForMultipleConsumers { - for _, i := range chainData.toDelete { - providerKeeper.DeleteThrottledPacketData(ctx, chainData.chainID, chainData.instances[i].IbcSeqNum) - } - } - - // Assert retrieval ordering after deletion for each chain - for _, chainData := range packetDataForMultipleConsumers { - expectedInstances := getOrderedInstances(chainData.instances, chainData.expectedOrderAfterDeletion) - assertPendingPacketDataOrdering(t, &providerKeeper, ctx, chainData.chainID, expectedInstances) - } -} - -func TestGetLeadingVSCMaturedData(t *testing.T) { - // Instantiate some sample data - slashData := getTenSampleSlashPacketData() - vscMaturedData := getTenSampleVSCMaturedPacketData() - - testCases := []struct { - name string - dataToQueue []throttledPacketDataInstance - expectedReturnData []ccvtypes.VSCMaturedPacketData - expectedReturnSeqs []uint64 - }{ - { - name: "no data", - dataToQueue: []throttledPacketDataInstance{}, - expectedReturnData: []ccvtypes.VSCMaturedPacketData{}, - expectedReturnSeqs: []uint64{}, - }, - { - name: "one slash", - dataToQueue: []throttledPacketDataInstance{ - {IbcSeqNum: 889, Data: slashData[0]}, - }, - expectedReturnData: []ccvtypes.VSCMaturedPacketData{}, - expectedReturnSeqs: []uint64{}, - }, - { - name: "one vsc matured", - dataToQueue: []throttledPacketDataInstance{ - {IbcSeqNum: 54, Data: vscMaturedData[0]}, - }, - expectedReturnData: []ccvtypes.VSCMaturedPacketData{vscMaturedData[0]}, - expectedReturnSeqs: []uint64{54}, - }, - { - name: "one vsc matured trailing one slash", - dataToQueue: []throttledPacketDataInstance{ - {IbcSeqNum: 87, Data: slashData[0]}, - {IbcSeqNum: 88, Data: vscMaturedData[0]}, - }, - expectedReturnData: []ccvtypes.VSCMaturedPacketData{}, // Nothing returned - expectedReturnSeqs: []uint64{}, // Nothing returned - }, - { - name: "one vsc matured trailing multiple slash", - dataToQueue: []throttledPacketDataInstance{ - {IbcSeqNum: 87, Data: slashData[0]}, - {IbcSeqNum: 88, Data: slashData[1]}, - {IbcSeqNum: 89, Data: slashData[2]}, - {IbcSeqNum: 90, Data: vscMaturedData[0]}, - }, - expectedReturnData: []ccvtypes.VSCMaturedPacketData{}, // Nothing returned - expectedReturnSeqs: []uint64{}, // Nothing returned - }, - { - name: "one vsc matured leading multiple slash", - dataToQueue: []throttledPacketDataInstance{ - {IbcSeqNum: 87, Data: vscMaturedData[0]}, - {IbcSeqNum: 88, Data: slashData[0]}, - {IbcSeqNum: 89, Data: slashData[1]}, - {IbcSeqNum: 90, Data: slashData[2]}, - }, - expectedReturnData: []ccvtypes.VSCMaturedPacketData{vscMaturedData[0]}, - expectedReturnSeqs: []uint64{87}, - }, - { - name: "multiple vsc matured leading multiple slash", - dataToQueue: []throttledPacketDataInstance{ - {IbcSeqNum: 102, Data: vscMaturedData[0]}, - {IbcSeqNum: 103, Data: vscMaturedData[1]}, - {IbcSeqNum: 104, Data: vscMaturedData[2]}, - {IbcSeqNum: 105, Data: slashData[0]}, - {IbcSeqNum: 106, Data: slashData[1]}, - {IbcSeqNum: 107, Data: slashData[2]}, - }, - expectedReturnData: []ccvtypes.VSCMaturedPacketData{vscMaturedData[0], vscMaturedData[1], vscMaturedData[2]}, - expectedReturnSeqs: []uint64{102, 103, 104}, - }, - } - - for _, tc := range testCases { - - providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - providerKeeper.SetParams(ctx, providertypes.DefaultParams()) - - // Queue a slash and vsc matured packet data for some random chain. - // These values should never be returned. - err := providerKeeper.QueueThrottledSlashPacketData(ctx, "some-rando-chain", 77, testkeeper.GetNewSlashPacketData()) - require.NoError(t, err) - err = providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "some-rando-chain", 97, testkeeper.GetNewVSCMaturedPacketData()) - require.NoError(t, err) - - // Queue the data to test against - for _, dataInstance := range tc.dataToQueue { - err := providerKeeper.QueueThrottledPacketData(ctx, "chain-99", dataInstance.IbcSeqNum, dataInstance.Data) - require.NoError(t, err) - } - - // Obtain data from iterator - returnedData, ibcSeqNums := providerKeeper.GetLeadingVSCMaturedData(ctx, "chain-99") - - // Assert the returned data is as expected - require.Equal(t, tc.expectedReturnData, returnedData) - require.Equal(t, tc.expectedReturnSeqs, ibcSeqNums) - } -} - -func TestGetSlashAndTrailingData(t *testing.T) { - // Instantiate some data to test against - someSlashData := getTenSampleSlashPacketData() - someVSCMaturedData := getTenSampleVSCMaturedPacketData() - - testCases := []struct { - name string - dataToQueue []throttledPacketDataInstance - expectedSlashFound bool - expectedSlashData ccvtypes.SlashPacketData - expectedVSCMaturedData []ccvtypes.VSCMaturedPacketData - expectedIBCSeqNums []uint64 - }{ - { - name: "Empty queue", - dataToQueue: []throttledPacketDataInstance{}, - expectedSlashFound: false, - expectedSlashData: ccvtypes.SlashPacketData{}, // single zero value returned. - expectedVSCMaturedData: []ccvtypes.VSCMaturedPacketData{}, - expectedIBCSeqNums: []uint64{}, - }, - { - name: "Queue only one slash data", - dataToQueue: []throttledPacketDataInstance{ - {IbcSeqNum: 1, Data: someSlashData[0]}, - }, - expectedSlashFound: true, - expectedSlashData: someSlashData[0], - expectedVSCMaturedData: []ccvtypes.VSCMaturedPacketData{}, - expectedIBCSeqNums: []uint64{1}, - }, - { - name: "Queue two vsc matured behind slash data", - dataToQueue: []throttledPacketDataInstance{ - {IbcSeqNum: 80, Data: someSlashData[3]}, - {IbcSeqNum: 82, Data: someVSCMaturedData[0]}, - {IbcSeqNum: 83, Data: someVSCMaturedData[1]}, - }, - expectedSlashFound: true, - expectedSlashData: someSlashData[3], - expectedVSCMaturedData: []ccvtypes.VSCMaturedPacketData{someVSCMaturedData[0], someVSCMaturedData[1]}, - expectedIBCSeqNums: []uint64{80, 82, 83}, - }, - { - name: "Queue two vsc matured behind 4 slash data", - dataToQueue: []throttledPacketDataInstance{ - {IbcSeqNum: 80, Data: someSlashData[1]}, // Only returned value - {IbcSeqNum: 82, Data: someSlashData[2]}, - {IbcSeqNum: 83, Data: someSlashData[3]}, - {IbcSeqNum: 84, Data: someSlashData[4]}, - {IbcSeqNum: 85, Data: someVSCMaturedData[1]}, - {IbcSeqNum: 86, Data: someVSCMaturedData[2]}, - }, - expectedSlashFound: true, - expectedSlashData: someSlashData[1], - expectedVSCMaturedData: []ccvtypes.VSCMaturedPacketData{}, - expectedIBCSeqNums: []uint64{80}, - }, - { - name: "Queue vsc matured data behind slash data, ending with another slash data", - dataToQueue: []throttledPacketDataInstance{ - {IbcSeqNum: 47238, Data: someSlashData[1]}, - {IbcSeqNum: 47239, Data: someVSCMaturedData[0]}, - {IbcSeqNum: 47240, Data: someVSCMaturedData[1]}, - {IbcSeqNum: 47241, Data: someVSCMaturedData[2]}, - {IbcSeqNum: 47242, Data: someVSCMaturedData[3]}, - {IbcSeqNum: 47243, Data: someSlashData[2]}, // Not returned - }, - expectedSlashFound: true, - expectedSlashData: someSlashData[1], - expectedVSCMaturedData: []ccvtypes.VSCMaturedPacketData{ - someVSCMaturedData[0], someVSCMaturedData[1], someVSCMaturedData[2], someVSCMaturedData[3], - }, - expectedIBCSeqNums: []uint64{47238, 47239, 47240, 47241, 47242}, - }, - } - - for _, tc := range testCases { - - providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - providerKeeper.SetParams(ctx, providertypes.DefaultParams()) - - // Queue a slash and vsc matured packet data for some random chain. - // These values should never be returned. - err := providerKeeper.QueueThrottledSlashPacketData(ctx, "some-rando-chain", 77, testkeeper.GetNewSlashPacketData()) - require.NoError(t, err) - err = providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "some-rando-chain", 97, testkeeper.GetNewVSCMaturedPacketData()) - require.NoError(t, err) - - // Queue the data to test - for _, dataInstance := range tc.dataToQueue { - err := providerKeeper.QueueThrottledPacketData(ctx, "chain-49", dataInstance.IbcSeqNum, dataInstance.Data) - require.NoError(t, err) - } - - // Retrieve the data, and assert that it is correct - slashFound, slashData, vscMaturedData, ibcSeqNums := providerKeeper.GetSlashAndTrailingData(ctx, "chain-49") - require.Equal(t, tc.expectedSlashFound, slashFound, tc.name) - require.Equal(t, tc.expectedSlashData, slashData, tc.name) - require.Equal(t, tc.expectedVSCMaturedData, vscMaturedData, tc.name) - require.Equal(t, tc.expectedIBCSeqNums, ibcSeqNums, tc.name) - } -} - -// TestDeleteThrottledPacketDataForConsumer tests the DeleteThrottledPacketDataForConsumer method. -func TestDeleteThrottledPacketDataForConsumer(t *testing.T) { - providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - providerKeeper.SetParams(ctx, providertypes.DefaultParams()) - - // Queue slash and a VSC matured packet data for chain-48 - err := providerKeeper.QueueThrottledSlashPacketData(ctx, "chain-48", 0, testkeeper.GetNewSlashPacketData()) - require.NoError(t, err) - err = providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "chain-48", 1, testkeeper.GetNewVSCMaturedPacketData()) - require.NoError(t, err) - - // Queue 3 slash, and 4 vsc matured packet data instances for chain-49 - err = providerKeeper.QueueThrottledSlashPacketData(ctx, "chain-49", 0, testkeeper.GetNewSlashPacketData()) - require.NoError(t, err) - err = providerKeeper.QueueThrottledSlashPacketData(ctx, "chain-49", 1, testkeeper.GetNewSlashPacketData()) - require.NoError(t, err) - err = providerKeeper.QueueThrottledSlashPacketData(ctx, "chain-49", 2, testkeeper.GetNewSlashPacketData()) - require.NoError(t, err) - err = providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "chain-49", 3, testkeeper.GetNewVSCMaturedPacketData()) - require.NoError(t, err) - err = providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "chain-49", 4, testkeeper.GetNewVSCMaturedPacketData()) - require.NoError(t, err) - err = providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "chain-49", 5, testkeeper.GetNewVSCMaturedPacketData()) - require.NoError(t, err) - err = providerKeeper.QueueThrottledVSCMaturedPacketData(ctx, "chain-49", 6, testkeeper.GetNewVSCMaturedPacketData()) - require.NoError(t, err) - - // Delete all packet data for chain-49, confirm they are deleted - providerKeeper.DeleteThrottledPacketDataForConsumer(ctx, "chain-49") - slashData, vscMaturedData, _, _ := providerKeeper.GetAllThrottledPacketData(ctx, "chain-49") - require.Empty(t, slashData) - require.Empty(t, vscMaturedData) - - // Confirm size of queue is now 0 - require.Equal(t, uint64(0), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-49")) - - // Confirm packet data for chain-48 is not deleted - slashData, vscMaturedData, _, _ = providerKeeper.GetAllThrottledPacketData(ctx, "chain-48") - require.Len(t, slashData, 1) - require.Len(t, vscMaturedData, 1) -} - -// TestPanicIfTooMuchThrottledPacketData tests that the provider panics -// when the number of throttled (queued) packets exceeds the max allowed by params. -func TestPanicIfTooMuchThrottledPacketData(t *testing.T) { - testCases := []struct { - max int64 - }{ - {max: 3}, // Max must be greater than 2 since we queue 2 packets for another chain in the test - {max: 5}, - {max: 10}, - {max: 15}, - {max: 25}, - {max: 100}, - } - - for _, tc := range testCases { - - providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - - // Set max throttled packets param - defaultParams := providertypes.DefaultParams() - defaultParams.MaxThrottledPackets = tc.max - providerKeeper.SetParams(ctx, defaultParams) - - seed := time.Now().UnixNano() - rng := rand.New(rand.NewSource(seed)) - - // Queuing up a couple data instances for another chain shouldn't matter - err := providerKeeper.QueueThrottledPacketData(ctx, "chain-17", 0, testkeeper.GetNewSlashPacketData()) - require.NoError(t, err) - err = providerKeeper.QueueThrottledPacketData(ctx, "chain-17", 1, testkeeper.GetNewVSCMaturedPacketData()) - require.NoError(t, err) - - // Queue packet data instances until we reach the max (some slash packets, some VSC matured packets) - reachedMax := false - for i := 0; i < int(tc.max); i++ { - randBool := rng.Intn(2) == 0 - var data interface{} - if randBool { - data = testkeeper.GetNewSlashPacketData() - } else { - data = testkeeper.GetNewVSCMaturedPacketData() - } - // Panic only if we've reached the max - if i == int(tc.max-1) { - require.Panics(t, func() { - _ = providerKeeper.QueueThrottledPacketData(ctx, "chain-88", uint64(i), data) - }) - reachedMax = true - } else { - err := providerKeeper.QueueThrottledPacketData(ctx, "chain-88", uint64(i), data) - require.NoError(t, err) - } - } - require.True(t, reachedMax) - } -} - -// TestThrottledPacketDataSize tests the getter, setter and incrementer for throttled packet data size. -func TestThrottledPacketDataSize(t *testing.T) { - providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) - defer ctrl.Finish() - - // Set params so we can use the default max throttled packet data size - params := providertypes.DefaultParams() - providerKeeper.SetParams(ctx, params) - - // Confirm initial size is 0 - require.Equal(t, uint64(0), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-0")) - - // Set throttled packet data size and confirm it was set - providerKeeper.SetThrottledPacketDataSize(ctx, "chain-0", 10) - require.Equal(t, uint64(10), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-0")) - - // Increment throttled packet data size and confirm it was incremented - providerKeeper.IncrementThrottledPacketDataSize(ctx, "chain-0") - require.Equal(t, uint64(11), providerKeeper.GetThrottledPacketDataSize(ctx, "chain-0")) -} - // TestSlashMeter tests the getter and setter for the slash gas meter func TestSlashMeter(t *testing.T) { testCases := []struct { @@ -1320,65 +538,3 @@ func TestSlashMeterReplenishTimeCandidate(t *testing.T) { require.Equal(t, tc.blockTime.Add(tc.replenishPeriod).UTC(), gotTime) } } - -// Struct used for TestPendingPacketData and helpers -type throttledPacketDataInstance struct { - IbcSeqNum uint64 - Data interface{} -} - -// getAllThrottledPacketDataInstances returns all throttled packet data instances in order -// from the chain-specific packet data queue. -func getAllThrottledPacketDataInstances(ctx sdktypes.Context, k *keeper.Keeper, consumerChainId string) (instances []throttledPacketDataInstance) { - _, _, allData, ibcSeqNums := k.GetAllThrottledPacketData(ctx, consumerChainId) - instances = []throttledPacketDataInstance{} - for idx, data := range allData { - instances = append(instances, throttledPacketDataInstance{ - IbcSeqNum: ibcSeqNums[idx], - Data: data, - }) - } - return instances -} - -// getOrderedInstances returns the given instances in order, specified by the given indexes -func getOrderedInstances(instances []throttledPacketDataInstance, orderbyIdx []int) (orderedInstances []throttledPacketDataInstance) { - toReturn := []throttledPacketDataInstance{} - for _, idx := range orderbyIdx { - toReturn = append(toReturn, instances[idx]) - } - return toReturn -} - -// Asserts that the throttled packet data retrieved for this consumer chain matches what's expected -func assertPendingPacketDataOrdering(t *testing.T, k *keeper.Keeper, ctx sdktypes.Context, - consumerChainId string, expectedInstances []throttledPacketDataInstance, -) { - t.Helper() - // Get all packet data for this chain - obtainedInstances := getAllThrottledPacketDataInstances(ctx, k, consumerChainId) - // No extra data should be present - require.Equal(t, len(expectedInstances), len(obtainedInstances)) - // Assert order and correct serialization/deserialization for each data instance - for i, obtainedInstance := range obtainedInstances { - require.Equal(t, expectedInstances[i], obtainedInstance) - } -} - -// getTenSampleSlashPacketData returns 10 randomized slash packet data instances for testing -func getTenSampleSlashPacketData() []ccvtypes.SlashPacketData { - sampleData := []ccvtypes.SlashPacketData{} - for i := 0; i < 10; i++ { - sampleData = append(sampleData, testkeeper.GetNewSlashPacketData()) - } - return sampleData -} - -// getTenSampleVSCMaturedPacketData returns 10 randomized VSC matured packet data instances for testing -func getTenSampleVSCMaturedPacketData() []ccvtypes.VSCMaturedPacketData { - sampleData := []ccvtypes.VSCMaturedPacketData{} - for i := 0; i < 10; i++ { - sampleData = append(sampleData, testkeeper.GetNewVSCMaturedPacketData()) - } - return sampleData -} diff --git a/x/ccv/provider/module.go b/x/ccv/provider/module.go index 82891c27c7..c70fdeafa7 100644 --- a/x/ccv/provider/module.go +++ b/x/ccv/provider/module.go @@ -107,6 +107,10 @@ 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 := keeper.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)) + } } // InitGenesis performs genesis initialization for the provider module. It returns no validator updates. @@ -129,7 +133,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 2 } +func (AppModule) ConsensusVersion() uint64 { return 3 } // BeginBlock implements the AppModule interface func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { @@ -137,6 +141,8 @@ func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { am.keeper.BeginBlockInit(ctx) // Stop and remove state for any consumer chains that are due to be stopped via pending consumer removal proposals am.keeper.BeginBlockCCR(ctx) + // Check for replenishing slash meter before any slash packets are processed for this block + am.keeper.BeginBlockCIS(ctx) } // EndBlock implements the AppModule interface diff --git a/x/ccv/provider/proposal_handler.go b/x/ccv/provider/proposal_handler.go index 7af7ec4e5f..b5bd4a6597 100644 --- a/x/ccv/provider/proposal_handler.go +++ b/x/ccv/provider/proposal_handler.go @@ -12,7 +12,7 @@ import ( ) // NewProviderProposalHandler defines the handler for consumer addition, -// consumer removal and equivocation proposals. +// consumer removal, and consumer reward denom proposals. // Passed proposals are executed during EndBlock. func NewProviderProposalHandler(k keeper.Keeper) govv1beta1.Handler { return func(ctx sdk.Context, content govv1beta1.Content) error { @@ -21,8 +21,6 @@ func NewProviderProposalHandler(k keeper.Keeper) govv1beta1.Handler { return k.HandleConsumerAdditionProposal(ctx, c) case *types.ConsumerRemovalProposal: return k.HandleConsumerRemovalProposal(ctx, c) - case *types.EquivocationProposal: - return k.HandleEquivocationProposal(ctx, c) case *types.ChangeRewardDenomsProposal: return k.HandleConsumerRewardDenomProposal(ctx, c) default: diff --git a/x/ccv/provider/proposal_handler_test.go b/x/ccv/provider/proposal_handler_test.go index 8f1322b3d2..7e4d586097 100644 --- a/x/ccv/provider/proposal_handler_test.go +++ b/x/ccv/provider/proposal_handler_test.go @@ -10,7 +10,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" testkeeper "github.com/cosmos/interchain-security/v3/testutil/keeper" @@ -19,12 +18,11 @@ import ( ) // TestProviderProposalHandler tests the highest level handler for proposals -// concerning creating, stopping consumer chains and submitting equivocations. +// concerning creating, stopping consumer chains and changing reward denom. func TestProviderProposalHandler(t *testing.T) { // Snapshot times asserted in tests now := time.Now().UTC() hourFromNow := now.Add(time.Hour).UTC() - equivocation := &evidencetypes.Equivocation{Height: 42} testCases := []struct { name string @@ -32,7 +30,6 @@ func TestProviderProposalHandler(t *testing.T) { blockTime time.Time expValidConsumerAddition bool expValidConsumerRemoval bool - expValidEquivocation bool expValidChangeRewardDenom bool }{ { @@ -58,21 +55,6 @@ func TestProviderProposalHandler(t *testing.T) { blockTime: hourFromNow, expValidConsumerRemoval: true, }, - { - // no slash log for equivocation - name: "invalid equivocation proposal", - content: providertypes.NewEquivocationProposal( - "title", "description", []*evidencetypes.Equivocation{equivocation}), - blockTime: hourFromNow, - expValidEquivocation: false, - }, - { - name: "valid equivocation proposal", - content: providertypes.NewEquivocationProposal( - "title", "description", []*evidencetypes.Equivocation{equivocation}), - blockTime: hourFromNow, - expValidEquivocation: true, - }, { name: "valid change reward denoms proposal", content: providertypes.NewChangeRewardDenomsProposal( @@ -118,10 +100,6 @@ func TestProviderProposalHandler(t *testing.T) { // assert mocks for expected calls to `StopConsumerChain` when closing the underlying channel gomock.InOrder(testkeeper.GetMocksForStopConsumerChainWithCloseChannel(ctx, &mocks)...) - - case tc.expValidEquivocation: - providerKeeper.SetSlashLog(ctx, providertypes.NewProviderConsAddress(equivocation.GetConsensusAddress())) - mocks.MockEvidenceKeeper.EXPECT().HandleEquivocationEvidence(ctx, equivocation) case tc.expValidChangeRewardDenom: // Nothing to mock } @@ -131,7 +109,7 @@ func TestProviderProposalHandler(t *testing.T) { err := proposalHandler(ctx, tc.content) if tc.expValidConsumerAddition || tc.expValidConsumerRemoval || - tc.expValidEquivocation || tc.expValidChangeRewardDenom { + tc.expValidChangeRewardDenom { require.NoError(t, err) } else { require.Error(t, err) diff --git a/x/ccv/provider/types/codec.go b/x/ccv/provider/types/codec.go index ceed3bf789..d1b9203efb 100644 --- a/x/ccv/provider/types/codec.go +++ b/x/ccv/provider/types/codec.go @@ -35,7 +35,14 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { (*govv1beta1.Content)(nil), &ChangeRewardDenomsProposal{}, ) - + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgSubmitConsumerMisbehaviour{}, + ) + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgSubmitConsumerDoubleVoting{}, + ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) } diff --git a/x/ccv/provider/types/errors.go b/x/ccv/provider/types/errors.go index 12fbfbe9c2..66d7a9a3b8 100644 --- a/x/ccv/provider/types/errors.go +++ b/x/ccv/provider/types/errors.go @@ -21,4 +21,7 @@ var ( 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") ) diff --git a/x/ccv/provider/types/events.go b/x/ccv/provider/types/events.go new file mode 100644 index 0000000000..58d686020f --- /dev/null +++ b/x/ccv/provider/types/events.go @@ -0,0 +1,18 @@ +package types + +// Provider events +const ( + EventTypeConsumerClientCreated = "consumer_client_created" + EventTypeAssignConsumerKey = "assign_consumer_key" + EventTypeAddConsumerRewardDenom = "add_consumer_reward_denom" + EventTypeRemoveConsumerRewardDenom = "remove_consumer_reward_denom" + EventTypeExecuteConsumerChainSlash = "execute_consumer_chain_slash" + AttributeInfractionHeight = "infraction_height" + AttributeInitialHeight = "initial_height" + AttributeInitializationTimeout = "initialization_timeout" + AttributeTrustingPeriod = "trusting_period" + AttributeUnbondingPeriod = "unbonding_period" + AttributeProviderValidatorAddress = "provider_validator_address" + AttributeConsumerConsensusPubKey = "consumer_consensus_pub_key" + AttributeConsumerRewardDenom = "consumer_reward_denom" +) diff --git a/x/ccv/provider/types/genesis.pb.go b/x/ccv/provider/types/genesis.pb.go index e08947ea5e..a7e06b7b09 100644 --- a/x/ccv/provider/types/genesis.pb.go +++ b/x/ccv/provider/types/genesis.pb.go @@ -5,7 +5,6 @@ package types import ( fmt "fmt" - _ "github.com/cometbft/cometbft/proto/tendermint/crypto" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" types "github.com/cosmos/interchain-security/v3/x/ccv/types" @@ -353,65 +352,64 @@ func init() { } var fileDescriptor_48411d9c7900d48e = []byte{ - // 925 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x6e, 0xdb, 0x36, - 0x14, 0x8e, 0x12, 0x37, 0x8d, 0x99, 0x9f, 0x65, 0x5c, 0xe6, 0x2a, 0x49, 0xe7, 0x06, 0x1e, 0x0a, - 0x04, 0xd8, 0x66, 0x35, 0xe9, 0x2e, 0xba, 0x9f, 0x5e, 0x34, 0xed, 0xb0, 0x19, 0xc3, 0x30, 0xc3, - 0x49, 0x33, 0xa0, 0xbb, 0x20, 0x68, 0x92, 0xb0, 0xd9, 0x48, 0xa4, 0x40, 0x52, 0x4a, 0x8c, 0x61, - 0x40, 0x87, 0xed, 0x01, 0xf6, 0x58, 0xbd, 0xcc, 0xe5, 0xae, 0x8a, 0x21, 0x79, 0x83, 0x3d, 0xc1, - 0x20, 0x8a, 0x52, 0xe5, 0xcc, 0x2e, 0xec, 0x5d, 0xd9, 0x3a, 0x1f, 0xcf, 0xf7, 0x9d, 0xc3, 0x43, - 0x9e, 0x43, 0x70, 0xc0, 0x85, 0x61, 0x8a, 0x0c, 0x31, 0x17, 0x48, 0x33, 0x92, 0x28, 0x6e, 0x46, - 0x01, 0x21, 0x69, 0x10, 0x2b, 0x99, 0x72, 0xca, 0x54, 0x90, 0x1e, 0x04, 0x03, 0x26, 0x98, 0xe6, - 0xba, 0x1d, 0x2b, 0x69, 0x24, 0xfc, 0x78, 0x82, 0x4b, 0x9b, 0x90, 0xb4, 0x5d, 0xb8, 0xb4, 0xd3, - 0x83, 0x9d, 0xad, 0x81, 0x1c, 0x48, 0xbb, 0x3e, 0xc8, 0xfe, 0xe5, 0xae, 0x3b, 0x0f, 0xa6, 0xa9, - 0xa5, 0x07, 0x81, 0x1e, 0x62, 0xc5, 0x28, 0x22, 0x52, 0xe8, 0x24, 0x62, 0xca, 0x79, 0xdc, 0x7f, - 0x87, 0xc7, 0x39, 0x57, 0xcc, 0x2d, 0x3b, 0x9c, 0x25, 0x8d, 0x32, 0xbe, 0xdc, 0xe7, 0xae, 0x61, - 0x82, 0x32, 0x15, 0x71, 0x61, 0x02, 0xa2, 0x46, 0xb1, 0x91, 0xc1, 0x19, 0x1b, 0xb9, 0x2c, 0x5b, - 0x97, 0xab, 0x60, 0xed, 0xdb, 0x3c, 0xef, 0x63, 0x83, 0x0d, 0x83, 0xfb, 0x60, 0x33, 0xc5, 0xa1, - 0x66, 0x06, 0x25, 0x31, 0xc5, 0x86, 0x21, 0x4e, 0x7d, 0x6f, 0xcf, 0xdb, 0xaf, 0xf5, 0x36, 0x72, - 0xfb, 0x73, 0x6b, 0xee, 0x50, 0xf8, 0x0b, 0x78, 0xaf, 0xc8, 0x02, 0xe9, 0xcc, 0x57, 0xfb, 0x8b, - 0x7b, 0x4b, 0xfb, 0xab, 0x87, 0x87, 0xed, 0x19, 0xb6, 0xae, 0xfd, 0xd4, 0xf9, 0x5a, 0xd9, 0xa3, - 0xe6, 0xeb, 0x37, 0xf7, 0x16, 0xfe, 0x79, 0x73, 0xaf, 0x31, 0xc2, 0x51, 0xf8, 0x65, 0xeb, 0x06, - 0x71, 0xab, 0xb7, 0x41, 0xaa, 0xcb, 0x35, 0xfc, 0x19, 0xac, 0x27, 0xa2, 0x2f, 0x05, 0xe5, 0x62, - 0x80, 0x64, 0xac, 0xfd, 0x25, 0x2b, 0xfd, 0x60, 0x26, 0xe9, 0xe7, 0x85, 0xe7, 0x8f, 0xf1, 0x51, - 0x2d, 0x13, 0xee, 0xad, 0x25, 0x6f, 0x4d, 0x1a, 0xbe, 0x04, 0x5b, 0x11, 0x36, 0x89, 0x62, 0x68, - 0x5c, 0xa3, 0xb6, 0xe7, 0xed, 0xaf, 0x1e, 0x3e, 0x9a, 0x49, 0xe3, 0x07, 0x4b, 0x40, 0x2b, 0x52, - 0xba, 0x07, 0x73, 0xd6, 0xaa, 0x0d, 0xfe, 0x0a, 0x76, 0x6e, 0xee, 0x37, 0x32, 0x12, 0x0d, 0x19, - 0x1f, 0x0c, 0x8d, 0x7f, 0xcb, 0x66, 0xf5, 0xd5, 0x4c, 0x8a, 0xa7, 0x63, 0xe5, 0x39, 0x91, 0xdf, - 0x59, 0x0a, 0x97, 0x60, 0x23, 0x9d, 0x88, 0xc2, 0xdf, 0x3d, 0xb0, 0x5b, 0x6e, 0x36, 0xa6, 0x94, - 0x1b, 0x2e, 0x05, 0x8a, 0x95, 0x8c, 0xa5, 0xc6, 0xa1, 0xf6, 0x97, 0x6d, 0x00, 0x8f, 0xe7, 0xaa, - 0xe8, 0x13, 0x47, 0xd3, 0x75, 0x2c, 0x2e, 0x84, 0x6d, 0x32, 0x05, 0xd7, 0xf0, 0x95, 0x07, 0x76, - 0xca, 0x28, 0x14, 0x8b, 0x64, 0x8a, 0xc3, 0x4a, 0x10, 0xb7, 0x6d, 0x10, 0x5f, 0xcf, 0x15, 0x44, - 0x2f, 0x67, 0xb9, 0x11, 0x83, 0x4f, 0x26, 0xc3, 0x1a, 0x76, 0xc0, 0x72, 0x8c, 0x15, 0x8e, 0xb4, - 0xbf, 0x62, 0xab, 0xfc, 0xc9, 0x4c, 0x6a, 0x5d, 0xeb, 0xe2, 0xc8, 0x1d, 0x81, 0xcd, 0x26, 0xc5, - 0x21, 0xa7, 0xd8, 0x48, 0x55, 0xde, 0x74, 0x14, 0x27, 0xfd, 0xec, 0xe2, 0xf9, 0xf5, 0x39, 0xb2, - 0x39, 0x2d, 0x68, 0x8a, 0xb4, 0xba, 0x49, 0xff, 0x7b, 0x36, 0x2a, 0xb2, 0x49, 0x27, 0xc0, 0x99, - 0x06, 0xfc, 0xcd, 0x03, 0xbb, 0x25, 0xa8, 0x51, 0x7f, 0x84, 0xaa, 0x45, 0x56, 0x3e, 0xf8, 0x3f, - 0x31, 0x1c, 0x8d, 0x2a, 0x15, 0x56, 0xff, 0x89, 0x41, 0x8f, 0xe3, 0x30, 0x05, 0x77, 0xc6, 0x44, - 0x75, 0x76, 0xae, 0x63, 0x95, 0x08, 0xe6, 0xaf, 0x5a, 0xf9, 0x2f, 0xe6, 0x3d, 0x55, 0x4a, 0x9f, - 0xc8, 0x6e, 0x46, 0xe0, 0xb4, 0xb7, 0xc8, 0x04, 0x0c, 0x9e, 0x83, 0x3b, 0x5c, 0x70, 0x83, 0x0c, - 0x8f, 0x98, 0x4c, 0xf2, 0x5f, 0x6d, 0x70, 0x14, 0x6b, 0x7f, 0x6d, 0x0e, 0xdd, 0x8e, 0xe0, 0xe6, - 0x24, 0xa7, 0x38, 0x29, 0x18, 0x9c, 0xee, 0x87, 0x7c, 0x02, 0xa6, 0xe1, 0x1f, 0x1e, 0xb8, 0xcb, - 0x2e, 0x62, 0xa9, 0x0c, 0xa3, 0x28, 0xd5, 0x04, 0x69, 0x26, 0x68, 0x55, 0x7e, 0x7d, 0x8e, 0xcb, - 0xf4, 0x8d, 0x23, 0x3a, 0xd5, 0xe4, 0x98, 0x09, 0x7a, 0x33, 0x84, 0x6d, 0x36, 0x05, 0xd7, 0xad, - 0x57, 0x35, 0xb0, 0x3e, 0xd6, 0x5c, 0xe1, 0x36, 0x58, 0xc9, 0xd5, 0x5c, 0x2f, 0xaf, 0xf7, 0x6e, - 0xdb, 0xef, 0x0e, 0x85, 0x1f, 0x01, 0x40, 0x86, 0x58, 0x08, 0x16, 0x66, 0xe0, 0xa2, 0x05, 0xeb, - 0xce, 0xd2, 0xa1, 0x70, 0x17, 0xd4, 0x49, 0xc8, 0x99, 0x30, 0x19, 0xba, 0x64, 0xd1, 0x95, 0xdc, - 0xd0, 0xa1, 0xf0, 0x3e, 0xd8, 0xc8, 0x36, 0x82, 0xe3, 0xb0, 0x68, 0x57, 0x35, 0x3b, 0x28, 0xd6, - 0x9d, 0xd5, 0xb5, 0x18, 0x0c, 0x36, 0xcb, 0x73, 0xe0, 0x46, 0xac, 0x7f, 0xcb, 0xde, 0xb1, 0xe9, - 0xdd, 0xba, 0x52, 0xf7, 0xea, 0x74, 0x72, 0xc9, 0x97, 0x73, 0xc7, 0x61, 0xd0, 0x80, 0x46, 0xcc, - 0xf2, 0x3e, 0xed, 0x9a, 0x69, 0x96, 0xc2, 0x80, 0x15, 0xfd, 0xeb, 0xd1, 0xbb, 0x84, 0xca, 0xf3, - 0x7d, 0xcc, 0xcc, 0x53, 0xeb, 0xd6, 0xc5, 0xe4, 0x8c, 0x99, 0x67, 0xd8, 0xe0, 0xe2, 0xa0, 0x39, - 0xf6, 0xbc, 0xc5, 0xe6, 0x8b, 0x34, 0xfc, 0x14, 0x40, 0x1d, 0x62, 0x3d, 0x44, 0x54, 0x9e, 0x8b, - 0xac, 0xcc, 0x08, 0x93, 0x33, 0xdb, 0xac, 0xea, 0xbd, 0x4d, 0x8b, 0x3c, 0x73, 0xc0, 0x13, 0x72, - 0x06, 0x5f, 0x82, 0x0f, 0xc6, 0xa6, 0x09, 0xe2, 0x82, 0xb2, 0x0b, 0x7f, 0xc5, 0x06, 0xf8, 0xf9, - 0x6c, 0x37, 0x51, 0x93, 0xea, 0xec, 0x70, 0xc1, 0xbd, 0x5f, 0x9d, 0x5d, 0x9d, 0x8c, 0xb4, 0xf5, - 0x02, 0x34, 0x26, 0x4f, 0x83, 0x39, 0xc6, 0x7b, 0x03, 0x2c, 0xbb, 0xaa, 0x2e, 0x5a, 0xdc, 0x7d, - 0x1d, 0xfd, 0xf4, 0xfa, 0xaa, 0xe9, 0x5d, 0x5e, 0x35, 0xbd, 0xbf, 0xaf, 0x9a, 0xde, 0x9f, 0xd7, - 0xcd, 0x85, 0xcb, 0xeb, 0xe6, 0xc2, 0x5f, 0xd7, 0xcd, 0x85, 0x17, 0x8f, 0x07, 0xdc, 0x0c, 0x93, - 0x7e, 0x9b, 0xc8, 0x28, 0x20, 0x52, 0x47, 0x52, 0x07, 0x6f, 0xb3, 0xfa, 0xac, 0x7c, 0xaf, 0xa4, - 0x0f, 0x83, 0x8b, 0xf1, 0x47, 0x8b, 0x19, 0xc5, 0x4c, 0xf7, 0x97, 0xed, 0x8b, 0xe4, 0xe1, 0xbf, - 0x01, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x6e, 0x42, 0x2b, 0xac, 0x09, 0x00, 0x00, + // 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, 0x3b, 0x3d, 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + 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, 0x5f, 0x4c, 0xf7, + 0x12, 0x81, 0x95, 0x67, 0x87, 0x37, 0xf7, 0x7e, 0x79, 0x76, 0xb5, 0x52, 0xd2, 0xfa, 0x73, 0x54, + 0x9d, 0x3c, 0x0d, 0x66, 0x18, 0xef, 0x55, 0xb4, 0xe4, 0xab, 0x3a, 0xef, 0x70, 0xff, 0xeb, 0xf0, + 0xe7, 0x57, 0x97, 0xb5, 0xe0, 0xe2, 0xb2, 0x16, 0xfc, 0x73, 0x59, 0x0b, 0xfe, 0xba, 0xaa, 0xcd, + 0x5d, 0x5c, 0xd5, 0xe6, 0xfe, 0xbe, 0xaa, 0xcd, 0x3d, 0x7f, 0xd4, 0x93, 0xb6, 0x1f, 0x77, 0x1b, + 0x4c, 0x0f, 0x9b, 0x4c, 0xc3, 0x50, 0x43, 0xf3, 0x4d, 0x56, 0x9f, 0x17, 0x5f, 0x24, 0xc9, 0x83, + 0xe6, 0xf9, 0xf8, 0x67, 0x89, 0x1d, 0x45, 0x02, 0xba, 0x4b, 0xee, 0x8b, 0xe4, 0xc1, 0x7f, 0x01, + 0x00, 0x00, 0xff, 0xff, 0x9e, 0xfb, 0x60, 0xd0, 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 7878afb0a4..d77ea563f8 100644 --- a/x/ccv/provider/types/genesis_test.go +++ b/x/ccv/provider/types/genesis_test.go @@ -81,7 +81,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", 400, 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: sdk.NewInt(10000000)}), nil, nil, nil, @@ -102,7 +102,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", 400, 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: sdk.NewInt(10000000)}), nil, nil, nil, @@ -123,7 +123,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", 400, 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: sdk.NewInt(10000000)}), nil, nil, nil, @@ -144,7 +144,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", 400, 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: sdk.NewInt(10000000)}), nil, nil, nil, @@ -171,7 +171,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - types.DefaultMaxThrottledPackets, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -198,7 +198,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - types.DefaultMaxThrottledPackets, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -225,7 +225,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - types.DefaultMaxThrottledPackets, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(1000000)}), + sdk.Coin{Denom: "stake", Amount: sdk.NewInt(1000000)}), nil, nil, nil, @@ -252,7 +252,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - types.DefaultMaxThrottledPackets, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -279,7 +279,7 @@ func TestValidateGenesisState(t *testing.T) { 0, // 0 vsc timeout here types.DefaultSlashMeterReplenishPeriod, types.DefaultSlashMeterReplenishFraction, - types.DefaultMaxThrottledPackets, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -306,7 +306,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, 0, // 0 slash meter replenish period here types.DefaultSlashMeterReplenishFraction, - types.DefaultMaxThrottledPackets, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -333,34 +333,7 @@ func TestValidateGenesisState(t *testing.T) { types.DefaultVscTimeoutPeriod, types.DefaultSlashMeterReplenishPeriod, "1.15", - types.DefaultMaxThrottledPackets, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), - nil, - nil, - nil, - nil, - nil, - ), - false, - }, - { - "invalid params, invalid max pending slash packets", - types.NewGenesisState( - types.DefaultValsetUpdateID, - nil, - []types.ConsumerState{{ChainId: "chainid-1", ChannelId: "channelid", ClientId: "client-id"}}, - nil, - nil, - nil, - nil, - types.NewParams(ibctmtypes.NewClientState("", ibctmtypes.DefaultTrustLevel, 0, 0, - time.Second*40, clienttypes.Height{}, commitmenttypes.GetSDKSpecs(), []string{"ibc", "upgradedIBCState"}), - types.DefaultTrustingPeriodFraction, - ccv.DefaultCCVTimeoutPeriod, - types.DefaultInitTimeoutPeriod, - types.DefaultVscTimeoutPeriod, - types.DefaultSlashMeterReplenishPeriod, - "1.15", - -1, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), + sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), nil, nil, nil, @@ -712,7 +685,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", 400, 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: sdk.NewInt(10000000)}), nil, nil, nil, @@ -733,7 +706,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", 400, 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: sdk.NewInt(-1000000)}), nil, nil, nil, diff --git a/x/ccv/provider/types/keys.go b/x/ccv/provider/types/keys.go index ee4c11015b..d2845d094a 100644 --- a/x/ccv/provider/types/keys.go +++ b/x/ccv/provider/types/keys.go @@ -138,6 +138,13 @@ const ( // handled in the current block VSCMaturedHandledThisBlockBytePrefix + // EquivocationEvidenceMinHeightBytePrefix is the byte prefix storing the mapping from consumer chain IDs + // to the minimum height of a valid consumer equivocation evidence + EquivocationEvidenceMinHeightBytePrefix + + // ProposedConsumerChainByteKey is the byte prefix storing the consumer chainId in consumerAddition gov proposal submitted before voting finishes + ProposedConsumerChainByteKey + // NOTE: DO NOT ADD NEW BYTE PREFIXES HERE WITHOUT ADDING THEM TO getAllKeyPrefixes() IN keys_test.go ) @@ -377,6 +384,12 @@ func ConsumerRewardDenomsKey(denom string) []byte { return append([]byte{ConsumerRewardDenomsBytePrefix}, []byte(denom)...) } +// EquivocationEvidenceMinHeightKey returns the key storing the minimum height +// of a valid consumer equivocation evidence for a given consumer chain ID +func EquivocationEvidenceMinHeightKey(consumerChainID string) []byte { + return append([]byte{EquivocationEvidenceMinHeightBytePrefix}, []byte(consumerChainID)...) +} + // NOTE: DO NOT ADD FULLY DEFINED KEY FUNCTIONS WITHOUT ADDING THEM TO getAllFullyDefinedKeys() IN keys_test.go // @@ -484,6 +497,26 @@ func VSCMaturedHandledThisBlockKey() []byte { return []byte{VSCMaturedHandledThisBlockBytePrefix} } +// ProposedConsumerChainKey returns the key of proposed consumer chainId in consumerAddition gov proposal before voting finishes, the stored key format is prefix|proposalID, value is chainID +func ProposedConsumerChainKey(proposalID uint64) []byte { + return ccvtypes.AppendMany( + []byte{ProposedConsumerChainByteKey}, + sdk.Uint64ToBigEndian(proposalID), + ) +} + +// ParseProposedConsumerChainKey get the proposalID in the key +func ParseProposedConsumerChainKey(prefix byte, bz []byte) (uint64, error) { + expectedPrefix := []byte{prefix} + prefixL := len(expectedPrefix) + if prefix := bz[:prefixL]; !bytes.Equal(prefix, expectedPrefix) { + return 0, fmt.Errorf("invalid prefix; expected: %X, got: %X", expectedPrefix, prefix) + } + proposalID := sdk.BigEndianToUint64(bz[prefixL:]) + + return proposalID, nil +} + // // End of generic helpers section // diff --git a/x/ccv/provider/types/keys_test.go b/x/ccv/provider/types/keys_test.go index 9f470f4a82..c1c9394764 100644 --- a/x/ccv/provider/types/keys_test.go +++ b/x/ccv/provider/types/keys_test.go @@ -54,6 +54,8 @@ func getAllKeyPrefixes() []byte { providertypes.ConsumerAddrsToPruneBytePrefix, providertypes.SlashLogBytePrefix, providertypes.VSCMaturedHandledThisBlockBytePrefix, + providertypes.EquivocationEvidenceMinHeightBytePrefix, + providertypes.ProposedConsumerChainByteKey, } } @@ -98,6 +100,7 @@ func getAllFullyDefinedKeys() [][]byte { providertypes.ConsumerAddrsToPruneKey("chainID", 88), providertypes.SlashLogKey(providertypes.NewProviderConsAddress([]byte{0x05})), providertypes.VSCMaturedHandledThisBlockKey(), + providertypes.EquivocationEvidenceMinHeightKey("chainID"), } } @@ -309,3 +312,22 @@ func TestKeysWithUint64Payload(t *testing.T) { } } } + +func TestParseProposedConsumerChainKey(t *testing.T) { + tests := []struct { + chainID string + proposalID uint64 + }{ + {chainID: "1", proposalID: 1}, + {chainID: "some other ID", proposalID: 12}, + {chainID: "some other other chain ID", proposalID: 123}, + } + + for _, test := range tests { + key := providertypes.ProposedConsumerChainKey(test.proposalID) + pID, err := providertypes.ParseProposedConsumerChainKey( + providertypes.ProposedConsumerChainByteKey, key) + require.NoError(t, err) + require.Equal(t, pID, test.proposalID) + } +} diff --git a/x/ccv/provider/types/msg.go b/x/ccv/provider/types/msg.go index 901aa03600..f7ee11325c 100644 --- a/x/ccv/provider/types/msg.go +++ b/x/ccv/provider/types/msg.go @@ -2,17 +2,33 @@ package types import ( "encoding/json" + "fmt" "strings" + ibctmtypes "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" + + errorsmod "cosmossdk.io/errors" + 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/v3/x/ccv/types" ) // provider message types const ( - TypeMsgAssignConsumerKey = "assign_consumer_key" + TypeMsgAssignConsumerKey = "assign_consumer_key" + TypeMsgSubmitConsumerMisbehaviour = "submit_consumer_misbehaviour" + TypeMsgSubmitConsumerDoubleVoting = "submit_consumer_double_vote" ) -var _ sdk.Msg = &MsgAssignConsumerKey{} +var ( + _ sdk.Msg = &MsgAssignConsumerKey{} + _ sdk.Msg = &MsgSubmitConsumerMisbehaviour{} + _ sdk.Msg = &MsgSubmitConsumerDoubleVoting{} +) // NewMsgAssignConsumerKey creates a new MsgAssignConsumerKey instance. // Delegator address and validator address are the same. @@ -49,7 +65,7 @@ func (msg MsgAssignConsumerKey) GetSigners() []sdk.AccAddress { // GetSignBytes returns the message bytes to sign over. func (msg MsgAssignConsumerKey) GetSignBytes() []byte { - bz := ModuleCdc.MustMarshalJSON(&msg) + bz := ccvtypes.ModuleCdc.MustMarshalJSON(&msg) return sdk.MustSortJSON(bz) } @@ -61,8 +77,7 @@ func (msg MsgAssignConsumerKey) ValidateBasic() error { // 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. - // TODO: In future, a mechanism will be added to limit assigning keys to chains - // which are approved or pending approval, only. + if 128 < len(msg.ChainId) { return ErrBlankConsumerChainID } @@ -93,3 +108,99 @@ func ParseConsumerKeyFromJson(jsonStr string) (pkType, key string, err error) { } return pubKey.Type, pubKey.Key, nil } + +func NewMsgSubmitConsumerMisbehaviour(submitter sdk.AccAddress, misbehaviour *ibctmtypes.Misbehaviour) (*MsgSubmitConsumerMisbehaviour, error) { + return &MsgSubmitConsumerMisbehaviour{Submitter: submitter.String(), Misbehaviour: misbehaviour}, nil +} + +// Route implements the sdk.Msg interface. +func (msg MsgSubmitConsumerMisbehaviour) Route() string { return RouterKey } + +// Type implements the sdk.Msg interface. +func (msg MsgSubmitConsumerMisbehaviour) Type() string { + return TypeMsgSubmitConsumerMisbehaviour +} + +// Type implements the sdk.Msg interface. +func (msg MsgSubmitConsumerMisbehaviour) ValidateBasic() error { + if msg.Submitter == "" { + return errorsmod.Wrap(sdkerrors.ErrInvalidAddress, msg.Submitter) + } + + if err := msg.Misbehaviour.ValidateBasic(); err != nil { + return err + } + return nil +} + +// Type implements the sdk.Msg interface. +func (msg MsgSubmitConsumerMisbehaviour) GetSignBytes() []byte { + bz := ccvtypes.ModuleCdc.MustMarshalJSON(&msg) + return sdk.MustSortJSON(bz) +} + +// Type implements the sdk.Msg interface. +func (msg MsgSubmitConsumerMisbehaviour) GetSigners() []sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(msg.Submitter) + if err != nil { + // same behavior as in cosmos-sdk + panic(err) + } + return []sdk.AccAddress{addr} +} + +func NewMsgSubmitConsumerDoubleVoting(submitter sdk.AccAddress, ev *tmtypes.DuplicateVoteEvidence, header *ibctmtypes.Header) (*MsgSubmitConsumerDoubleVoting, error) { + return &MsgSubmitConsumerDoubleVoting{Submitter: submitter.String(), DuplicateVoteEvidence: ev, InfractionBlockHeader: header}, nil +} + +// Route implements the sdk.Msg interface. +func (msg MsgSubmitConsumerDoubleVoting) Route() string { return RouterKey } + +// Type implements the sdk.Msg interface. +func (msg MsgSubmitConsumerDoubleVoting) Type() string { + return TypeMsgSubmitConsumerDoubleVoting +} + +// Type implements the sdk.Msg interface. +func (msg MsgSubmitConsumerDoubleVoting) ValidateBasic() error { + if msg.Submitter == "" { + return errorsmod.Wrap(sdkerrors.ErrInvalidAddress, msg.Submitter) + } + if msg.DuplicateVoteEvidence == nil { + return fmt.Errorf("double voting evidence cannot be nil") + } + + if msg.InfractionBlockHeader == nil { + return fmt.Errorf("infraction block header cannot be nil") + } + + if msg.InfractionBlockHeader.SignedHeader == nil { + return fmt.Errorf("signed header in infraction block header cannot be nil") + } + + if msg.InfractionBlockHeader.SignedHeader.Header == nil { + return fmt.Errorf("invalid signed header in infraction block header, 'SignedHeader.Header' is nil") + } + + if msg.InfractionBlockHeader.ValidatorSet == nil { + return fmt.Errorf("invalid infraction block header, validator set is nil") + } + + return nil +} + +// Type implements the sdk.Msg interface. +func (msg MsgSubmitConsumerDoubleVoting) GetSignBytes() []byte { + bz := ccvtypes.ModuleCdc.MustMarshalJSON(&msg) + return sdk.MustSortJSON(bz) +} + +// Type implements the sdk.Msg interface. +func (msg MsgSubmitConsumerDoubleVoting) GetSigners() []sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(msg.Submitter) + if err != nil { + // same behavior as in cosmos-sdk + panic(err) + } + return []sdk.AccAddress{addr} +} diff --git a/x/ccv/provider/types/params.go b/x/ccv/provider/types/params.go index afb46694a3..fb6b0c267e 100644 --- a/x/ccv/provider/types/params.go +++ b/x/ccv/provider/types/params.go @@ -36,10 +36,6 @@ const ( // 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. DefaultSlashMeterReplenishFraction = "0.05" - - // DefaultMaxThrottledPackets defines the default amount of throttled slash or vsc matured packets - // that can be queued for a single consumer before the provider chain halts. - DefaultMaxThrottledPackets = 100000 ) // Reflection based keys for params subspace @@ -50,7 +46,6 @@ var ( KeyVscTimeoutPeriod = []byte("VscTimeoutPeriod") KeySlashMeterReplenishPeriod = []byte("SlashMeterReplenishPeriod") KeySlashMeterReplenishFraction = []byte("SlashMeterReplenishFraction") - KeyMaxThrottledPackets = []byte("MaxThrottledPackets") KeyConsumerRewardDenomRegistrationFee = []byte("ConsumerRewardDenomRegistrationFee") ) @@ -68,7 +63,6 @@ func NewParams( vscTimeoutPeriod time.Duration, slashMeterReplenishPeriod time.Duration, slashMeterReplenishFraction string, - maxThrottledPackets int64, consumerRewardDenomRegistrationFee sdk.Coin, ) Params { return Params{ @@ -79,7 +73,6 @@ func NewParams( VscTimeoutPeriod: vscTimeoutPeriod, SlashMeterReplenishPeriod: slashMeterReplenishPeriod, SlashMeterReplenishFraction: slashMeterReplenishFraction, - MaxThrottledPackets: maxThrottledPackets, ConsumerRewardDenomRegistrationFee: consumerRewardDenomRegistrationFee, } } @@ -105,7 +98,6 @@ func DefaultParams() Params { DefaultVscTimeoutPeriod, DefaultSlashMeterReplenishPeriod, DefaultSlashMeterReplenishFraction, - DefaultMaxThrottledPackets, // Defining this inline because it's not possible to define a constant of type sdk.Coin. // Following the pattern from cosmos-sdk/staking/types/params.go sdk.Coin{ @@ -141,9 +133,6 @@ func (p Params) Validate() error { if err := ccvtypes.ValidateStringFraction(p.SlashMeterReplenishFraction); err != nil { return fmt.Errorf("slash meter replenish fraction is invalid: %s", err) } - if err := ccvtypes.ValidatePositiveInt64(p.MaxThrottledPackets); err != nil { - return fmt.Errorf("max throttled packets is invalid: %s", err) - } if err := ValidateCoin(p.ConsumerRewardDenomRegistrationFee); err != nil { return fmt.Errorf("consumer reward denom registration fee is invalid: %s", err) } @@ -160,7 +149,6 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { paramtypes.NewParamSetPair(KeyVscTimeoutPeriod, p.VscTimeoutPeriod, ccvtypes.ValidateDuration), paramtypes.NewParamSetPair(KeySlashMeterReplenishPeriod, p.SlashMeterReplenishPeriod, ccvtypes.ValidateDuration), paramtypes.NewParamSetPair(KeySlashMeterReplenishFraction, p.SlashMeterReplenishFraction, ccvtypes.ValidateStringFraction), - paramtypes.NewParamSetPair(KeyMaxThrottledPackets, p.MaxThrottledPackets, ccvtypes.ValidatePositiveInt64), paramtypes.NewParamSetPair(KeyConsumerRewardDenomRegistrationFee, p.ConsumerRewardDenomRegistrationFee, ValidateCoin), } } diff --git a/x/ccv/provider/types/params_test.go b/x/ccv/provider/types/params_test.go index 0676a15986..6e8bd780bf 100644 --- a/x/ccv/provider/types/params_test.go +++ b/x/ccv/provider/types/params_test.go @@ -24,42 +24,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", 100, 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: sdk.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", 100, 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: sdk.NewInt(10000000)}), false}, {"blank client", types.NewParams(&ibctmtypes.ClientState{}, - "0.33", time.Hour, time.Hour, time.Hour, 30*time.Minute, "0.1", 100, 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", 100, 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: 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}, // 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", 100, 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: sdk.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", 100, 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: sdk.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", 100, 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: sdk.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", 100, 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: sdk.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", 100, 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: sdk.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", 100, sdk.Coin{Denom: "stake", Amount: sdk.NewInt(10000000)}), false}, - {"negative max pending slash packets", 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", -100, 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: sdk.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", -100, 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: sdk.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", -100, 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: sdk.NewInt(-10000000)}), false}, } for _, tc := range testCases { diff --git a/x/ccv/provider/types/proposal.go b/x/ccv/provider/types/proposal.go index b2286d4adf..d1755852ef 100644 --- a/x/ccv/provider/types/proposal.go +++ b/x/ccv/provider/types/proposal.go @@ -27,15 +27,15 @@ const ( var ( _ govv1beta1.Content = &ConsumerAdditionProposal{} _ govv1beta1.Content = &ConsumerRemovalProposal{} - _ govv1beta1.Content = &EquivocationProposal{} _ govv1beta1.Content = &ChangeRewardDenomsProposal{} + _ govv1beta1.Content = &EquivocationProposal{} ) func init() { govv1beta1.RegisterProposalType(ProposalTypeConsumerAddition) govv1beta1.RegisterProposalType(ProposalTypeConsumerRemoval) - govv1beta1.RegisterProposalType(ProposalTypeEquivocation) govv1beta1.RegisterProposalType(ProposalTypeChangeRewardDenoms) + govv1beta1.RegisterProposalType(ProposalTypeEquivocation) } // NewConsumerAdditionProposal creates a new consumer addition proposal. @@ -204,6 +204,8 @@ func (sccp *ConsumerRemovalProposal) ValidateBasic() error { } // NewEquivocationProposal creates a new equivocation proposal. +// [DEPRECATED]: do not use because equivocations can be submitted +// and verified automatically on the provider. func NewEquivocationProposal(title, description string, equivocations []*evidencetypes.Equivocation) govv1beta1.Content { return &EquivocationProposal{ Title: title, diff --git a/x/ccv/provider/types/proposal_test.go b/x/ccv/provider/types/proposal_test.go index 357c555d0e..d8f10766dd 100644 --- a/x/ccv/provider/types/proposal_test.go +++ b/x/ccv/provider/types/proposal_test.go @@ -12,7 +12,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" @@ -307,62 +306,6 @@ func TestConsumerAdditionProposalString(t *testing.T) { require.Equal(t, expect, proposal.String(), "string method for ConsumerAdditionProposal returned unexpected string") } -func TestEquivocationProposalValidateBasic(t *testing.T) { - tests := []struct { - name string - proposal govv1beta1.Content - expectedError string - }{ - { - name: "fail: validate abstract - empty title", - proposal: types.NewEquivocationProposal("", "", nil), - expectedError: "proposal title cannot be blank: invalid proposal content", - }, - { - name: "fail: equivocations is empty", - proposal: types.NewEquivocationProposal("title", "desc", nil), - expectedError: "invalid equivocation proposal: empty equivocations", - }, - { - name: "fail: invalid equivocation", - proposal: types.NewEquivocationProposal("title", "desc", - []*evidencetypes.Equivocation{ - { - Time: time.Now(), - Height: 1, - Power: 1, - ConsensusAddress: "addr", - }, - {}, // invalid one - }), - expectedError: "invalid equivocation time: 0001-01-01 00:00:00 +0000 UTC", - }, - { - name: "ok", - proposal: types.NewEquivocationProposal("title", "desc", - []*evidencetypes.Equivocation{ - { - Time: time.Now(), - Height: 1, - Power: 1, - ConsensusAddress: "addr", - }, - }), - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.proposal.ValidateBasic() - - if tt.expectedError != "" { - require.EqualError(t, err, tt.expectedError) - return - } - require.NoError(t, err) - }) - } -} - func TestChangeRewardDenomsProposalValidateBasic(t *testing.T) { tcs := []struct { name string diff --git a/x/ccv/provider/types/provider.pb.go b/x/ccv/provider/types/provider.pb.go index ef0aa6e5e1..e251053ef9 100644 --- a/x/ccv/provider/types/provider.pb.go +++ b/x/ccv/provider/types/provider.pb.go @@ -205,6 +205,10 @@ func (m *ConsumerRemovalProposal) GetStopTime() time.Time { // punish a validator for equivocation on a consumer chain. // // This type is only used internally to the consumer CCV module. +// WARNING: This message is deprecated now that equivocations can be submitted +// and verified automatically on the provider. (see SubmitConsumerDoubleVoting in proto/interchain-security/ccv/provider/v1/tx.proto). +// +// Deprecated: Do not use. type EquivocationProposal struct { // the title of the proposal Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` @@ -445,9 +449,6 @@ type Params struct { // every replenish period. This param also serves as a maximum fraction of // total voting power that the slash meter can hold. SlashMeterReplenishFraction string `protobuf:"bytes,7,opt,name=slash_meter_replenish_fraction,json=slashMeterReplenishFraction,proto3" json:"slash_meter_replenish_fraction,omitempty"` - // The maximum amount of throttled slash or vsc matured packets - // that can be queued for a single consumer before the provider chain halts. - MaxThrottledPackets int64 `protobuf:"varint,8,opt,name=max_throttled_packets,json=maxThrottledPackets,proto3" json:"max_throttled_packets,omitempty"` // The fee required to be paid to add a reward denom ConsumerRewardDenomRegistrationFee types2.Coin `protobuf:"bytes,9,opt,name=consumer_reward_denom_registration_fee,json=consumerRewardDenomRegistrationFee,proto3" json:"consumer_reward_denom_registration_fee"` } @@ -534,13 +535,6 @@ func (m *Params) GetSlashMeterReplenishFraction() string { return "" } -func (m *Params) GetMaxThrottledPackets() int64 { - if m != nil { - return m.MaxThrottledPackets - } - return 0 -} - func (m *Params) GetConsumerRewardDenomRegistrationFee() types2.Coin { if m != nil { return m.ConsumerRewardDenomRegistrationFee @@ -733,6 +727,7 @@ func (m *AddressList) GetAddresses() [][]byte { return nil } +// ChannelToChain is used to map a CCV channel ID to the consumer chainID type ChannelToChain struct { ChannelId string `protobuf:"bytes,1,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty"` ChainId string `protobuf:"bytes,2,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` @@ -1420,115 +1415,113 @@ func init() { } var fileDescriptor_f22ec409a72b7b72 = []byte{ - // 1723 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0x4b, 0x73, 0x1b, 0xc7, - 0x11, 0xe6, 0x12, 0x20, 0x45, 0x34, 0xf8, 0xd2, 0x92, 0xb2, 0x40, 0x85, 0x01, 0xa9, 0x75, 0xec, - 0x30, 0xe5, 0xf2, 0xc2, 0xa4, 0x2a, 0x55, 0x2e, 0x55, 0x5c, 0x2e, 0x12, 0x94, 0x2d, 0x9a, 0xb1, - 0x45, 0x2f, 0x19, 0xaa, 0x92, 0x1c, 0xb6, 0x06, 0x33, 0x23, 0x60, 0x8a, 0xbb, 0x3b, 0xab, 0x99, - 0xc1, 0x4a, 0xb8, 0xe4, 0x9c, 0xa3, 0x73, 0x73, 0x25, 0x17, 0x27, 0x7f, 0x20, 0x7f, 0xc3, 0x47, - 0x1f, 0x73, 0xb2, 0x53, 0xd2, 0x21, 0x87, 0xfc, 0x89, 0xd4, 0xcc, 0x3e, 0x01, 0x3e, 0x02, 0x95, - 0x93, 0xdb, 0xa2, 0xa7, 0xfb, 0xeb, 0x9e, 0x7e, 0x7c, 0x3d, 0x24, 0xec, 0xb1, 0x48, 0x51, 0x81, - 0x07, 0x88, 0x45, 0xbe, 0xa4, 0x78, 0x28, 0x98, 0x1a, 0x75, 0x30, 0x4e, 0x3a, 0xb1, 0xe0, 0x09, - 0x23, 0x54, 0x74, 0x92, 0xdd, 0xe2, 0xdb, 0x8d, 0x05, 0x57, 0xdc, 0x7e, 0xfb, 0x0a, 0x1b, 0x17, - 0xe3, 0xc4, 0x2d, 0xf4, 0x92, 0xdd, 0x7b, 0x1f, 0x5c, 0x07, 0x9c, 0xec, 0x76, 0xe4, 0x00, 0x09, - 0x4a, 0x7c, 0xcc, 0x23, 0x39, 0x0c, 0x73, 0xd8, 0x7b, 0xef, 0xdc, 0x60, 0xf1, 0x82, 0x09, 0x9a, - 0xa9, 0xad, 0xf7, 0x79, 0x9f, 0x9b, 0xcf, 0x8e, 0xfe, 0xca, 0xa4, 0x5b, 0x7d, 0xce, 0xfb, 0x01, - 0xed, 0x98, 0x5f, 0xbd, 0xe1, 0xb3, 0x8e, 0x62, 0x21, 0x95, 0x0a, 0x85, 0x71, 0xa6, 0xd0, 0x9e, - 0x54, 0x20, 0x43, 0x81, 0x14, 0xe3, 0x51, 0x0e, 0xc0, 0x7a, 0xb8, 0x83, 0xb9, 0xa0, 0x1d, 0x1c, - 0x30, 0x1a, 0x29, 0xed, 0x35, 0xfd, 0xca, 0x14, 0x3a, 0x5a, 0x21, 0x60, 0xfd, 0x81, 0x4a, 0xc5, - 0xb2, 0xa3, 0x68, 0x44, 0xa8, 0x08, 0x59, 0xaa, 0x5c, 0xfe, 0xca, 0x0c, 0x36, 0x2b, 0xe7, 0x58, - 0x8c, 0x62, 0xc5, 0x3b, 0x17, 0x74, 0x24, 0xb3, 0xd3, 0x77, 0x31, 0x97, 0x21, 0x97, 0x1d, 0xaa, - 0x33, 0x16, 0x61, 0xda, 0x49, 0x76, 0x7b, 0x54, 0xa1, 0xdd, 0x42, 0x90, 0xc7, 0x9d, 0xe9, 0xf5, - 0x90, 0x2c, 0x75, 0x30, 0x67, 0x59, 0xdc, 0xce, 0x0f, 0xf3, 0xd0, 0xea, 0x66, 0x89, 0xdc, 0x27, - 0x84, 0xe9, 0x2b, 0x9d, 0x08, 0x1e, 0x73, 0x89, 0x02, 0x7b, 0x1d, 0xe6, 0x14, 0x53, 0x01, 0x6d, - 0x59, 0xdb, 0xd6, 0x4e, 0xc3, 0x4b, 0x7f, 0xd8, 0xdb, 0xd0, 0x24, 0x54, 0x62, 0xc1, 0x62, 0xad, - 0xdc, 0x9a, 0x35, 0x67, 0x55, 0x91, 0xbd, 0x01, 0x0b, 0x69, 0x1d, 0x18, 0x69, 0xd5, 0xcc, 0xf1, - 0x2d, 0xf3, 0xfb, 0x88, 0xd8, 0x9f, 0xc2, 0x32, 0x8b, 0x98, 0x62, 0x28, 0xf0, 0x07, 0x54, 0x67, - 0xa3, 0x55, 0xdf, 0xb6, 0x76, 0x9a, 0x7b, 0xf7, 0x5c, 0xd6, 0xc3, 0xae, 0x4e, 0xa0, 0x9b, 0xa5, - 0x2d, 0xd9, 0x75, 0x1f, 0x1b, 0x8d, 0x83, 0xfa, 0xb7, 0xdf, 0x6f, 0xcd, 0x78, 0x4b, 0x99, 0x5d, - 0x2a, 0xb4, 0xef, 0xc3, 0x62, 0x9f, 0x46, 0x54, 0x32, 0xe9, 0x0f, 0x90, 0x1c, 0xb4, 0xe6, 0xb6, - 0xad, 0x9d, 0x45, 0xaf, 0x99, 0xc9, 0x1e, 0x23, 0x39, 0xb0, 0xb7, 0xa0, 0xd9, 0x63, 0x11, 0x12, - 0xa3, 0x54, 0x63, 0xde, 0x68, 0x40, 0x2a, 0x32, 0x0a, 0x5d, 0x00, 0x19, 0xa3, 0x17, 0x91, 0xaf, - 0xab, 0xdd, 0xba, 0x95, 0x05, 0x92, 0x56, 0xda, 0xcd, 0x2b, 0xed, 0x9e, 0xe5, 0xad, 0x70, 0xb0, - 0xa0, 0x03, 0xf9, 0xea, 0x87, 0x2d, 0xcb, 0x6b, 0x18, 0x3b, 0x7d, 0x62, 0x7f, 0x01, 0xab, 0xc3, - 0xa8, 0xc7, 0x23, 0xc2, 0xa2, 0xbe, 0x1f, 0x53, 0xc1, 0x38, 0x69, 0x2d, 0x18, 0xa8, 0x8d, 0x4b, - 0x50, 0x87, 0x59, 0xd3, 0xa4, 0x48, 0x5f, 0x6b, 0xa4, 0x95, 0xc2, 0xf8, 0xc4, 0xd8, 0xda, 0x5f, - 0x82, 0x8d, 0x71, 0x62, 0x42, 0xe2, 0x43, 0x95, 0x23, 0x36, 0xa6, 0x47, 0x5c, 0xc5, 0x38, 0x39, - 0x4b, 0xad, 0x33, 0xc8, 0xdf, 0xc3, 0x5d, 0x25, 0x50, 0x24, 0x9f, 0x51, 0x31, 0x89, 0x0b, 0xd3, - 0xe3, 0xde, 0xc9, 0x31, 0xc6, 0xc1, 0x1f, 0xc3, 0x76, 0x3e, 0x89, 0xbe, 0xa0, 0x84, 0x49, 0x25, - 0x58, 0x6f, 0xa8, 0x6d, 0xfd, 0x67, 0x02, 0x61, 0xd3, 0x23, 0x4d, 0xd3, 0x04, 0xed, 0x5c, 0xcf, - 0x1b, 0x53, 0xfb, 0x24, 0xd3, 0xb2, 0x9f, 0xc0, 0xcf, 0x7a, 0x01, 0xc7, 0x17, 0x52, 0x07, 0xe7, - 0x8f, 0x21, 0x19, 0xd7, 0x21, 0x93, 0x52, 0xa3, 0x2d, 0x6e, 0x5b, 0x3b, 0x35, 0xef, 0x7e, 0xaa, - 0x7b, 0x42, 0xc5, 0x61, 0x45, 0xf3, 0xac, 0xa2, 0x68, 0xbf, 0x0f, 0xf6, 0x80, 0x49, 0xc5, 0x05, - 0xc3, 0x28, 0xf0, 0x69, 0xa4, 0x04, 0xa3, 0xb2, 0xb5, 0x64, 0xcc, 0x6f, 0x97, 0x27, 0x8f, 0xd2, - 0x03, 0xfb, 0x33, 0xb8, 0x7f, 0xad, 0x53, 0x1f, 0x0f, 0x50, 0x14, 0xd1, 0xa0, 0xb5, 0x6c, 0xae, - 0xb2, 0x45, 0xae, 0xf1, 0xd9, 0x4d, 0xd5, 0x1e, 0x2e, 0xfc, 0xf1, 0x9b, 0xad, 0x99, 0xaf, 0xbf, - 0xd9, 0x9a, 0x71, 0xfe, 0x6e, 0xc1, 0xdd, 0x6e, 0x71, 0xf1, 0x90, 0x27, 0x28, 0xf8, 0x7f, 0x0e, - 0xd8, 0x3e, 0x34, 0xa4, 0xe2, 0x71, 0xda, 0xd2, 0xf5, 0x37, 0x68, 0xe9, 0x05, 0x6d, 0xa6, 0x0f, - 0x9c, 0xbf, 0x58, 0xb0, 0xfe, 0xe8, 0xf9, 0x90, 0x25, 0x1c, 0xa3, 0xff, 0x09, 0x1f, 0x1c, 0xc3, - 0x12, 0xad, 0xe0, 0xc9, 0x56, 0x6d, 0xbb, 0xb6, 0xd3, 0xdc, 0x7b, 0xc7, 0x4d, 0xc9, 0xc9, 0x2d, - 0x38, 0x2b, 0x23, 0x28, 0xb7, 0xea, 0xdd, 0x1b, 0xb7, 0x75, 0xfe, 0x66, 0xc1, 0x3d, 0x9d, 0xe5, - 0x3e, 0xf5, 0xe8, 0x0b, 0x24, 0xc8, 0x21, 0x8d, 0x78, 0x28, 0x7f, 0x74, 0x8c, 0x0e, 0x2c, 0x11, - 0x83, 0xe4, 0x2b, 0xee, 0x23, 0x42, 0x4c, 0x8c, 0x46, 0x47, 0x0b, 0xcf, 0xf8, 0x3e, 0x21, 0xf6, - 0x0e, 0xac, 0x96, 0x3a, 0x42, 0xd7, 0x52, 0xa7, 0x58, 0xab, 0x2d, 0xe7, 0x6a, 0xa6, 0xc2, 0xd4, - 0xf9, 0xb7, 0x05, 0xab, 0x9f, 0x06, 0xbc, 0x87, 0x82, 0xd3, 0x00, 0xc9, 0x81, 0xee, 0xb0, 0x91, - 0x2e, 0x8d, 0xa0, 0xd9, 0x68, 0x9b, 0xf0, 0xa6, 0x2e, 0x8d, 0x36, 0x33, 0x64, 0xf3, 0x31, 0xdc, - 0x2e, 0x86, 0xad, 0xe8, 0x00, 0x73, 0x9b, 0x83, 0xb5, 0x57, 0xdf, 0x6f, 0xad, 0xe4, 0x8d, 0xd6, - 0x35, 0xdd, 0x70, 0xe8, 0xad, 0xe0, 0x31, 0x01, 0xb1, 0xdb, 0xd0, 0x64, 0x3d, 0xec, 0x4b, 0xfa, - 0xdc, 0x8f, 0x86, 0xa1, 0x69, 0x9e, 0xba, 0xd7, 0x60, 0x3d, 0x7c, 0x4a, 0x9f, 0x7f, 0x31, 0x0c, - 0xed, 0x07, 0xf0, 0x56, 0xbe, 0x86, 0xfd, 0x04, 0x05, 0x66, 0xc9, 0xea, 0x74, 0x08, 0xd3, 0x4b, - 0x8b, 0xde, 0x5a, 0x7e, 0x7a, 0x8e, 0x02, 0xed, 0x6c, 0x9f, 0x10, 0xe1, 0xfc, 0x6b, 0x0e, 0xe6, - 0x4f, 0x90, 0x40, 0xa1, 0xb4, 0xcf, 0x60, 0x45, 0xd1, 0x30, 0x0e, 0x90, 0xa2, 0x7e, 0x4a, 0xe4, - 0xd9, 0x4d, 0xdf, 0x33, 0x04, 0x5f, 0x5d, 0x80, 0x6e, 0x65, 0xe5, 0x25, 0xbb, 0x6e, 0xd7, 0x48, - 0x4f, 0x15, 0x52, 0xd4, 0x5b, 0xce, 0x31, 0x52, 0xa1, 0xfd, 0x21, 0xb4, 0x94, 0x18, 0x4a, 0x55, - 0x52, 0x6c, 0xc9, 0x2d, 0x69, 0x2d, 0xdf, 0xca, 0xcf, 0x53, 0x56, 0x2a, 0x38, 0xe5, 0x6a, 0x36, - 0xad, 0xfd, 0x18, 0x36, 0x3d, 0x85, 0x35, 0xbd, 0x8a, 0x26, 0x31, 0xeb, 0xd3, 0x63, 0xde, 0xd6, - 0xf6, 0xe3, 0xa0, 0x5f, 0x82, 0x9d, 0x48, 0x3c, 0x89, 0x39, 0xf7, 0x06, 0x71, 0x26, 0x12, 0x8f, - 0x43, 0x12, 0xd8, 0x94, 0xba, 0xf9, 0xfc, 0x90, 0x2a, 0xc3, 0xcd, 0x71, 0x40, 0x23, 0x26, 0x07, - 0x39, 0xf8, 0xfc, 0xf4, 0xe0, 0x1b, 0x06, 0xe8, 0x73, 0x8d, 0xe3, 0xe5, 0x30, 0x99, 0x97, 0x2e, - 0xb4, 0xaf, 0xf6, 0x52, 0x14, 0xe8, 0x96, 0x29, 0xd0, 0x4f, 0xae, 0x80, 0x28, 0xaa, 0xb4, 0x07, - 0x77, 0x42, 0xf4, 0xd2, 0x57, 0x03, 0xc1, 0x95, 0x0a, 0x28, 0xf1, 0x63, 0x84, 0x2f, 0xa8, 0x92, - 0x66, 0x91, 0xd6, 0xbc, 0xb5, 0x10, 0xbd, 0x3c, 0xcb, 0xcf, 0x4e, 0xd2, 0x23, 0x5b, 0xc2, 0xbb, - 0x95, 0xbd, 0xa3, 0x99, 0xc0, 0x37, 0x43, 0xe8, 0x0b, 0xda, 0xd7, 0xe4, 0x8c, 0xd2, 0x15, 0x44, - 0x69, 0xb1, 0x3b, 0x33, 0xb6, 0xd1, 0x4f, 0xa1, 0x82, 0x69, 0xba, 0x9c, 0x45, 0xd9, 0x03, 0xc3, - 0x29, 0xd7, 0x53, 0xc1, 0x2b, 0x5e, 0x05, 0xeb, 0x13, 0x4a, 0x9d, 0x5f, 0x40, 0xc3, 0x0c, 0xf4, - 0x3e, 0xbe, 0x90, 0xf6, 0x26, 0x34, 0xf4, 0x64, 0x50, 0x29, 0xa9, 0x6c, 0x59, 0x86, 0x07, 0x4a, - 0x81, 0xa3, 0x60, 0xe3, 0xba, 0x87, 0x95, 0xb4, 0x9f, 0xc2, 0xad, 0x98, 0x9a, 0xad, 0x6f, 0x0c, - 0x9b, 0x7b, 0x1f, 0xb9, 0x53, 0xbc, 0x8a, 0xdd, 0xeb, 0x00, 0xbd, 0x1c, 0xcd, 0x11, 0xe5, 0x73, - 0x6e, 0x62, 0xd9, 0x48, 0xfb, 0x7c, 0xd2, 0xe9, 0xaf, 0xde, 0xc8, 0xe9, 0x04, 0x5e, 0xe9, 0xf3, - 0x3d, 0x68, 0xee, 0xa7, 0xd7, 0xfe, 0x35, 0x93, 0xea, 0x72, 0x5a, 0x16, 0xab, 0x69, 0xf9, 0x0c, - 0x96, 0xb3, 0x1d, 0x79, 0xc6, 0x0d, 0x29, 0xd9, 0x3f, 0x05, 0xc8, 0x96, 0xab, 0x26, 0xb3, 0x94, - 0xb6, 0x1b, 0x99, 0xe4, 0x88, 0x8c, 0xed, 0xba, 0xd9, 0xb1, 0x5d, 0xe7, 0x78, 0xb0, 0x72, 0x2e, - 0xf1, 0x6f, 0xf2, 0x07, 0xd4, 0x93, 0x58, 0xda, 0x77, 0x60, 0x5e, 0xcf, 0x51, 0x06, 0x54, 0xf7, - 0xe6, 0x12, 0x89, 0x8f, 0x0c, 0x73, 0x97, 0x8f, 0x34, 0x1e, 0xfb, 0x8c, 0xc8, 0xd6, 0xec, 0x76, - 0x6d, 0xa7, 0xee, 0x2d, 0x0f, 0x4b, 0xf3, 0x23, 0x22, 0x9d, 0xdf, 0x42, 0xb3, 0x02, 0x68, 0x2f, - 0xc3, 0x6c, 0x81, 0x35, 0xcb, 0x88, 0xfd, 0x10, 0x36, 0x4a, 0xa0, 0x71, 0x2a, 0x4e, 0x11, 0x1b, - 0xde, 0xdd, 0x42, 0x61, 0x8c, 0x8d, 0xa5, 0xf3, 0x04, 0xd6, 0x8f, 0xca, 0xc1, 0x2f, 0x88, 0x7e, - 0xec, 0x86, 0xd6, 0xf8, 0x36, 0xdf, 0x84, 0x46, 0xf1, 0x97, 0x88, 0xb9, 0x7d, 0xdd, 0x2b, 0x05, - 0x4e, 0x08, 0xab, 0xe7, 0x12, 0x9f, 0xd2, 0x88, 0x94, 0x60, 0xd7, 0x24, 0xe0, 0x60, 0x12, 0x68, - 0xea, 0x97, 0x6e, 0xe9, 0x8e, 0xc3, 0xc6, 0x39, 0x0a, 0x18, 0x41, 0x8a, 0x8b, 0x53, 0xaa, 0xd2, - 0x25, 0x9c, 0x8f, 0xa3, 0x07, 0xf5, 0x80, 0x49, 0x95, 0x75, 0xd6, 0x87, 0xd7, 0x76, 0x56, 0xb2, - 0xeb, 0x5e, 0x07, 0x72, 0x88, 0x14, 0xca, 0x66, 0xd1, 0x60, 0x39, 0x3f, 0x87, 0xb5, 0xcf, 0x91, - 0x1a, 0x0a, 0x4a, 0xc6, 0x6a, 0xbc, 0x0a, 0x35, 0x5d, 0x3f, 0xcb, 0xd4, 0x4f, 0x7f, 0xea, 0x37, - 0x41, 0xeb, 0xd1, 0xcb, 0x98, 0x0b, 0x45, 0xc9, 0xa5, 0x8c, 0xdc, 0x90, 0xde, 0x0b, 0x58, 0xd3, - 0xc9, 0x92, 0x34, 0x22, 0x7e, 0x71, 0xcf, 0xb4, 0x8e, 0xcd, 0xbd, 0x5f, 0x4e, 0x35, 0x1d, 0x93, - 0xee, 0xb2, 0x0b, 0xdc, 0x4e, 0x26, 0xe4, 0xd2, 0xf9, 0x93, 0x05, 0xad, 0x63, 0x3a, 0xda, 0x97, - 0x92, 0xf5, 0xa3, 0x90, 0x46, 0x4a, 0xf3, 0x20, 0xc2, 0x54, 0x7f, 0xda, 0x6f, 0xc3, 0x52, 0xb1, - 0x77, 0xcd, 0xba, 0xb5, 0xcc, 0xba, 0x5d, 0xcc, 0x85, 0x7a, 0xc0, 0xec, 0x87, 0x00, 0xb1, 0xa0, - 0x89, 0x8f, 0xfd, 0x0b, 0x3a, 0xca, 0xaa, 0xb8, 0x59, 0x5d, 0xa3, 0xe9, 0xdf, 0x89, 0xee, 0xc9, - 0xb0, 0x17, 0x30, 0x7c, 0x4c, 0x47, 0xde, 0x82, 0xd6, 0xef, 0x1e, 0xd3, 0x91, 0x7e, 0x17, 0xc5, - 0xfc, 0x05, 0x15, 0x66, 0xf7, 0xd5, 0xbc, 0xf4, 0x87, 0xf3, 0x67, 0x0b, 0xee, 0x16, 0xe5, 0xc8, - 0xdb, 0xf5, 0x64, 0xd8, 0xd3, 0x16, 0x37, 0xe4, 0xed, 0x52, 0xb4, 0xb3, 0x57, 0x44, 0xfb, 0x31, - 0x2c, 0x16, 0x03, 0xa2, 0xe3, 0xad, 0x4d, 0x11, 0x6f, 0x33, 0xb7, 0x38, 0xa6, 0x23, 0xe7, 0x0f, - 0x95, 0xd8, 0x0e, 0x46, 0x15, 0xee, 0x13, 0xff, 0x25, 0xb6, 0xc2, 0x6d, 0x35, 0x36, 0x5c, 0xb5, - 0xbf, 0x74, 0x81, 0xda, 0xe5, 0x0b, 0x38, 0x7f, 0xb5, 0x60, 0xbd, 0xea, 0x55, 0x9e, 0xf1, 0x13, - 0x31, 0x8c, 0xe8, 0x4d, 0xde, 0xcb, 0xf1, 0x9b, 0xad, 0x8e, 0xdf, 0x53, 0x58, 0x1e, 0x0b, 0x4a, - 0x66, 0xd9, 0xf8, 0x60, 0xaa, 0x1e, 0xab, 0xb0, 0xab, 0xb7, 0x54, 0xbd, 0x87, 0x3c, 0x78, 0xfa, - 0xed, 0xab, 0xb6, 0xf5, 0xdd, 0xab, 0xb6, 0xf5, 0xcf, 0x57, 0x6d, 0xeb, 0xab, 0xd7, 0xed, 0x99, - 0xef, 0x5e, 0xb7, 0x67, 0xfe, 0xf1, 0xba, 0x3d, 0xf3, 0xbb, 0x8f, 0xfa, 0x4c, 0x0d, 0x86, 0x3d, - 0x17, 0xf3, 0xb0, 0x93, 0xfd, 0x13, 0xa0, 0xf4, 0xf5, 0x7e, 0xf1, 0x1f, 0x92, 0xe4, 0x41, 0xe7, - 0xe5, 0xf8, 0x7f, 0x6c, 0xd4, 0x28, 0xa6, 0xb2, 0x37, 0x6f, 0x58, 0xe1, 0xc1, 0x7f, 0x02, 0x00, - 0x00, 0xff, 0xff, 0x47, 0xa2, 0xef, 0x46, 0xe2, 0x11, 0x00, 0x00, + // 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, 0xaa, 0x54, 0xb9, 0x54, 0x71, 0xb9, 0x48, 0x50, 0xb6, 0x28, 0xc6, + 0x16, 0xbd, 0x64, 0xa8, 0x4a, 0x72, 0xd8, 0x1a, 0xcc, 0x8e, 0x80, 0x29, 0x2e, 0x76, 0x56, 0x33, + 0xb3, 0x2b, 0xe3, 0x92, 0x73, 0x8e, 0xce, 0xcd, 0x95, 0x4b, 0x9c, 0xbc, 0x40, 0xce, 0x79, 0x03, + 0x1f, 0x7d, 0xcc, 0xc9, 0x4e, 0x51, 0xc7, 0xbc, 0x44, 0x6a, 0x66, 0xff, 0x41, 0x52, 0x81, 0x4a, + 0xf1, 0x6d, 0xb6, 0xa7, 0xfb, 0xeb, 0x9e, 0xe9, 0xee, 0xaf, 0x07, 0x80, 0x3d, 0x1a, 0x4a, 0xc2, + 0xf1, 0x10, 0xd1, 0xd0, 0x13, 0x04, 0xc7, 0x9c, 0xca, 0x71, 0x17, 0xe3, 0xa4, 0x1b, 0x71, 0x96, + 0x50, 0x9f, 0xf0, 0x6e, 0xb2, 0x5b, 0xac, 0x9d, 0x88, 0x33, 0xc9, 0xcc, 0x77, 0xae, 0xb1, 0x71, + 0x30, 0x4e, 0x9c, 0x42, 0x2f, 0xd9, 0xbd, 0xfb, 0xee, 0x4d, 0xc0, 0xc9, 0x6e, 0xf7, 0x05, 0xe5, + 0x24, 0xc5, 0xba, 0xbb, 0x3e, 0x60, 0x03, 0xa6, 0x97, 0x5d, 0xb5, 0xca, 0xa4, 0x5b, 0x03, 0xc6, + 0x06, 0x01, 0xe9, 0xea, 0xaf, 0x7e, 0xfc, 0xac, 0x2b, 0xe9, 0x88, 0x08, 0x89, 0x46, 0x51, 0xa6, + 0xd0, 0x99, 0x54, 0xf0, 0x63, 0x8e, 0x24, 0x65, 0x61, 0x0e, 0x40, 0xfb, 0xb8, 0x8b, 0x19, 0x27, + 0x5d, 0x1c, 0x50, 0x12, 0x4a, 0xe5, 0x35, 0x5d, 0x65, 0x0a, 0x5d, 0xa5, 0x10, 0xd0, 0xc1, 0x50, + 0xa6, 0x62, 0xd1, 0x95, 0x24, 0xf4, 0x09, 0x1f, 0xd1, 0x54, 0xb9, 0xfc, 0xca, 0x0c, 0x36, 0x2b, + 0xfb, 0x98, 0x8f, 0x23, 0xc9, 0xba, 0x17, 0x64, 0x2c, 0xb2, 0xdd, 0xf7, 0x30, 0x13, 0x23, 0x26, + 0xba, 0x44, 0x9d, 0x3f, 0xc4, 0xa4, 0x9b, 0xec, 0xf6, 0x89, 0x44, 0xbb, 0x85, 0x20, 0x8f, 0x3b, + 0xd3, 0xeb, 0x23, 0x51, 0xea, 0x60, 0x46, 0xb3, 0xb8, 0xed, 0x1f, 0xe6, 0xc1, 0xea, 0xb1, 0x50, + 0xc4, 0x23, 0xc2, 0xf7, 0x7d, 0x9f, 0xaa, 0x23, 0x9d, 0x70, 0x16, 0x31, 0x81, 0x02, 0x73, 0x1d, + 0xe6, 0x24, 0x95, 0x01, 0xb1, 0x8c, 0x6d, 0x63, 0xa7, 0xe5, 0xa6, 0x1f, 0xe6, 0x36, 0xb4, 0x7d, + 0x22, 0x30, 0xa7, 0x91, 0x52, 0xb6, 0x66, 0xf5, 0x5e, 0x55, 0x64, 0x6e, 0xc0, 0x42, 0x9a, 0x07, + 0xea, 0x5b, 0x0d, 0xbd, 0x7d, 0x4b, 0x7f, 0x1f, 0xf9, 0xe6, 0xa7, 0xb0, 0x4c, 0x43, 0x2a, 0x29, + 0x0a, 0xbc, 0x21, 0x51, 0xb7, 0x61, 0x35, 0xb7, 0x8d, 0x9d, 0xf6, 0xde, 0x5d, 0x87, 0xf6, 0xb1, + 0xa3, 0x2e, 0xd0, 0xc9, 0xae, 0x2d, 0xd9, 0x75, 0x1e, 0x69, 0x8d, 0x83, 0xe6, 0xb7, 0xdf, 0x6f, + 0xcd, 0xb8, 0x4b, 0x99, 0x5d, 0x2a, 0x34, 0xef, 0xc1, 0xe2, 0x80, 0x84, 0x44, 0x50, 0xe1, 0x0d, + 0x91, 0x18, 0x5a, 0x73, 0xdb, 0xc6, 0xce, 0xa2, 0xdb, 0xce, 0x64, 0x8f, 0x90, 0x18, 0x9a, 0x5b, + 0xd0, 0xee, 0xd3, 0x10, 0xf1, 0x71, 0xaa, 0x31, 0xaf, 0x35, 0x20, 0x15, 0x69, 0x85, 0x1e, 0x80, + 0x88, 0xd0, 0x8b, 0xd0, 0x53, 0xd9, 0xb6, 0x6e, 0x65, 0x81, 0xa4, 0x99, 0x76, 0xf2, 0x4c, 0x3b, + 0x67, 0x79, 0x29, 0x1c, 0x2c, 0xa8, 0x40, 0xbe, 0xfa, 0x61, 0xcb, 0x70, 0x5b, 0xda, 0x4e, 0xed, + 0x98, 0x9f, 0xc3, 0x6a, 0x1c, 0xf6, 0x59, 0xe8, 0xd3, 0x70, 0xe0, 0x45, 0x84, 0x53, 0xe6, 0x5b, + 0x0b, 0x1a, 0x6a, 0xe3, 0x0a, 0xd4, 0x61, 0x56, 0x34, 0x29, 0xd2, 0xd7, 0x0a, 0x69, 0xa5, 0x30, + 0x3e, 0xd1, 0xb6, 0xe6, 0x17, 0x60, 0x62, 0x9c, 0xe8, 0x90, 0x58, 0x2c, 0x73, 0xc4, 0xd6, 0xf4, + 0x88, 0xab, 0x18, 0x27, 0x67, 0xa9, 0x75, 0x06, 0xf9, 0x07, 0xb8, 0x23, 0x39, 0x0a, 0xc5, 0x33, + 0xc2, 0x27, 0x71, 0x61, 0x7a, 0xdc, 0xb7, 0x72, 0x8c, 0x3a, 0xf8, 0x23, 0xd8, 0xc6, 0x59, 0x01, + 0x79, 0x9c, 0xf8, 0x54, 0x48, 0x4e, 0xfb, 0xb1, 0xb2, 0xf5, 0x9e, 0x71, 0x84, 0x75, 0x8d, 0xb4, + 0x75, 0x11, 0x74, 0x72, 0x3d, 0xb7, 0xa6, 0xf6, 0x49, 0xa6, 0x65, 0x3e, 0x81, 0x9f, 0xf5, 0x03, + 0x86, 0x2f, 0x84, 0x0a, 0xce, 0xab, 0x21, 0x69, 0xd7, 0x23, 0x2a, 0x84, 0x42, 0x5b, 0xdc, 0x36, + 0x76, 0x1a, 0xee, 0xbd, 0x54, 0xf7, 0x84, 0xf0, 0xc3, 0x8a, 0xe6, 0x59, 0x45, 0xd1, 0xfc, 0x00, + 0xcc, 0x21, 0x15, 0x92, 0x71, 0x8a, 0x51, 0xe0, 0x91, 0x50, 0x72, 0x4a, 0x84, 0xb5, 0xa4, 0xcd, + 0x6f, 0x97, 0x3b, 0x0f, 0xd3, 0x0d, 0xf3, 0x31, 0xdc, 0xbb, 0xd1, 0xa9, 0x87, 0x87, 0x28, 0x0c, + 0x49, 0x60, 0x2d, 0xeb, 0xa3, 0x6c, 0xf9, 0x37, 0xf8, 0xec, 0xa5, 0x6a, 0x0f, 0x16, 0xfe, 0xf4, + 0xcd, 0xd6, 0xcc, 0xd7, 0xdf, 0x6c, 0xcd, 0xd8, 0xff, 0x30, 0xe0, 0x4e, 0xaf, 0x38, 0xf8, 0x88, + 0x25, 0x28, 0xf8, 0x31, 0x1b, 0x6c, 0x1f, 0x5a, 0x42, 0xb2, 0x28, 0x2d, 0xe9, 0xe6, 0x6b, 0x94, + 0xf4, 0x82, 0x32, 0x53, 0x1b, 0xf6, 0x5f, 0x0d, 0x58, 0x7f, 0xf8, 0x3c, 0xa6, 0x09, 0xc3, 0xe8, + 0xff, 0xc2, 0x07, 0xc7, 0xb0, 0x44, 0x2a, 0x78, 0xc2, 0x6a, 0x6c, 0x37, 0x76, 0xda, 0x7b, 0xef, + 0x3a, 0x29, 0x39, 0x39, 0x05, 0x67, 0x65, 0x04, 0xe5, 0x54, 0xbd, 0xbb, 0x75, 0xdb, 0x07, 0xb3, + 0x96, 0x61, 0xff, 0xdd, 0x80, 0xbb, 0xea, 0xa6, 0x07, 0xc4, 0x25, 0x2f, 0x10, 0xf7, 0x0f, 0x49, + 0xc8, 0x46, 0xe2, 0x8d, 0xe3, 0xb4, 0x61, 0xc9, 0xd7, 0x48, 0x9e, 0x64, 0x1e, 0xf2, 0x7d, 0x1d, + 0xa7, 0xd6, 0x51, 0xc2, 0x33, 0xb6, 0xef, 0xfb, 0xe6, 0x0e, 0xac, 0x96, 0x3a, 0x5c, 0xe5, 0x53, + 0x5d, 0xb3, 0x52, 0x5b, 0xce, 0xd5, 0x74, 0x96, 0x89, 0xfd, 0x1f, 0x03, 0x56, 0x3f, 0x0d, 0x58, + 0x1f, 0x05, 0xa7, 0x01, 0x12, 0x43, 0x55, 0x65, 0x63, 0x95, 0x1e, 0x4e, 0xb2, 0xf6, 0xd6, 0xe1, + 0x4d, 0x9d, 0x1e, 0x65, 0xa6, 0x09, 0xe7, 0x63, 0xb8, 0x5d, 0x34, 0x5c, 0x51, 0x05, 0xfa, 0x34, + 0x07, 0x6b, 0x97, 0xdf, 0x6f, 0xad, 0xe4, 0xc5, 0xd6, 0xd3, 0x15, 0x71, 0xe8, 0xae, 0xe0, 0x9a, + 0xc0, 0x37, 0x3b, 0xd0, 0xa6, 0x7d, 0xec, 0x09, 0xf2, 0xdc, 0x0b, 0xe3, 0x91, 0x2e, 0xa0, 0xa6, + 0xdb, 0xa2, 0x7d, 0x7c, 0x4a, 0x9e, 0x7f, 0x1e, 0x8f, 0xcc, 0xfb, 0xf0, 0x76, 0x3e, 0x58, 0xbd, + 0x04, 0x05, 0x9e, 0xb2, 0x57, 0xd7, 0xc1, 0x75, 0x3d, 0x2d, 0xba, 0x6b, 0xf9, 0xee, 0x39, 0x0a, + 0x94, 0xb3, 0x7d, 0xdf, 0xe7, 0xf6, 0x3f, 0xe7, 0x60, 0xfe, 0x04, 0x71, 0x34, 0x12, 0xe6, 0x19, + 0xac, 0x48, 0x32, 0x8a, 0x02, 0x24, 0x89, 0x97, 0x92, 0x79, 0x76, 0xd2, 0xf7, 0x35, 0xc9, 0x57, + 0x87, 0xa0, 0x53, 0x19, 0x7b, 0xc9, 0xae, 0xd3, 0xd3, 0xd2, 0x53, 0x89, 0x24, 0x71, 0x97, 0x73, + 0x8c, 0x54, 0x68, 0x7e, 0x08, 0x96, 0xe4, 0xb1, 0x90, 0x25, 0xcd, 0x96, 0xfc, 0x92, 0xe6, 0xf2, + 0xed, 0x7c, 0x3f, 0x65, 0xa6, 0x82, 0x57, 0xae, 0x67, 0xd4, 0xc6, 0x9b, 0x30, 0xea, 0x29, 0xac, + 0xa9, 0x71, 0x34, 0x89, 0xd9, 0x9c, 0x1e, 0xf3, 0xb6, 0xb2, 0xaf, 0x83, 0x7e, 0x01, 0x66, 0x22, + 0xf0, 0x24, 0xe6, 0xdc, 0x6b, 0xc4, 0x99, 0x08, 0x5c, 0x87, 0xf4, 0x61, 0x53, 0xa8, 0xe2, 0xf3, + 0x46, 0x44, 0x6a, 0x7e, 0x8e, 0x02, 0x12, 0x52, 0x31, 0xcc, 0xc1, 0xe7, 0xa7, 0x07, 0xdf, 0xd0, + 0x40, 0x9f, 0x29, 0x1c, 0x37, 0x87, 0xc9, 0xbc, 0xf4, 0xa0, 0x73, 0xbd, 0x97, 0x22, 0x41, 0xb7, + 0x74, 0x82, 0x7e, 0x72, 0x0d, 0x44, 0x91, 0x25, 0x01, 0xef, 0x55, 0xe6, 0x88, 0xea, 0x6a, 0x4f, + 0x37, 0x94, 0xc7, 0xc9, 0x40, 0x91, 0x2d, 0x4a, 0x47, 0x0a, 0x21, 0xc5, 0x2c, 0xcc, 0xd8, 0x43, + 0x3d, 0x6d, 0x0a, 0xe6, 0xe8, 0x31, 0x1a, 0x66, 0x0f, 0x06, 0xbb, 0x1c, 0x37, 0x05, 0x47, 0xb8, + 0x15, 0xac, 0x4f, 0x08, 0x79, 0xdc, 0x5c, 0x58, 0x58, 0x6d, 0xd9, 0xbf, 0x80, 0x96, 0x6e, 0xd1, + 0x7d, 0x7c, 0x21, 0xcc, 0x4d, 0x68, 0xa9, 0x5a, 0x27, 0x42, 0x10, 0x61, 0x19, 0xba, 0xb3, 0x4b, + 0x81, 0x2d, 0x61, 0xe3, 0xa6, 0xe7, 0x92, 0x30, 0x9f, 0xc2, 0xad, 0x88, 0xe8, 0x59, 0xae, 0x0d, + 0xdb, 0x7b, 0x1f, 0x39, 0x53, 0xbc, 0x5c, 0x9d, 0x9b, 0x00, 0xdd, 0x1c, 0xcd, 0xe6, 0xe5, 0x23, + 0x6d, 0x62, 0x84, 0x08, 0xf3, 0x7c, 0xd2, 0xe9, 0xaf, 0x5f, 0xcb, 0xe9, 0x04, 0x5e, 0xe9, 0xf3, + 0x7d, 0x68, 0xef, 0xa7, 0xc7, 0xfe, 0x0d, 0x15, 0xf2, 0xea, 0xb5, 0x2c, 0x56, 0xaf, 0xe5, 0x31, + 0x2c, 0x67, 0x93, 0xef, 0x8c, 0x69, 0x9a, 0x31, 0x7f, 0x0a, 0x90, 0x8d, 0x4c, 0x45, 0x4f, 0x29, + 0x11, 0xb7, 0x32, 0xc9, 0x91, 0x5f, 0x9b, 0x60, 0xb3, 0xb5, 0x09, 0x66, 0xbb, 0xb0, 0x72, 0x2e, + 0xf0, 0x6f, 0xf3, 0x67, 0xd1, 0x93, 0x48, 0x98, 0x6f, 0xc1, 0xbc, 0xea, 0x8c, 0x0c, 0xa8, 0xe9, + 0xce, 0x25, 0x02, 0x1f, 0x69, 0x2e, 0x2e, 0x9f, 0x5e, 0x2c, 0xf2, 0xa8, 0x2f, 0xac, 0xd9, 0xed, + 0xc6, 0x4e, 0xd3, 0x5d, 0x8e, 0x4b, 0xf3, 0x23, 0x5f, 0xd8, 0xbf, 0x83, 0x76, 0x05, 0xd0, 0x5c, + 0x86, 0xd9, 0x02, 0x6b, 0x96, 0xfa, 0xe6, 0x03, 0xd8, 0x28, 0x81, 0xea, 0xe4, 0x9a, 0x22, 0xb6, + 0xdc, 0x3b, 0x85, 0x42, 0x8d, 0x5f, 0x85, 0xfd, 0x04, 0xd6, 0x8f, 0xca, 0x56, 0x2e, 0xa8, 0xbb, + 0x76, 0x42, 0xa3, 0x3e, 0xa3, 0x37, 0xa1, 0x55, 0xfc, 0xbe, 0xd0, 0xa7, 0x6f, 0xba, 0xa5, 0xc0, + 0x1e, 0xc1, 0xea, 0xb9, 0xc0, 0xa7, 0x24, 0xf4, 0x4b, 0xb0, 0x1b, 0x2e, 0xe0, 0x60, 0x12, 0x68, + 0xea, 0xf7, 0x6b, 0xe9, 0x8e, 0xc1, 0xc6, 0x39, 0x0a, 0xa8, 0x8f, 0x24, 0xe3, 0xa7, 0x44, 0xa6, + 0x63, 0xf5, 0x04, 0xe1, 0x0b, 0x22, 0x85, 0xe9, 0x42, 0x33, 0xa0, 0x42, 0x66, 0x95, 0xf5, 0xe1, + 0x8d, 0x95, 0x95, 0xec, 0x3a, 0x37, 0x81, 0x1c, 0x22, 0x89, 0xb2, 0x8e, 0xd4, 0x58, 0xf6, 0xcf, + 0x61, 0xed, 0x33, 0x24, 0x63, 0x4e, 0xfc, 0x5a, 0x8e, 0x57, 0xa1, 0xa1, 0xf2, 0x67, 0xe8, 0xfc, + 0xa9, 0xa5, 0x9a, 0xf2, 0xd6, 0xc3, 0x2f, 0x23, 0xc6, 0x25, 0xf1, 0xaf, 0xdc, 0xc8, 0x2b, 0xae, + 0xf7, 0x02, 0xd6, 0xd4, 0x65, 0x09, 0x12, 0xfa, 0x5e, 0x71, 0xce, 0x34, 0x8f, 0xed, 0xbd, 0x5f, + 0x4d, 0xd5, 0x1d, 0x93, 0xee, 0xb2, 0x03, 0xdc, 0x4e, 0x26, 0xe4, 0xc2, 0xfe, 0xb3, 0x01, 0xd6, + 0x31, 0x19, 0xef, 0x0b, 0x41, 0x07, 0xe1, 0x88, 0x84, 0x52, 0x31, 0x1b, 0xc2, 0x44, 0x2d, 0xcd, + 0x77, 0x60, 0xa9, 0x98, 0xa4, 0x7a, 0x80, 0x1a, 0x7a, 0x80, 0x2e, 0xe6, 0x42, 0xd5, 0x60, 0xe6, + 0x03, 0x80, 0x88, 0x93, 0xc4, 0xc3, 0xde, 0x05, 0x19, 0x67, 0x59, 0xdc, 0xac, 0x0e, 0xc6, 0xf4, + 0xd7, 0x9f, 0x73, 0x12, 0xf7, 0x03, 0x8a, 0x8f, 0xc9, 0xd8, 0x5d, 0x50, 0xfa, 0xbd, 0x63, 0x32, + 0x56, 0x2f, 0x9d, 0x88, 0xbd, 0x20, 0x5c, 0x4f, 0xb3, 0x86, 0x9b, 0x7e, 0xd8, 0x7f, 0x31, 0xe0, + 0x4e, 0x91, 0x8e, 0xbc, 0x5c, 0x4f, 0xe2, 0xbe, 0xb2, 0x78, 0xc5, 0xbd, 0x5d, 0x89, 0x76, 0xf6, + 0x9a, 0x68, 0x3f, 0x86, 0xc5, 0xa2, 0x41, 0x54, 0xbc, 0x8d, 0x29, 0xe2, 0x6d, 0xe7, 0x16, 0xc7, + 0x64, 0x6c, 0xff, 0xb1, 0x12, 0xdb, 0xc1, 0xb8, 0xc2, 0x7d, 0xfc, 0x7f, 0xc4, 0x56, 0xb8, 0xad, + 0xc6, 0x86, 0xab, 0xf6, 0x57, 0x0e, 0xd0, 0xb8, 0x7a, 0x00, 0xfb, 0x6f, 0x06, 0xac, 0x57, 0xbd, + 0x8a, 0x33, 0x76, 0xc2, 0xe3, 0x90, 0xbc, 0xca, 0x7b, 0xd9, 0x7e, 0xb3, 0xd5, 0xf6, 0x7b, 0x0a, + 0xcb, 0xb5, 0xa0, 0x44, 0x76, 0x1b, 0xbf, 0x9c, 0xaa, 0xc6, 0x2a, 0xec, 0xea, 0x2e, 0x55, 0xcf, + 0x21, 0x0e, 0x9e, 0x7e, 0x7b, 0xd9, 0x31, 0xbe, 0xbb, 0xec, 0x18, 0xff, 0xbe, 0xec, 0x18, 0x5f, + 0xbd, 0xec, 0xcc, 0x7c, 0xf7, 0xb2, 0x33, 0xf3, 0xaf, 0x97, 0x9d, 0x99, 0xdf, 0x7f, 0x34, 0xa0, + 0x72, 0x18, 0xf7, 0x1d, 0xcc, 0x46, 0xdd, 0xec, 0xa7, 0x7d, 0xe9, 0xeb, 0x83, 0xe2, 0x7f, 0x8f, + 0xe4, 0x7e, 0xf7, 0xcb, 0xfa, 0xbf, 0x2a, 0x72, 0x1c, 0x11, 0xd1, 0x9f, 0xd7, 0xac, 0x70, 0xff, + 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa7, 0xa1, 0xa2, 0x88, 0x86, 0x11, 0x00, 0x00, } func (m *ConsumerAdditionProposal) Marshal() (dAtA []byte, err error) { @@ -1893,11 +1886,6 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x4a - if m.MaxThrottledPackets != 0 { - i = encodeVarintProvider(dAtA, i, uint64(m.MaxThrottledPackets)) - i-- - dAtA[i] = 0x40 - } if len(m.SlashMeterReplenishFraction) > 0 { i -= len(m.SlashMeterReplenishFraction) copy(dAtA[i:], m.SlashMeterReplenishFraction) @@ -2784,9 +2772,6 @@ func (m *Params) Size() (n int) { if l > 0 { n += 1 + l + sovProvider(uint64(l)) } - if m.MaxThrottledPackets != 0 { - n += 1 + sovProvider(uint64(m.MaxThrottledPackets)) - } l = m.ConsumerRewardDenomRegistrationFee.Size() n += 1 + l + sovProvider(uint64(l)) return n @@ -4489,25 +4474,6 @@ func (m *Params) Unmarshal(dAtA []byte) error { } m.SlashMeterReplenishFraction = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MaxThrottledPackets", wireType) - } - m.MaxThrottledPackets = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowProvider - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.MaxThrottledPackets |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } case 9: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ConsumerRewardDenomRegistrationFee", wireType) diff --git a/x/ccv/provider/types/query.pb.go b/x/ccv/provider/types/query.pb.go index eac75ded70..f5f9852846 100644 --- a/x/ccv/provider/types/query.pb.go +++ b/x/ccv/provider/types/query.pb.go @@ -637,8 +637,6 @@ type QueryThrottleStateResponse struct { // next time the slash meter could potentially be replenished, iff it's not // full NextReplenishCandidate time.Time `protobuf:"bytes,3,opt,name=next_replenish_candidate,json=nextReplenishCandidate,proto3,stdtime" json:"next_replenish_candidate"` - // data relevant to currently throttled slash packets - Packets []*ThrottledSlashPacket `protobuf:"bytes,4,rep,name=packets,proto3" json:"packets,omitempty"` } func (m *QueryThrottleStateResponse) Reset() { *m = QueryThrottleStateResponse{} } @@ -695,31 +693,25 @@ func (m *QueryThrottleStateResponse) GetNextReplenishCandidate() time.Time { return time.Time{} } -func (m *QueryThrottleStateResponse) GetPackets() []*ThrottledSlashPacket { - if m != nil { - return m.Packets - } - return nil +type QueryRegisteredConsumerRewardDenomsRequest struct { } -type QueryThrottledConsumerPacketDataRequest struct { - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` +func (m *QueryRegisteredConsumerRewardDenomsRequest) Reset() { + *m = QueryRegisteredConsumerRewardDenomsRequest{} } - -func (m *QueryThrottledConsumerPacketDataRequest) Reset() { - *m = QueryThrottledConsumerPacketDataRequest{} +func (m *QueryRegisteredConsumerRewardDenomsRequest) String() string { + return proto.CompactTextString(m) } -func (m *QueryThrottledConsumerPacketDataRequest) String() string { return proto.CompactTextString(m) } -func (*QueryThrottledConsumerPacketDataRequest) ProtoMessage() {} -func (*QueryThrottledConsumerPacketDataRequest) Descriptor() ([]byte, []int) { +func (*QueryRegisteredConsumerRewardDenomsRequest) ProtoMessage() {} +func (*QueryRegisteredConsumerRewardDenomsRequest) Descriptor() ([]byte, []int) { return fileDescriptor_422512d7b7586cd7, []int{15} } -func (m *QueryThrottledConsumerPacketDataRequest) XXX_Unmarshal(b []byte) error { +func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryThrottledConsumerPacketDataRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryThrottledConsumerPacketDataRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryRegisteredConsumerRewardDenomsRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -729,45 +721,38 @@ func (m *QueryThrottledConsumerPacketDataRequest) XXX_Marshal(b []byte, determin return b[:n], nil } } -func (m *QueryThrottledConsumerPacketDataRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryThrottledConsumerPacketDataRequest.Merge(m, src) +func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryRegisteredConsumerRewardDenomsRequest.Merge(m, src) } -func (m *QueryThrottledConsumerPacketDataRequest) XXX_Size() int { +func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_Size() int { return m.Size() } -func (m *QueryThrottledConsumerPacketDataRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryThrottledConsumerPacketDataRequest.DiscardUnknown(m) +func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryRegisteredConsumerRewardDenomsRequest.DiscardUnknown(m) } -var xxx_messageInfo_QueryThrottledConsumerPacketDataRequest proto.InternalMessageInfo +var xxx_messageInfo_QueryRegisteredConsumerRewardDenomsRequest proto.InternalMessageInfo -func (m *QueryThrottledConsumerPacketDataRequest) GetChainId() string { - if m != nil { - return m.ChainId - } - return "" +type QueryRegisteredConsumerRewardDenomsResponse struct { + Denoms []string `protobuf:"bytes,1,rep,name=denoms,proto3" json:"denoms,omitempty"` } -type QueryThrottledConsumerPacketDataResponse struct { - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` - Size_ uint64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` - PacketDataInstances []ThrottledPacketDataWrapper `protobuf:"bytes,3,rep,name=packetDataInstances,proto3" json:"packetDataInstances"` +func (m *QueryRegisteredConsumerRewardDenomsResponse) Reset() { + *m = QueryRegisteredConsumerRewardDenomsResponse{} } - -func (m *QueryThrottledConsumerPacketDataResponse) Reset() { - *m = QueryThrottledConsumerPacketDataResponse{} +func (m *QueryRegisteredConsumerRewardDenomsResponse) String() string { + return proto.CompactTextString(m) } -func (m *QueryThrottledConsumerPacketDataResponse) String() string { return proto.CompactTextString(m) } -func (*QueryThrottledConsumerPacketDataResponse) ProtoMessage() {} -func (*QueryThrottledConsumerPacketDataResponse) Descriptor() ([]byte, []int) { +func (*QueryRegisteredConsumerRewardDenomsResponse) ProtoMessage() {} +func (*QueryRegisteredConsumerRewardDenomsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_422512d7b7586cd7, []int{16} } -func (m *QueryThrottledConsumerPacketDataResponse) XXX_Unmarshal(b []byte) error { +func (m *QueryRegisteredConsumerRewardDenomsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryThrottledConsumerPacketDataResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryRegisteredConsumerRewardDenomsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryThrottledConsumerPacketDataResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryRegisteredConsumerRewardDenomsResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -777,58 +762,40 @@ func (m *QueryThrottledConsumerPacketDataResponse) XXX_Marshal(b []byte, determi return b[:n], nil } } -func (m *QueryThrottledConsumerPacketDataResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryThrottledConsumerPacketDataResponse.Merge(m, src) +func (m *QueryRegisteredConsumerRewardDenomsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryRegisteredConsumerRewardDenomsResponse.Merge(m, src) } -func (m *QueryThrottledConsumerPacketDataResponse) XXX_Size() int { +func (m *QueryRegisteredConsumerRewardDenomsResponse) XXX_Size() int { return m.Size() } -func (m *QueryThrottledConsumerPacketDataResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryThrottledConsumerPacketDataResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryThrottledConsumerPacketDataResponse proto.InternalMessageInfo - -func (m *QueryThrottledConsumerPacketDataResponse) GetChainId() string { - if m != nil { - return m.ChainId - } - return "" +func (m *QueryRegisteredConsumerRewardDenomsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryRegisteredConsumerRewardDenomsResponse.DiscardUnknown(m) } -func (m *QueryThrottledConsumerPacketDataResponse) GetSize_() uint64 { - if m != nil { - return m.Size_ - } - return 0 -} +var xxx_messageInfo_QueryRegisteredConsumerRewardDenomsResponse proto.InternalMessageInfo -func (m *QueryThrottledConsumerPacketDataResponse) GetPacketDataInstances() []ThrottledPacketDataWrapper { +func (m *QueryRegisteredConsumerRewardDenomsResponse) GetDenoms() []string { if m != nil { - return m.PacketDataInstances + return m.Denoms } return nil } -// A query wrapper type for the global entry and data relevant to a throttled -// slash packet. -type ThrottledSlashPacket struct { - GlobalEntry GlobalSlashEntry `protobuf:"bytes,1,opt,name=global_entry,json=globalEntry,proto3" json:"global_entry"` - Data types.SlashPacketData `protobuf:"bytes,2,opt,name=data,proto3" json:"data"` +type QueryProposedChainIDsRequest struct { } -func (m *ThrottledSlashPacket) Reset() { *m = ThrottledSlashPacket{} } -func (m *ThrottledSlashPacket) String() string { return proto.CompactTextString(m) } -func (*ThrottledSlashPacket) ProtoMessage() {} -func (*ThrottledSlashPacket) Descriptor() ([]byte, []int) { +func (m *QueryProposedChainIDsRequest) Reset() { *m = QueryProposedChainIDsRequest{} } +func (m *QueryProposedChainIDsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryProposedChainIDsRequest) ProtoMessage() {} +func (*QueryProposedChainIDsRequest) Descriptor() ([]byte, []int) { return fileDescriptor_422512d7b7586cd7, []int{17} } -func (m *ThrottledSlashPacket) XXX_Unmarshal(b []byte) error { +func (m *QueryProposedChainIDsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *ThrottledSlashPacket) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryProposedChainIDsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_ThrottledSlashPacket.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryProposedChainIDsRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -838,53 +805,34 @@ func (m *ThrottledSlashPacket) XXX_Marshal(b []byte, deterministic bool) ([]byte return b[:n], nil } } -func (m *ThrottledSlashPacket) XXX_Merge(src proto.Message) { - xxx_messageInfo_ThrottledSlashPacket.Merge(m, src) +func (m *QueryProposedChainIDsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryProposedChainIDsRequest.Merge(m, src) } -func (m *ThrottledSlashPacket) XXX_Size() int { +func (m *QueryProposedChainIDsRequest) XXX_Size() int { return m.Size() } -func (m *ThrottledSlashPacket) XXX_DiscardUnknown() { - xxx_messageInfo_ThrottledSlashPacket.DiscardUnknown(m) +func (m *QueryProposedChainIDsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryProposedChainIDsRequest.DiscardUnknown(m) } -var xxx_messageInfo_ThrottledSlashPacket proto.InternalMessageInfo - -func (m *ThrottledSlashPacket) GetGlobalEntry() GlobalSlashEntry { - if m != nil { - return m.GlobalEntry - } - return GlobalSlashEntry{} -} - -func (m *ThrottledSlashPacket) GetData() types.SlashPacketData { - if m != nil { - return m.Data - } - return types.SlashPacketData{} -} +var xxx_messageInfo_QueryProposedChainIDsRequest proto.InternalMessageInfo -// ThrottledPacketDataWrapper contains either SlashPacketData or -// VSCMaturedPacketData -type ThrottledPacketDataWrapper struct { - // Types that are valid to be assigned to Data: - // *ThrottledPacketDataWrapper_SlashPacket - // *ThrottledPacketDataWrapper_VscMaturedPacket - Data isThrottledPacketDataWrapper_Data `protobuf_oneof:"data"` +type QueryProposedChainIDsResponse struct { + ProposedChains []ProposedChain `protobuf:"bytes,1,rep,name=proposedChains,proto3" json:"proposedChains"` } -func (m *ThrottledPacketDataWrapper) Reset() { *m = ThrottledPacketDataWrapper{} } -func (m *ThrottledPacketDataWrapper) String() string { return proto.CompactTextString(m) } -func (*ThrottledPacketDataWrapper) ProtoMessage() {} -func (*ThrottledPacketDataWrapper) Descriptor() ([]byte, []int) { +func (m *QueryProposedChainIDsResponse) Reset() { *m = QueryProposedChainIDsResponse{} } +func (m *QueryProposedChainIDsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryProposedChainIDsResponse) ProtoMessage() {} +func (*QueryProposedChainIDsResponse) Descriptor() ([]byte, []int) { return fileDescriptor_422512d7b7586cd7, []int{18} } -func (m *ThrottledPacketDataWrapper) XXX_Unmarshal(b []byte) error { +func (m *QueryProposedChainIDsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *ThrottledPacketDataWrapper) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryProposedChainIDsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_ThrottledPacketDataWrapper.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryProposedChainIDsResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -894,82 +842,42 @@ func (m *ThrottledPacketDataWrapper) XXX_Marshal(b []byte, deterministic bool) ( return b[:n], nil } } -func (m *ThrottledPacketDataWrapper) XXX_Merge(src proto.Message) { - xxx_messageInfo_ThrottledPacketDataWrapper.Merge(m, src) +func (m *QueryProposedChainIDsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryProposedChainIDsResponse.Merge(m, src) } -func (m *ThrottledPacketDataWrapper) XXX_Size() int { +func (m *QueryProposedChainIDsResponse) XXX_Size() int { return m.Size() } -func (m *ThrottledPacketDataWrapper) XXX_DiscardUnknown() { - xxx_messageInfo_ThrottledPacketDataWrapper.DiscardUnknown(m) +func (m *QueryProposedChainIDsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryProposedChainIDsResponse.DiscardUnknown(m) } -var xxx_messageInfo_ThrottledPacketDataWrapper proto.InternalMessageInfo +var xxx_messageInfo_QueryProposedChainIDsResponse proto.InternalMessageInfo -type isThrottledPacketDataWrapper_Data interface { - isThrottledPacketDataWrapper_Data() - MarshalTo([]byte) (int, error) - Size() int -} - -type ThrottledPacketDataWrapper_SlashPacket struct { - SlashPacket *types.SlashPacketData `protobuf:"bytes,1,opt,name=slash_packet,json=slashPacket,proto3,oneof" json:"slash_packet,omitempty"` -} -type ThrottledPacketDataWrapper_VscMaturedPacket struct { - VscMaturedPacket *types.VSCMaturedPacketData `protobuf:"bytes,2,opt,name=vsc_matured_packet,json=vscMaturedPacket,proto3,oneof" json:"vsc_matured_packet,omitempty"` -} - -func (*ThrottledPacketDataWrapper_SlashPacket) isThrottledPacketDataWrapper_Data() {} -func (*ThrottledPacketDataWrapper_VscMaturedPacket) isThrottledPacketDataWrapper_Data() {} - -func (m *ThrottledPacketDataWrapper) GetData() isThrottledPacketDataWrapper_Data { +func (m *QueryProposedChainIDsResponse) GetProposedChains() []ProposedChain { if m != nil { - return m.Data - } - return nil -} - -func (m *ThrottledPacketDataWrapper) GetSlashPacket() *types.SlashPacketData { - if x, ok := m.GetData().(*ThrottledPacketDataWrapper_SlashPacket); ok { - return x.SlashPacket - } - return nil -} - -func (m *ThrottledPacketDataWrapper) GetVscMaturedPacket() *types.VSCMaturedPacketData { - if x, ok := m.GetData().(*ThrottledPacketDataWrapper_VscMaturedPacket); ok { - return x.VscMaturedPacket + return m.ProposedChains } return nil } -// XXX_OneofWrappers is for the internal use of the proto package. -func (*ThrottledPacketDataWrapper) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*ThrottledPacketDataWrapper_SlashPacket)(nil), - (*ThrottledPacketDataWrapper_VscMaturedPacket)(nil), - } -} - -type QueryRegisteredConsumerRewardDenomsRequest struct { +type ProposedChain struct { + ChainID string `protobuf:"bytes,1,opt,name=chainID,proto3" json:"chainID,omitempty"` + ProposalID uint64 `protobuf:"varint,2,opt,name=proposalID,proto3" json:"proposalID,omitempty"` } -func (m *QueryRegisteredConsumerRewardDenomsRequest) Reset() { - *m = QueryRegisteredConsumerRewardDenomsRequest{} -} -func (m *QueryRegisteredConsumerRewardDenomsRequest) String() string { - return proto.CompactTextString(m) -} -func (*QueryRegisteredConsumerRewardDenomsRequest) ProtoMessage() {} -func (*QueryRegisteredConsumerRewardDenomsRequest) Descriptor() ([]byte, []int) { +func (m *ProposedChain) Reset() { *m = ProposedChain{} } +func (m *ProposedChain) String() string { return proto.CompactTextString(m) } +func (*ProposedChain) ProtoMessage() {} +func (*ProposedChain) Descriptor() ([]byte, []int) { return fileDescriptor_422512d7b7586cd7, []int{19} } -func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_Unmarshal(b []byte) error { +func (m *ProposedChain) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *ProposedChain) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryRegisteredConsumerRewardDenomsRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_ProposedChain.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -979,64 +887,30 @@ func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_Marshal(b []byte, deter return b[:n], nil } } -func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryRegisteredConsumerRewardDenomsRequest.Merge(m, src) +func (m *ProposedChain) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProposedChain.Merge(m, src) } -func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_Size() int { +func (m *ProposedChain) XXX_Size() int { return m.Size() } -func (m *QueryRegisteredConsumerRewardDenomsRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryRegisteredConsumerRewardDenomsRequest.DiscardUnknown(m) +func (m *ProposedChain) XXX_DiscardUnknown() { + xxx_messageInfo_ProposedChain.DiscardUnknown(m) } -var xxx_messageInfo_QueryRegisteredConsumerRewardDenomsRequest proto.InternalMessageInfo - -type QueryRegisteredConsumerRewardDenomsResponse struct { - Denoms []string `protobuf:"bytes,1,rep,name=denoms,proto3" json:"denoms,omitempty"` -} +var xxx_messageInfo_ProposedChain proto.InternalMessageInfo -func (m *QueryRegisteredConsumerRewardDenomsResponse) Reset() { - *m = QueryRegisteredConsumerRewardDenomsResponse{} -} -func (m *QueryRegisteredConsumerRewardDenomsResponse) String() string { - return proto.CompactTextString(m) -} -func (*QueryRegisteredConsumerRewardDenomsResponse) ProtoMessage() {} -func (*QueryRegisteredConsumerRewardDenomsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_422512d7b7586cd7, []int{20} -} -func (m *QueryRegisteredConsumerRewardDenomsResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryRegisteredConsumerRewardDenomsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryRegisteredConsumerRewardDenomsResponse.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 *ProposedChain) GetChainID() string { + if m != nil { + return m.ChainID } -} -func (m *QueryRegisteredConsumerRewardDenomsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryRegisteredConsumerRewardDenomsResponse.Merge(m, src) -} -func (m *QueryRegisteredConsumerRewardDenomsResponse) XXX_Size() int { - return m.Size() -} -func (m *QueryRegisteredConsumerRewardDenomsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryRegisteredConsumerRewardDenomsResponse.DiscardUnknown(m) + return "" } -var xxx_messageInfo_QueryRegisteredConsumerRewardDenomsResponse proto.InternalMessageInfo - -func (m *QueryRegisteredConsumerRewardDenomsResponse) GetDenoms() []string { +func (m *ProposedChain) GetProposalID() uint64 { if m != nil { - return m.Denoms + return m.ProposalID } - return nil + return 0 } func init() { @@ -1055,12 +929,11 @@ func init() { 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((*QueryThrottledConsumerPacketDataRequest)(nil), "interchain_security.ccv.provider.v1.QueryThrottledConsumerPacketDataRequest") - proto.RegisterType((*QueryThrottledConsumerPacketDataResponse)(nil), "interchain_security.ccv.provider.v1.QueryThrottledConsumerPacketDataResponse") - proto.RegisterType((*ThrottledSlashPacket)(nil), "interchain_security.ccv.provider.v1.ThrottledSlashPacket") - proto.RegisterType((*ThrottledPacketDataWrapper)(nil), "interchain_security.ccv.provider.v1.ThrottledPacketDataWrapper") 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") } func init() { @@ -1068,90 +941,81 @@ func init() { } var fileDescriptor_422512d7b7586cd7 = []byte{ - // 1321 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcf, 0x8f, 0x14, 0x45, - 0x18, 0x9d, 0x9e, 0x5d, 0x96, 0xdd, 0x5a, 0x14, 0x2c, 0x10, 0x87, 0x86, 0xcc, 0x60, 0x13, 0x75, - 0x01, 0xed, 0x66, 0x87, 0x98, 0x00, 0xba, 0x0c, 0x33, 0xcb, 0xba, 0x10, 0x20, 0xac, 0xbd, 0x04, - 0x12, 0x35, 0xb4, 0xb5, 0xdd, 0xe5, 0x4c, 0xc7, 0x9e, 0xae, 0xa6, 0xaa, 0x66, 0x96, 0x95, 0x78, - 0x50, 0x13, 0xe5, 0x48, 0x62, 0xbc, 0x79, 0xe0, 0xe4, 0x7f, 0xe1, 0x9d, 0x9b, 0x44, 0x2e, 0x9c, - 0xd0, 0x2c, 0x1e, 0x3c, 0x1a, 0xef, 0x26, 0xa6, 0xab, 0xab, 0x7b, 0x7e, 0xf5, 0xce, 0xf4, 0x0c, - 0xdc, 0x66, 0xaa, 0xeb, 0x7b, 0xdf, 0x7b, 0x6f, 0xbe, 0xaa, 0x7e, 0x03, 0x0c, 0xd7, 0xe7, 0x98, - 0xda, 0x0d, 0xe4, 0xfa, 0x16, 0xc3, 0x76, 0x8b, 0xba, 0x7c, 0xcb, 0xb0, 0xed, 0xb6, 0x11, 0x50, - 0xd2, 0x76, 0x1d, 0x4c, 0x8d, 0xf6, 0xa2, 0x71, 0xa7, 0x85, 0xe9, 0x96, 0x1e, 0x50, 0xc2, 0x09, - 0x3c, 0x96, 0x52, 0xa0, 0xdb, 0x76, 0x5b, 0x8f, 0x0b, 0xf4, 0xf6, 0xa2, 0x7a, 0xa4, 0x4e, 0x48, - 0xdd, 0xc3, 0x06, 0x0a, 0x5c, 0x03, 0xf9, 0x3e, 0xe1, 0x88, 0xbb, 0xc4, 0x67, 0x11, 0x84, 0x7a, - 0xa0, 0x4e, 0xea, 0x44, 0x7c, 0x34, 0xc2, 0x4f, 0x72, 0xb5, 0x24, 0x6b, 0xc4, 0xb7, 0x8d, 0xd6, - 0x17, 0x06, 0x77, 0x9b, 0x98, 0x71, 0xd4, 0x0c, 0xe4, 0x86, 0x72, 0x16, 0xaa, 0x09, 0x8b, 0xa8, - 0xe6, 0xd4, 0x4e, 0x35, 0xed, 0x45, 0x83, 0x35, 0x10, 0xc5, 0x8e, 0x65, 0x13, 0x9f, 0xb5, 0x9a, - 0x49, 0xc5, 0x5b, 0x43, 0x2a, 0x36, 0x5d, 0x8a, 0xa3, 0x6d, 0xda, 0x19, 0x70, 0xf8, 0xe3, 0xd0, - 0x95, 0x65, 0x59, 0xbd, 0x8a, 0x7d, 0xcc, 0x5c, 0x66, 0xe2, 0x3b, 0x2d, 0xcc, 0x38, 0x3c, 0x04, - 0x66, 0x23, 0x08, 0xd7, 0x29, 0x28, 0x47, 0x95, 0x85, 0x39, 0x73, 0xb7, 0xf8, 0x7e, 0xd9, 0xd1, - 0xee, 0x81, 0x23, 0xe9, 0x95, 0x2c, 0x20, 0x3e, 0xc3, 0xf0, 0x53, 0xf0, 0x4a, 0x3d, 0x5a, 0xb2, - 0x18, 0x47, 0x1c, 0x8b, 0xfa, 0xf9, 0xf2, 0x29, 0x7d, 0x27, 0xe3, 0xdb, 0x8b, 0x7a, 0x1f, 0xd6, - 0x7a, 0x58, 0x57, 0x9b, 0x7e, 0xf4, 0xac, 0x94, 0x33, 0xf7, 0xd4, 0xbb, 0xd6, 0xb4, 0x23, 0x40, - 0xed, 0x69, 0xbe, 0x1c, 0xc2, 0xc5, 0xac, 0x35, 0xd4, 0x27, 0x2a, 0x7e, 0x2a, 0x99, 0xd5, 0xc0, - 0x8c, 0x68, 0xcf, 0x0a, 0xca, 0xd1, 0xa9, 0x85, 0xf9, 0xf2, 0x09, 0x3d, 0xc3, 0x2c, 0xe8, 0x02, - 0xc4, 0x94, 0x95, 0xda, 0x71, 0xf0, 0xce, 0x60, 0x8b, 0x75, 0x8e, 0x28, 0x5f, 0xa3, 0x24, 0x20, - 0x0c, 0x79, 0x09, 0x9b, 0xfb, 0x0a, 0x58, 0x18, 0xbd, 0x57, 0x72, 0xfb, 0x0c, 0xcc, 0x05, 0xf1, - 0xa2, 0x74, 0xec, 0x7c, 0x36, 0x7a, 0x12, 0xbc, 0xea, 0x38, 0x6e, 0x38, 0xa4, 0x1d, 0xe8, 0x0e, - 0xa0, 0xb6, 0x00, 0xde, 0x4e, 0x63, 0x42, 0x82, 0x01, 0xd2, 0xdf, 0x2b, 0xe9, 0x02, 0x7b, 0xb6, - 0x26, 0xbf, 0xf4, 0x00, 0xe7, 0xa5, 0xb1, 0x38, 0x9b, 0xb8, 0x49, 0xda, 0xc8, 0x4b, 0xa5, 0x5c, - 0x01, 0xbb, 0x44, 0xeb, 0x21, 0xa3, 0x08, 0x0f, 0x83, 0x39, 0xdb, 0x73, 0xb1, 0xcf, 0xc3, 0x67, - 0x79, 0xf1, 0x6c, 0x36, 0x5a, 0xb8, 0xec, 0x68, 0x3f, 0x28, 0xe0, 0x4d, 0xa1, 0xe4, 0x26, 0xf2, - 0x5c, 0x07, 0x71, 0x42, 0xbb, 0xac, 0xa2, 0xa3, 0x07, 0x1d, 0x2e, 0x81, 0x7d, 0x31, 0x69, 0x0b, - 0x39, 0x0e, 0xc5, 0x8c, 0x45, 0x4d, 0x6a, 0xf0, 0xdf, 0x67, 0xa5, 0x57, 0xb7, 0x50, 0xd3, 0x3b, - 0xa7, 0xc9, 0x07, 0x9a, 0xb9, 0x37, 0xde, 0x5b, 0x8d, 0x56, 0xce, 0xcd, 0xde, 0x7f, 0x58, 0xca, - 0xfd, 0xfd, 0xb0, 0x94, 0xd3, 0xae, 0x03, 0x6d, 0x18, 0x11, 0xe9, 0xe6, 0x71, 0xb0, 0x2f, 0x3e, - 0xca, 0x49, 0xbb, 0x88, 0xd1, 0x5e, 0xbb, 0x6b, 0x7f, 0xd8, 0x6c, 0x50, 0xda, 0x5a, 0x57, 0xf3, - 0x6c, 0xd2, 0x06, 0x7a, 0x0d, 0x91, 0xd6, 0xd7, 0x7f, 0x98, 0xb4, 0x5e, 0x22, 0x1d, 0x69, 0x03, - 0x4e, 0x4a, 0x69, 0x7d, 0xae, 0x69, 0x87, 0xc1, 0x21, 0x01, 0x78, 0xa3, 0x41, 0x09, 0xe7, 0x1e, - 0x16, 0xc7, 0x3e, 0x1e, 0xce, 0x5f, 0xf2, 0xf2, 0xf8, 0xf7, 0x3d, 0x95, 0x6d, 0x4a, 0x60, 0x9e, - 0x79, 0x88, 0x35, 0xac, 0x26, 0xe6, 0x98, 0x8a, 0x0e, 0x53, 0x26, 0x10, 0x4b, 0xd7, 0xc2, 0x15, - 0x58, 0x06, 0xaf, 0x77, 0x6d, 0xb0, 0x90, 0xe7, 0x91, 0x4d, 0xe4, 0xdb, 0x58, 0x68, 0x9f, 0x32, - 0xf7, 0x77, 0xb6, 0x56, 0xe3, 0x47, 0xf0, 0x36, 0x28, 0xf8, 0xf8, 0x2e, 0xb7, 0x28, 0x0e, 0x3c, - 0xec, 0xbb, 0xac, 0x61, 0xd9, 0xc8, 0x77, 0x42, 0xb1, 0xb8, 0x30, 0x25, 0x66, 0x5e, 0xd5, 0xa3, - 0x9b, 0x5f, 0x8f, 0x6f, 0x7e, 0xfd, 0x46, 0x7c, 0xf3, 0xd7, 0x66, 0xc3, 0x3b, 0xec, 0xc1, 0x1f, - 0x25, 0xc5, 0x3c, 0x18, 0xa2, 0x98, 0x31, 0xc8, 0x72, 0x8c, 0x01, 0xd7, 0xc1, 0xee, 0x00, 0xd9, - 0x5f, 0x62, 0xce, 0x0a, 0xd3, 0xe2, 0x56, 0x3a, 0x9b, 0xe9, 0x08, 0xc5, 0x0e, 0x38, 0xeb, 0x21, - 0xe7, 0x35, 0x81, 0x60, 0xc6, 0x48, 0xda, 0x45, 0x79, 0x88, 0x93, 0x5d, 0xf1, 0xc4, 0x45, 0x1b, - 0x2f, 0x22, 0x8e, 0x32, 0xdc, 0xf4, 0xbf, 0xc7, 0x17, 0xd8, 0x50, 0x18, 0x69, 0xfe, 0x90, 0x69, - 0x83, 0x60, 0x9a, 0xb9, 0x5f, 0x45, 0x2e, 0x4f, 0x9b, 0xe2, 0x33, 0xdc, 0x04, 0xfb, 0x83, 0x04, - 0xe4, 0xb2, 0xcf, 0x78, 0x68, 0x36, 0x2b, 0x4c, 0x09, 0x0b, 0x2a, 0xe3, 0x59, 0xd0, 0x61, 0x73, - 0x8b, 0xa2, 0x20, 0xc0, 0x54, 0xbe, 0x3a, 0xd2, 0x3a, 0x68, 0xbf, 0x2a, 0xe0, 0x40, 0x9a, 0x79, - 0xf0, 0x36, 0xd8, 0x53, 0xf7, 0xc8, 0x06, 0xf2, 0x2c, 0xec, 0x73, 0xba, 0x25, 0x2f, 0xb4, 0xf7, - 0x33, 0x51, 0x59, 0x15, 0x85, 0x02, 0x6d, 0x25, 0x2c, 0x96, 0x04, 0xe6, 0x23, 0x40, 0xb1, 0x04, - 0x57, 0xc0, 0xb4, 0x83, 0x38, 0x12, 0x2e, 0xcc, 0x97, 0x4f, 0x0e, 0x7b, 0x1d, 0x76, 0xd1, 0x0a, - 0xc9, 0x4b, 0x34, 0x51, 0xae, 0x3d, 0x55, 0x80, 0xba, 0xb3, 0x72, 0xb8, 0x06, 0xf6, 0x44, 0x23, - 0x1e, 0x69, 0x97, 0x2a, 0xc6, 0xe9, 0x76, 0x29, 0x67, 0x46, 0xc7, 0x48, 0xfa, 0xf2, 0x39, 0x80, - 0x6d, 0x66, 0x5b, 0x4d, 0xc4, 0x5b, 0x61, 0xdc, 0x90, 0xb8, 0xf9, 0xd1, 0x2f, 0xf5, 0x9b, 0xeb, - 0xcb, 0xd7, 0xa2, 0xa2, 0x1e, 0xf0, 0x7d, 0x6d, 0x66, 0xf7, 0xac, 0xd7, 0x66, 0x22, 0x67, 0xb4, - 0x77, 0xc1, 0x09, 0x31, 0x6e, 0x26, 0xae, 0xbb, 0x8c, 0x63, 0xda, 0x99, 0x37, 0x13, 0x6f, 0x22, - 0xea, 0x5c, 0xc4, 0x3e, 0x69, 0x26, 0x6f, 0xaa, 0x15, 0x70, 0x32, 0xd3, 0x6e, 0x39, 0x9f, 0x07, - 0xc1, 0x8c, 0x23, 0x56, 0xc4, 0xcb, 0x7f, 0xce, 0x94, 0xdf, 0xca, 0x3f, 0xbf, 0x06, 0x76, 0x09, - 0x1c, 0xb8, 0xad, 0x80, 0x03, 0x69, 0xc9, 0x06, 0x5e, 0xc8, 0x34, 0x03, 0x43, 0xe2, 0x94, 0x5a, - 0x7d, 0x01, 0x84, 0x88, 0xbf, 0xb6, 0xf2, 0xed, 0x93, 0xbf, 0x7e, 0xcc, 0x57, 0xe0, 0xd2, 0xe8, - 0xc4, 0x9b, 0x5c, 0xed, 0x32, 0x3a, 0x19, 0xf7, 0xe2, 0x93, 0xf9, 0x35, 0x7c, 0xa2, 0x80, 0xfd, - 0x29, 0x19, 0x09, 0x56, 0xc6, 0x67, 0xd8, 0x93, 0xbd, 0xd4, 0x0b, 0x93, 0x03, 0x48, 0x85, 0x67, - 0x85, 0xc2, 0xd3, 0x70, 0x71, 0x0c, 0x85, 0x51, 0x2a, 0x83, 0xdf, 0xe4, 0x41, 0x61, 0x87, 0xa8, - 0xc5, 0xe0, 0xd5, 0x09, 0x99, 0xa5, 0xa6, 0x3a, 0xf5, 0xda, 0x4b, 0x42, 0x93, 0xa2, 0x2f, 0x09, - 0xd1, 0x35, 0x78, 0x61, 0x5c, 0xd1, 0x61, 0xb8, 0xa6, 0xdc, 0x4a, 0x02, 0x13, 0xfc, 0x4f, 0x01, - 0x6f, 0xa4, 0x27, 0x37, 0x06, 0xaf, 0x4c, 0x4c, 0x7a, 0x30, 0x22, 0xaa, 0x57, 0x5f, 0x0e, 0x98, - 0x34, 0x60, 0x55, 0x18, 0x50, 0x85, 0x95, 0x09, 0x0c, 0x20, 0x41, 0x97, 0xfe, 0x7f, 0x14, 0x19, - 0x0e, 0x52, 0x63, 0x16, 0xfc, 0x28, 0x3b, 0xeb, 0x61, 0x81, 0x51, 0x5d, 0x7d, 0x61, 0x1c, 0x29, - 0xbc, 0x2a, 0x84, 0x7f, 0x00, 0xcf, 0x66, 0xf8, 0x0b, 0x1b, 0x03, 0x59, 0x3d, 0xa9, 0x2d, 0x45, - 0x72, 0x77, 0xfc, 0x9a, 0x48, 0x72, 0x4a, 0x90, 0x9c, 0x48, 0x72, 0x5a, 0x0e, 0x9c, 0x4c, 0x72, - 0x4f, 0x72, 0x84, 0xbf, 0x29, 0x00, 0x0e, 0x46, 0x40, 0x78, 0x3e, 0x3b, 0xc5, 0xb4, 0x64, 0xa9, - 0x56, 0x26, 0xae, 0x97, 0xd2, 0xce, 0x08, 0x69, 0x65, 0x78, 0x6a, 0xb4, 0x34, 0x2e, 0x01, 0xa2, - 0xbf, 0xc7, 0xf0, 0xbb, 0x3c, 0x38, 0x3a, 0x2a, 0x65, 0x8d, 0x73, 0x87, 0x8d, 0xce, 0x7c, 0xe3, - 0xdc, 0x61, 0x19, 0xa2, 0x9f, 0x56, 0x13, 0xda, 0x3f, 0x84, 0xe7, 0x46, 0x6b, 0x0f, 0xb0, 0xef, - 0xb8, 0x7e, 0xbd, 0x33, 0xc7, 0x32, 0xb1, 0xc2, 0x9f, 0xf2, 0xe0, 0x58, 0x86, 0xd7, 0x39, 0xbc, - 0x9e, 0x9d, 0x7a, 0xa6, 0x18, 0xa1, 0xae, 0xbd, 0x3c, 0x40, 0x69, 0xc7, 0x15, 0x61, 0xc7, 0x0a, - 0x5c, 0x1e, 0x6d, 0x07, 0x4d, 0x10, 0x3b, 0x8e, 0x50, 0x81, 0x69, 0x45, 0xf1, 0xa4, 0x76, 0xeb, - 0xd1, 0x76, 0x51, 0x79, 0xbc, 0x5d, 0x54, 0xfe, 0xdc, 0x2e, 0x2a, 0x0f, 0x9e, 0x17, 0x73, 0x8f, - 0x9f, 0x17, 0x73, 0x4f, 0x9f, 0x17, 0x73, 0x9f, 0x2c, 0xd5, 0x5d, 0xde, 0x68, 0x6d, 0xe8, 0x36, - 0x69, 0x1a, 0x36, 0x61, 0x4d, 0xc2, 0xba, 0xfa, 0xbd, 0x97, 0xf4, 0x6b, 0x9f, 0x36, 0xee, 0xf6, - 0xcd, 0xdf, 0x56, 0x80, 0xd9, 0xc6, 0x8c, 0xf8, 0xb7, 0x72, 0xfa, 0xff, 0x00, 0x00, 0x00, 0xff, - 0xff, 0x03, 0xbe, 0x75, 0x9c, 0x41, 0x13, 0x00, 0x00, + // 1170 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcf, 0x6f, 0x1b, 0xc5, + 0x17, 0xf7, 0x26, 0x6d, 0xbe, 0xc9, 0xe4, 0xdb, 0x1f, 0x4c, 0x4b, 0x71, 0x37, 0xc1, 0x2e, 0x5b, + 0x01, 0x69, 0x81, 0xdd, 0xc4, 0xb9, 0xb4, 0x81, 0x34, 0xb1, 0xe3, 0x10, 0xac, 0xb6, 0x6a, 0xd8, + 0x56, 0x20, 0x01, 0x62, 0xd9, 0xec, 0x0e, 0xf6, 0x4a, 0xeb, 0x9d, 0xed, 0xcc, 0xd8, 0x69, 0x54, + 0x71, 0x28, 0x48, 0xd0, 0x63, 0x25, 0xc4, 0xbd, 0x7f, 0x4e, 0x6f, 0x14, 0xf5, 0xc2, 0xa9, 0xa0, + 0x84, 0x03, 0xe2, 0x84, 0xb8, 0x23, 0xa1, 0x9d, 0x9d, 0x5d, 0xaf, 0xed, 0x8d, 0xbd, 0x76, 0x72, + 0xb3, 0x67, 0xde, 0xfb, 0xbc, 0xcf, 0xe7, 0xf9, 0xcd, 0x7b, 0xcf, 0x40, 0x73, 0x3c, 0x86, 0x88, + 0xd5, 0x30, 0x1d, 0xcf, 0xa0, 0xc8, 0x6a, 0x11, 0x87, 0xed, 0x69, 0x96, 0xd5, 0xd6, 0x7c, 0x82, + 0xdb, 0x8e, 0x8d, 0x88, 0xd6, 0x5e, 0xd2, 0xee, 0xb7, 0x10, 0xd9, 0x53, 0x7d, 0x82, 0x19, 0x86, + 0x97, 0x53, 0x1c, 0x54, 0xcb, 0x6a, 0xab, 0x91, 0x83, 0xda, 0x5e, 0x92, 0xe7, 0xeb, 0x18, 0xd7, + 0x5d, 0xa4, 0x99, 0xbe, 0xa3, 0x99, 0x9e, 0x87, 0x99, 0xc9, 0x1c, 0xec, 0xd1, 0x10, 0x42, 0x3e, + 0x5f, 0xc7, 0x75, 0xcc, 0x3f, 0x6a, 0xc1, 0x27, 0x71, 0x5a, 0x14, 0x3e, 0xfc, 0xdb, 0x4e, 0xeb, + 0x6b, 0x8d, 0x39, 0x4d, 0x44, 0x99, 0xd9, 0xf4, 0x85, 0x41, 0x29, 0x0b, 0xd5, 0x98, 0x45, 0xe8, + 0xb3, 0x78, 0x98, 0x4f, 0x7b, 0x49, 0xa3, 0x0d, 0x93, 0x20, 0xdb, 0xb0, 0xb0, 0x47, 0x5b, 0xcd, + 0xd8, 0xe3, 0xcd, 0x01, 0x1e, 0xbb, 0x0e, 0x41, 0xa1, 0x99, 0x72, 0x0d, 0xcc, 0x7d, 0x1c, 0x64, + 0x65, 0x43, 0x78, 0x6f, 0x21, 0x0f, 0x51, 0x87, 0xea, 0xe8, 0x7e, 0x0b, 0x51, 0x06, 0x2f, 0x82, + 0xe9, 0x10, 0xc2, 0xb1, 0xf3, 0xd2, 0x25, 0x69, 0x61, 0x46, 0xff, 0x1f, 0xff, 0x5e, 0xb3, 0x95, + 0x87, 0x60, 0x3e, 0xdd, 0x93, 0xfa, 0xd8, 0xa3, 0x08, 0x7e, 0x0e, 0x4e, 0xd5, 0xc3, 0x23, 0x83, + 0x32, 0x93, 0x21, 0xee, 0x3f, 0x5b, 0x5a, 0x54, 0x0f, 0x4b, 0x7c, 0x7b, 0x49, 0xed, 0xc1, 0xba, + 0x1b, 0xf8, 0x55, 0x4e, 0x3c, 0x7b, 0x59, 0xcc, 0xe9, 0xff, 0xaf, 0x27, 0xce, 0x94, 0x79, 0x20, + 0x77, 0x05, 0xdf, 0x08, 0xe0, 0x22, 0xd6, 0x8a, 0xd9, 0x23, 0x2a, 0xba, 0x15, 0xcc, 0x2a, 0x60, + 0x8a, 0x87, 0xa7, 0x79, 0xe9, 0xd2, 0xe4, 0xc2, 0x6c, 0xe9, 0xaa, 0x9a, 0xa1, 0x16, 0x54, 0x0e, + 0xa2, 0x0b, 0x4f, 0xe5, 0x0a, 0x78, 0xbb, 0x3f, 0xc4, 0x5d, 0x66, 0x12, 0xb6, 0x4d, 0xb0, 0x8f, + 0xa9, 0xe9, 0xc6, 0x6c, 0x1e, 0x4b, 0x60, 0x61, 0xb8, 0xad, 0xe0, 0xf6, 0x05, 0x98, 0xf1, 0xa3, + 0x43, 0x91, 0xb1, 0x1b, 0xd9, 0xe8, 0x09, 0xf0, 0xb2, 0x6d, 0x3b, 0x41, 0x91, 0x76, 0xa0, 0x3b, + 0x80, 0xca, 0x02, 0x78, 0x2b, 0x8d, 0x09, 0xf6, 0xfb, 0x48, 0x7f, 0x2f, 0xa5, 0x0b, 0xec, 0x32, + 0x8d, 0x7f, 0xe9, 0x3e, 0xce, 0xab, 0x23, 0x71, 0xd6, 0x51, 0x13, 0xb7, 0x4d, 0x37, 0x95, 0xf2, + 0x1a, 0x38, 0xc9, 0x43, 0x0f, 0x28, 0x45, 0x38, 0x07, 0x66, 0x2c, 0xd7, 0x41, 0x1e, 0x0b, 0xee, + 0x26, 0xf8, 0xdd, 0x74, 0x78, 0x50, 0xb3, 0x95, 0x1f, 0x24, 0xf0, 0x06, 0x57, 0xf2, 0x89, 0xe9, + 0x3a, 0xb6, 0xc9, 0x30, 0x49, 0xa4, 0x8a, 0x0c, 0x2f, 0x74, 0xb8, 0x0a, 0xce, 0x46, 0xa4, 0x0d, + 0xd3, 0xb6, 0x09, 0xa2, 0x34, 0x0c, 0x52, 0x81, 0xff, 0xbc, 0x2c, 0x9e, 0xde, 0x33, 0x9b, 0xee, + 0x8a, 0x22, 0x2e, 0x14, 0xfd, 0x4c, 0x64, 0x5b, 0x0e, 0x4f, 0x56, 0xa6, 0x1f, 0x3f, 0x2d, 0xe6, + 0xfe, 0x7c, 0x5a, 0xcc, 0x29, 0x77, 0x80, 0x32, 0x88, 0x88, 0xc8, 0xe6, 0x15, 0x70, 0x36, 0x7a, + 0xca, 0x71, 0xb8, 0x90, 0xd1, 0x19, 0x2b, 0x61, 0x1f, 0x04, 0xeb, 0x97, 0xb6, 0x9d, 0x08, 0x9e, + 0x4d, 0x5a, 0x5f, 0xac, 0x01, 0xd2, 0x7a, 0xe2, 0x0f, 0x92, 0xd6, 0x4d, 0xa4, 0x23, 0xad, 0x2f, + 0x93, 0x42, 0x5a, 0x4f, 0xd6, 0x94, 0x39, 0x70, 0x91, 0x03, 0xde, 0x6b, 0x10, 0xcc, 0x98, 0x8b, + 0xf8, 0xb3, 0x8f, 0x8a, 0xf3, 0x17, 0x49, 0x3c, 0xff, 0x9e, 0x5b, 0x11, 0xa6, 0x08, 0x66, 0xa9, + 0x6b, 0xd2, 0x86, 0xd1, 0x44, 0x0c, 0x11, 0x1e, 0x61, 0x52, 0x07, 0xfc, 0xe8, 0x76, 0x70, 0x02, + 0x4b, 0xe0, 0xd5, 0x84, 0x81, 0x61, 0xba, 0x2e, 0xde, 0x35, 0x3d, 0x0b, 0x71, 0xed, 0x93, 0xfa, + 0xb9, 0x8e, 0x69, 0x39, 0xba, 0x82, 0x5f, 0x82, 0xbc, 0x87, 0x1e, 0x30, 0x83, 0x20, 0xdf, 0x45, + 0x9e, 0x43, 0x1b, 0x86, 0x65, 0x7a, 0x76, 0x20, 0x16, 0xe5, 0x27, 0x79, 0xcd, 0xcb, 0x6a, 0xd8, + 0xf9, 0xd5, 0xa8, 0xf3, 0xab, 0xf7, 0xa2, 0xce, 0x5f, 0x99, 0x0e, 0x7a, 0xd8, 0x93, 0xdf, 0x8a, + 0x92, 0x7e, 0x21, 0x40, 0xd1, 0x23, 0x90, 0x8d, 0x08, 0x43, 0x79, 0x17, 0x5c, 0xe5, 0x92, 0x74, + 0x54, 0x77, 0x28, 0x43, 0x04, 0xd9, 0x9d, 0xd7, 0xb1, 0x6b, 0x12, 0xbb, 0x8a, 0x3c, 0xdc, 0x8c, + 0x9f, 0xe7, 0x26, 0x78, 0x27, 0x93, 0xb5, 0xc8, 0xc8, 0x05, 0x30, 0x65, 0xf3, 0x13, 0xde, 0xf1, + 0x66, 0x74, 0xf1, 0x4d, 0x29, 0x88, 0x1e, 0x1e, 0xbe, 0x3c, 0x64, 0xf3, 0x97, 0x56, 0xab, 0xc6, + 0x61, 0x1e, 0x49, 0xe0, 0xf5, 0x43, 0x0c, 0x04, 0xf2, 0x57, 0xe0, 0xb4, 0x9f, 0xbc, 0x8b, 0x7a, + 0x6a, 0x29, 0x53, 0x03, 0xe8, 0x82, 0x15, 0x8d, 0xbe, 0x07, 0x4f, 0xa9, 0x81, 0x53, 0x5d, 0x66, + 0x30, 0x0f, 0x44, 0xfd, 0x56, 0xbb, 0xcb, 0xb9, 0x0a, 0x0b, 0x00, 0x44, 0x8d, 0xa3, 0x56, 0xe5, + 0x3f, 0xe6, 0x09, 0x3d, 0x71, 0x52, 0xfa, 0xee, 0x15, 0x70, 0x92, 0xcb, 0x81, 0xfb, 0x12, 0x38, + 0x9f, 0x36, 0xbd, 0xe0, 0x7a, 0x26, 0xde, 0x03, 0x46, 0xa6, 0x5c, 0x3e, 0x02, 0x42, 0x98, 0x54, + 0x65, 0xf3, 0xdb, 0x17, 0x7f, 0xfc, 0x38, 0xb1, 0x06, 0x57, 0x87, 0x6f, 0x35, 0xf1, 0xf3, 0x15, + 0xe3, 0x51, 0x7b, 0x18, 0xbd, 0xf5, 0x6f, 0xe0, 0x0b, 0x09, 0x9c, 0x4b, 0x99, 0x83, 0x70, 0x6d, + 0x74, 0x86, 0x5d, 0xf3, 0x55, 0x5e, 0x1f, 0x1f, 0x40, 0x28, 0xbc, 0xce, 0x15, 0x2e, 0xc3, 0xa5, + 0x11, 0x14, 0x86, 0x93, 0x17, 0x3e, 0x9a, 0x00, 0xf9, 0x43, 0xc6, 0x29, 0x85, 0xb7, 0xc6, 0x64, + 0x96, 0x3a, 0xb9, 0xe5, 0xdb, 0xc7, 0x84, 0x26, 0x44, 0x7f, 0xc4, 0x45, 0x57, 0xe0, 0xfa, 0xa8, + 0xa2, 0x83, 0x05, 0x8a, 0x30, 0x23, 0x1e, 0x8a, 0xf0, 0x5f, 0x09, 0xbc, 0x96, 0x3e, 0x9d, 0x29, + 0xbc, 0x39, 0x36, 0xe9, 0xfe, 0x35, 0x40, 0xbe, 0x75, 0x3c, 0x60, 0x22, 0x01, 0x5b, 0x3c, 0x01, + 0x65, 0xb8, 0x36, 0x46, 0x02, 0xb0, 0x9f, 0xd0, 0xff, 0x77, 0x34, 0x00, 0x52, 0x47, 0x29, 0xfc, + 0x30, 0x3b, 0xeb, 0x41, 0x4b, 0x81, 0xbc, 0x75, 0x64, 0x1c, 0x21, 0xbc, 0xcc, 0x85, 0xbf, 0x0f, + 0xaf, 0x67, 0xf8, 0x9b, 0x12, 0x01, 0x19, 0x5d, 0x93, 0x39, 0x45, 0x72, 0x72, 0xc4, 0x8e, 0x25, + 0x39, 0x65, 0x59, 0x18, 0x4b, 0x72, 0xda, 0xac, 0x1f, 0x4f, 0x72, 0xd7, 0x76, 0x00, 0x7f, 0x96, + 0x00, 0xec, 0x1f, 0xf3, 0xf0, 0x46, 0x76, 0x8a, 0x69, 0xdb, 0x83, 0xbc, 0x36, 0xb6, 0xbf, 0x90, + 0x76, 0x8d, 0x4b, 0x2b, 0xc1, 0xc5, 0xe1, 0xd2, 0x98, 0x00, 0x08, 0xff, 0x02, 0xc1, 0x9f, 0x26, + 0xc0, 0xe5, 0x0c, 0x73, 0x1b, 0xde, 0xc9, 0x4e, 0x31, 0xd3, 0xbe, 0x20, 0x6f, 0x1f, 0x1f, 0xa0, + 0x48, 0xc2, 0x4d, 0x9e, 0x84, 0x4d, 0xb8, 0x31, 0x3c, 0x09, 0x24, 0x46, 0xec, 0xd4, 0x34, 0xe1, + 0x98, 0x46, 0xb8, 0x87, 0xc0, 0xbf, 0xfa, 0xf6, 0x8c, 0x64, 0x33, 0xa9, 0x55, 0x29, 0x1c, 0x61, + 0xaa, 0x1e, 0xb2, 0xcc, 0xc8, 0x95, 0xa3, 0x40, 0x08, 0xd5, 0x15, 0xae, 0xfa, 0x03, 0xb8, 0x32, + 0x5c, 0x75, 0xb4, 0xc6, 0x18, 0x3d, 0x03, 0xac, 0xf2, 0xe9, 0xb3, 0xfd, 0x82, 0xf4, 0x7c, 0xbf, + 0x20, 0xfd, 0xbe, 0x5f, 0x90, 0x9e, 0x1c, 0x14, 0x72, 0xcf, 0x0f, 0x0a, 0xb9, 0x5f, 0x0f, 0x0a, + 0xb9, 0xcf, 0x56, 0xeb, 0x0e, 0x6b, 0xb4, 0x76, 0x54, 0x0b, 0x37, 0x35, 0x0b, 0xd3, 0x26, 0xa6, + 0x89, 0x30, 0xef, 0xc5, 0x61, 0xda, 0xcb, 0xda, 0x83, 0x9e, 0x32, 0xdb, 0xf3, 0x11, 0xdd, 0x99, + 0xe2, 0x8b, 0xe7, 0xf2, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc2, 0x02, 0x37, 0x01, 0x0c, 0x11, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1185,12 +1049,12 @@ type QueryClient interface { // QueryThrottleState returns the main on-chain state relevant to currently // throttled slash packets QueryThrottleState(ctx context.Context, in *QueryThrottleStateRequest, opts ...grpc.CallOption) (*QueryThrottleStateResponse, error) - // QueryThrottledConsumerPacketData returns a list of pending packet data - // instances (slash packet and vsc matured) for a single consumer chain - QueryThrottledConsumerPacketData(ctx context.Context, in *QueryThrottledConsumerPacketDataRequest, opts ...grpc.CallOption) (*QueryThrottledConsumerPacketDataResponse, 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) } type queryClient struct { @@ -1264,18 +1128,18 @@ func (c *queryClient) QueryThrottleState(ctx context.Context, in *QueryThrottleS return out, nil } -func (c *queryClient) QueryThrottledConsumerPacketData(ctx context.Context, in *QueryThrottledConsumerPacketDataRequest, opts ...grpc.CallOption) (*QueryThrottledConsumerPacketDataResponse, error) { - out := new(QueryThrottledConsumerPacketDataResponse) - err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Query/QueryThrottledConsumerPacketData", in, out, opts...) +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 } -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...) +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 } @@ -1303,12 +1167,12 @@ type QueryServer interface { // QueryThrottleState returns the main on-chain state relevant to currently // throttled slash packets QueryThrottleState(context.Context, *QueryThrottleStateRequest) (*QueryThrottleStateResponse, error) - // QueryThrottledConsumerPacketData returns a list of pending packet data - // instances (slash packet and vsc matured) for a single consumer chain - QueryThrottledConsumerPacketData(context.Context, *QueryThrottledConsumerPacketDataRequest) (*QueryThrottledConsumerPacketDataResponse, 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) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -1336,12 +1200,12 @@ func (*UnimplementedQueryServer) QueryValidatorProviderAddr(ctx context.Context, func (*UnimplementedQueryServer) QueryThrottleState(ctx context.Context, req *QueryThrottleStateRequest) (*QueryThrottleStateResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryThrottleState not implemented") } -func (*UnimplementedQueryServer) QueryThrottledConsumerPacketData(ctx context.Context, req *QueryThrottledConsumerPacketDataRequest) (*QueryThrottledConsumerPacketDataResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryThrottledConsumerPacketData not implemented") -} func (*UnimplementedQueryServer) QueryRegisteredConsumerRewardDenoms(ctx context.Context, req *QueryRegisteredConsumerRewardDenomsRequest) (*QueryRegisteredConsumerRewardDenomsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryRegisteredConsumerRewardDenoms not implemented") } +func (*UnimplementedQueryServer) QueryProposedConsumerChainIDs(ctx context.Context, req *QueryProposedChainIDsRequest) (*QueryProposedChainIDsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryProposedConsumerChainIDs not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -1473,38 +1337,38 @@ func _Query_QueryThrottleState_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } -func _Query_QueryThrottledConsumerPacketData_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryThrottledConsumerPacketDataRequest) +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).QueryThrottledConsumerPacketData(ctx, in) + return srv.(QueryServer).QueryRegisteredConsumerRewardDenoms(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryThrottledConsumerPacketData", + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryRegisteredConsumerRewardDenoms", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).QueryThrottledConsumerPacketData(ctx, req.(*QueryThrottledConsumerPacketDataRequest)) + return srv.(QueryServer).QueryRegisteredConsumerRewardDenoms(ctx, req.(*QueryRegisteredConsumerRewardDenomsRequest)) } return interceptor(ctx, in, info, handler) } -func _Query_QueryRegisteredConsumerRewardDenoms_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryRegisteredConsumerRewardDenomsRequest) +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).QueryRegisteredConsumerRewardDenoms(ctx, in) + return srv.(QueryServer).QueryProposedConsumerChainIDs(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryRegisteredConsumerRewardDenoms", + FullMethod: "/interchain_security.ccv.provider.v1.Query/QueryProposedConsumerChainIDs", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).QueryRegisteredConsumerRewardDenoms(ctx, req.(*QueryRegisteredConsumerRewardDenomsRequest)) + return srv.(QueryServer).QueryProposedConsumerChainIDs(ctx, req.(*QueryProposedChainIDsRequest)) } return interceptor(ctx, in, info, handler) } @@ -1541,14 +1405,14 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "QueryThrottleState", Handler: _Query_QueryThrottleState_Handler, }, - { - MethodName: "QueryThrottledConsumerPacketData", - Handler: _Query_QueryThrottledConsumerPacketData_Handler, - }, { MethodName: "QueryRegisteredConsumerRewardDenoms", Handler: _Query_QueryRegisteredConsumerRewardDenoms_Handler, }, + { + MethodName: "QueryProposedConsumerChainIDs", + Handler: _Query_QueryProposedConsumerChainIDs_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "interchain_security/ccv/provider/v1/query.proto", @@ -2007,20 +1871,6 @@ func (m *QueryThrottleStateResponse) MarshalToSizedBuffer(dAtA []byte) (int, err _ = i var l int _ = l - if len(m.Packets) > 0 { - for iNdEx := len(m.Packets) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Packets[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - } 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 @@ -2042,7 +1892,7 @@ func (m *QueryThrottleStateResponse) MarshalToSizedBuffer(dAtA []byte) (int, err return len(dAtA) - i, nil } -func (m *QueryThrottledConsumerPacketDataRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryRegisteredConsumerRewardDenomsRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2052,27 +1902,20 @@ func (m *QueryThrottledConsumerPacketDataRequest) Marshal() (dAtA []byte, err er return dAtA[:n], nil } -func (m *QueryThrottledConsumerPacketDataRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryRegisteredConsumerRewardDenomsRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryThrottledConsumerPacketDataRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryRegisteredConsumerRewardDenomsRequest) 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 *QueryThrottledConsumerPacketDataResponse) Marshal() (dAtA []byte, err error) { +func (m *QueryRegisteredConsumerRewardDenomsResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2082,46 +1925,29 @@ func (m *QueryThrottledConsumerPacketDataResponse) Marshal() (dAtA []byte, err e return dAtA[:n], nil } -func (m *QueryThrottledConsumerPacketDataResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryRegisteredConsumerRewardDenomsResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryThrottledConsumerPacketDataResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryRegisteredConsumerRewardDenomsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.PacketDataInstances) > 0 { - for iNdEx := len(m.PacketDataInstances) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.PacketDataInstances[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } + 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] = 0x1a + dAtA[i] = 0xa } } - if m.Size_ != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.Size_)) - 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 *ThrottledSlashPacket) Marshal() (dAtA []byte, err error) { +func (m *QueryProposedChainIDsRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2131,40 +1957,20 @@ func (m *ThrottledSlashPacket) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ThrottledSlashPacket) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryProposedChainIDsRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ThrottledSlashPacket) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryProposedChainIDsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - { - size, err := m.Data.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - { - size, err := m.GlobalEntry.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 *ThrottledPacketDataWrapper) Marshal() (dAtA []byte, err error) { +func (m *QueryProposedChainIDsResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2174,121 +1980,64 @@ func (m *ThrottledPacketDataWrapper) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *ThrottledPacketDataWrapper) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryProposedChainIDsResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *ThrottledPacketDataWrapper) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryProposedChainIDsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.Data != nil { - { - size := m.Data.Size() - i -= size - if _, err := m.Data.MarshalTo(dAtA[i:]); err != nil { - return 0, err + 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 (m *ThrottledPacketDataWrapper_SlashPacket) MarshalTo(dAtA []byte) (int, error) { +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 *ThrottledPacketDataWrapper_SlashPacket) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.SlashPacket != nil { - { - size, err := m.SlashPacket.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 *ThrottledPacketDataWrapper_VscMaturedPacket) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ThrottledPacketDataWrapper_VscMaturedPacket) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - if m.VscMaturedPacket != nil { - { - size, err := m.VscMaturedPacket.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - return len(dAtA) - i, nil -} -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) { +func (m *ProposedChain) 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 + if m.ProposalID != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.ProposalID)) + i-- + dAtA[i] = 0x10 } - 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 - 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 - } + 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 } @@ -2496,119 +2245,69 @@ func (m *QueryThrottleStateResponse) Size() (n int) { } l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.NextReplenishCandidate) n += 1 + l + sovQuery(uint64(l)) - if len(m.Packets) > 0 { - for _, e := range m.Packets { - l = e.Size() - n += 1 + l + sovQuery(uint64(l)) - } - } return n } -func (m *QueryThrottledConsumerPacketDataRequest) Size() (n int) { +func (m *QueryRegisteredConsumerRewardDenomsRequest) 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 *QueryThrottledConsumerPacketDataResponse) Size() (n int) { +func (m *QueryRegisteredConsumerRewardDenomsResponse) 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.Size_ != 0 { - n += 1 + sovQuery(uint64(m.Size_)) - } - if len(m.PacketDataInstances) > 0 { - for _, e := range m.PacketDataInstances { - l = e.Size() + if len(m.Denoms) > 0 { + for _, s := range m.Denoms { + l = len(s) n += 1 + l + sovQuery(uint64(l)) } } return n } -func (m *ThrottledSlashPacket) Size() (n int) { +func (m *QueryProposedChainIDsRequest) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = m.GlobalEntry.Size() - n += 1 + l + sovQuery(uint64(l)) - l = m.Data.Size() - n += 1 + l + sovQuery(uint64(l)) return n } -func (m *ThrottledPacketDataWrapper) Size() (n int) { +func (m *QueryProposedChainIDsResponse) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.Data != nil { - n += m.Data.Size() + if len(m.ProposedChains) > 0 { + for _, e := range m.ProposedChains { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } } return n } -func (m *ThrottledPacketDataWrapper_SlashPacket) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.SlashPacket != nil { - l = m.SlashPacket.Size() - n += 1 + l + sovQuery(uint64(l)) - } - return n -} -func (m *ThrottledPacketDataWrapper_VscMaturedPacket) Size() (n int) { +func (m *ProposedChain) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.VscMaturedPacket != nil { - l = m.VscMaturedPacket.Size() + l = len(m.ChainID) + if l > 0 { 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)) - } + if m.ProposalID != 0 { + n += 1 + sovQuery(uint64(m.ProposalID)) } return n } @@ -3846,40 +3545,6 @@ func (m *QueryThrottleStateResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Packets", 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.Packets = append(m.Packets, &ThrottledSlashPacket{}) - if err := m.Packets[len(m.Packets)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -3901,7 +3566,7 @@ func (m *QueryThrottleStateResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryThrottledConsumerPacketDataRequest) Unmarshal(dAtA []byte) error { +func (m *QueryRegisteredConsumerRewardDenomsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3924,44 +3589,12 @@ func (m *QueryThrottledConsumerPacketDataRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryThrottledConsumerPacketDataRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryThrottledConsumerPacketDataRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsRequest: 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:]) @@ -3983,7 +3616,7 @@ func (m *QueryThrottledConsumerPacketDataRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryThrottledConsumerPacketDataResponse) Unmarshal(dAtA []byte) error { +func (m *QueryRegisteredConsumerRewardDenomsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4006,15 +3639,15 @@ func (m *QueryThrottledConsumerPacketDataResponse) Unmarshal(dAtA []byte) error fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryThrottledConsumerPacketDataResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryThrottledConsumerPacketDataResponse: 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 ChainId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Denoms", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4042,60 +3675,7 @@ func (m *QueryThrottledConsumerPacketDataResponse) Unmarshal(dAtA []byte) error if postIndex > l { return io.ErrUnexpectedEOF } - m.ChainId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Size_", wireType) - } - m.Size_ = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Size_ |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PacketDataInstances", 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.PacketDataInstances = append(m.PacketDataInstances, ThrottledPacketDataWrapper{}) - if err := m.PacketDataInstances[len(m.PacketDataInstances)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Denoms = append(m.Denoms, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -4118,7 +3698,7 @@ func (m *QueryThrottledConsumerPacketDataResponse) Unmarshal(dAtA []byte) error } return nil } -func (m *ThrottledSlashPacket) Unmarshal(dAtA []byte) error { +func (m *QueryProposedChainIDsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4141,78 +3721,12 @@ func (m *ThrottledSlashPacket) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ThrottledSlashPacket: wiretype end group for non-group") + return fmt.Errorf("proto: QueryProposedChainIDsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ThrottledSlashPacket: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryProposedChainIDsRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GlobalEntry", 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.GlobalEntry.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", 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.Data.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -4234,7 +3748,7 @@ func (m *ThrottledSlashPacket) Unmarshal(dAtA []byte) error { } return nil } -func (m *ThrottledPacketDataWrapper) Unmarshal(dAtA []byte) error { +func (m *QueryProposedChainIDsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4257,15 +3771,15 @@ func (m *ThrottledPacketDataWrapper) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ThrottledPacketDataWrapper: wiretype end group for non-group") + return fmt.Errorf("proto: QueryProposedChainIDsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ThrottledPacketDataWrapper: 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 SlashPacket", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProposedChains", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4292,97 +3806,11 @@ func (m *ThrottledPacketDataWrapper) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - v := &types.SlashPacketData{} - if err := v.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 } - m.Data = &ThrottledPacketDataWrapper_SlashPacket{v} iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field VscMaturedPacket", 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 - } - v := &types.VSCMaturedPacketData{} - if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - m.Data = &ThrottledPacketDataWrapper_VscMaturedPacket{v} - 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 *QueryRegisteredConsumerRewardDenomsRequest) 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: QueryRegisteredConsumerRewardDenomsRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryRegisteredConsumerRewardDenomsRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -4404,7 +3832,7 @@ func (m *QueryRegisteredConsumerRewardDenomsRequest) Unmarshal(dAtA []byte) erro } return nil } -func (m *QueryRegisteredConsumerRewardDenomsResponse) Unmarshal(dAtA []byte) error { +func (m *ProposedChain) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -4427,15 +3855,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: ProposedChain: 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: 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 Denoms", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChainID", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -4463,8 +3891,27 @@ func (m *QueryRegisteredConsumerRewardDenomsResponse) Unmarshal(dAtA []byte) err if postIndex > l { return io.ErrUnexpectedEOF } - m.Denoms = append(m.Denoms, string(dAtA[iNdEx:postIndex])) + m.ChainID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ProposalID", wireType) + } + m.ProposalID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ProposalID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) diff --git a/x/ccv/provider/types/query.pb.gw.go b/x/ccv/provider/types/query.pb.gw.go index 6a249ca2a2..f16dc6181d 100644 --- a/x/ccv/provider/types/query.pb.gw.go +++ b/x/ccv/provider/types/query.pb.gw.go @@ -231,56 +231,38 @@ func local_request_Query_QueryThrottleState_0(ctx context.Context, marshaler run } -var ( - filter_Query_QueryThrottledConsumerPacketData_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} -) - -func request_Query_QueryThrottledConsumerPacketData_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryThrottledConsumerPacketDataRequest +func request_Query_QueryRegisteredConsumerRewardDenoms_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryRegisteredConsumerRewardDenomsRequest var metadata runtime.ServerMetadata - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_QueryThrottledConsumerPacketData_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.QueryThrottledConsumerPacketData(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.QueryRegisteredConsumerRewardDenoms(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_Query_QueryThrottledConsumerPacketData_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryThrottledConsumerPacketDataRequest +func local_request_Query_QueryRegisteredConsumerRewardDenoms_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryRegisteredConsumerRewardDenomsRequest var metadata runtime.ServerMetadata - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_QueryThrottledConsumerPacketData_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := server.QueryThrottledConsumerPacketData(ctx, &protoReq) + msg, err := server.QueryRegisteredConsumerRewardDenoms(ctx, &protoReq) return msg, metadata, err } -func request_Query_QueryRegisteredConsumerRewardDenoms_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryRegisteredConsumerRewardDenomsRequest +func request_Query_QueryProposedConsumerChainIDs_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryProposedChainIDsRequest var metadata runtime.ServerMetadata - msg, err := client.QueryRegisteredConsumerRewardDenoms(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.QueryProposedConsumerChainIDs(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_Query_QueryRegisteredConsumerRewardDenoms_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryRegisteredConsumerRewardDenomsRequest +func local_request_Query_QueryProposedConsumerChainIDs_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryProposedChainIDsRequest var metadata runtime.ServerMetadata - msg, err := server.QueryRegisteredConsumerRewardDenoms(ctx, &protoReq) + msg, err := server.QueryProposedConsumerChainIDs(ctx, &protoReq) return msg, metadata, err } @@ -452,7 +434,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) - mux.Handle("GET", pattern_Query_QueryThrottledConsumerPacketData_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_QueryRegisteredConsumerRewardDenoms_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -463,7 +445,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_Query_QueryThrottledConsumerPacketData_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_Query_QueryRegisteredConsumerRewardDenoms_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 { @@ -471,11 +453,11 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_Query_QueryThrottledConsumerPacketData_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_QueryRegisteredConsumerRewardDenoms_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_Query_QueryRegisteredConsumerRewardDenoms_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_QueryProposedConsumerChainIDs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -486,7 +468,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_Query_QueryRegisteredConsumerRewardDenoms_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_Query_QueryProposedConsumerChainIDs_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 { @@ -494,7 +476,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_Query_QueryRegisteredConsumerRewardDenoms_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_QueryProposedConsumerChainIDs_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -679,7 +661,7 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) - mux.Handle("GET", pattern_Query_QueryThrottledConsumerPacketData_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_QueryRegisteredConsumerRewardDenoms_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) @@ -688,18 +670,18 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Query_QueryThrottledConsumerPacketData_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Query_QueryRegisteredConsumerRewardDenoms_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_QueryThrottledConsumerPacketData_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_QueryRegisteredConsumerRewardDenoms_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_Query_QueryRegisteredConsumerRewardDenoms_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_QueryProposedConsumerChainIDs_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) @@ -708,14 +690,14 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Query_QueryRegisteredConsumerRewardDenoms_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Query_QueryProposedConsumerChainIDs_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_QueryRegisteredConsumerRewardDenoms_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_QueryProposedConsumerChainIDs_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -737,9 +719,9 @@ var ( pattern_Query_QueryThrottleState_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"interchain_security", "ccv", "provider", "throttle_state"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_QueryThrottledConsumerPacketData_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"interchain_security", "ccv", "provider", "pending_consumer_packets"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_QueryRegisteredConsumerRewardDenoms_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"interchain_security", "ccv", "provider", "registered_consumer_reward_denoms"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_QueryProposedConsumerChainIDs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"interchain_security", "ccv", "provider", "proposed_consumer_chains"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -757,7 +739,7 @@ var ( forward_Query_QueryThrottleState_0 = runtime.ForwardResponseMessage - forward_Query_QueryThrottledConsumerPacketData_0 = runtime.ForwardResponseMessage - forward_Query_QueryRegisteredConsumerRewardDenoms_0 = runtime.ForwardResponseMessage + + forward_Query_QueryProposedConsumerChainIDs_0 = runtime.ForwardResponseMessage ) diff --git a/x/ccv/provider/types/tx.pb.go b/x/ccv/provider/types/tx.pb.go index c5bebf0cd5..b89c515dd3 100644 --- a/x/ccv/provider/types/tx.pb.go +++ b/x/ccv/provider/types/tx.pb.go @@ -6,12 +6,13 @@ package types import ( context "context" fmt "fmt" + types "github.com/cometbft/cometbft/proto/tendermint/types" _ "github.com/cosmos/cosmos-proto" _ "github.com/cosmos/cosmos-sdk/codec/types" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" - _ "google.golang.org/genproto/googleapis/api/annotations" + _07_tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -111,9 +112,171 @@ func (m *MsgAssignConsumerKeyResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgAssignConsumerKeyResponse proto.InternalMessageInfo +// MsgSubmitConsumerMisbehaviour defines a message that reports a light client attack, +// also known as a misbehaviour, observed on a consumer chain +type MsgSubmitConsumerMisbehaviour struct { + Submitter string `protobuf:"bytes,1,opt,name=submitter,proto3" json:"submitter,omitempty"` + // The Misbehaviour of the consumer chain wrapping + // two conflicting IBC headers + Misbehaviour *_07_tendermint.Misbehaviour `protobuf:"bytes,2,opt,name=misbehaviour,proto3" json:"misbehaviour,omitempty"` +} + +func (m *MsgSubmitConsumerMisbehaviour) Reset() { *m = MsgSubmitConsumerMisbehaviour{} } +func (m *MsgSubmitConsumerMisbehaviour) String() string { return proto.CompactTextString(m) } +func (*MsgSubmitConsumerMisbehaviour) ProtoMessage() {} +func (*MsgSubmitConsumerMisbehaviour) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{2} +} +func (m *MsgSubmitConsumerMisbehaviour) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSubmitConsumerMisbehaviour) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSubmitConsumerMisbehaviour.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 *MsgSubmitConsumerMisbehaviour) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSubmitConsumerMisbehaviour.Merge(m, src) +} +func (m *MsgSubmitConsumerMisbehaviour) XXX_Size() int { + return m.Size() +} +func (m *MsgSubmitConsumerMisbehaviour) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSubmitConsumerMisbehaviour.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSubmitConsumerMisbehaviour proto.InternalMessageInfo + +type MsgSubmitConsumerMisbehaviourResponse struct { +} + +func (m *MsgSubmitConsumerMisbehaviourResponse) Reset() { *m = MsgSubmitConsumerMisbehaviourResponse{} } +func (m *MsgSubmitConsumerMisbehaviourResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSubmitConsumerMisbehaviourResponse) ProtoMessage() {} +func (*MsgSubmitConsumerMisbehaviourResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{3} +} +func (m *MsgSubmitConsumerMisbehaviourResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSubmitConsumerMisbehaviourResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSubmitConsumerMisbehaviourResponse.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 *MsgSubmitConsumerMisbehaviourResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSubmitConsumerMisbehaviourResponse.Merge(m, src) +} +func (m *MsgSubmitConsumerMisbehaviourResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgSubmitConsumerMisbehaviourResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSubmitConsumerMisbehaviourResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSubmitConsumerMisbehaviourResponse proto.InternalMessageInfo + +// MsgSubmitConsumerDoubleVoting defines a message that reports +// a double signing infraction observed on a consumer chain +type MsgSubmitConsumerDoubleVoting struct { + Submitter string `protobuf:"bytes,1,opt,name=submitter,proto3" json:"submitter,omitempty"` + // The equivocation of the consumer chain wrapping + // an evidence of a validator that signed two conflicting votes + DuplicateVoteEvidence *types.DuplicateVoteEvidence `protobuf:"bytes,2,opt,name=duplicate_vote_evidence,json=duplicateVoteEvidence,proto3" json:"duplicate_vote_evidence,omitempty"` + // The light client header of the infraction block + InfractionBlockHeader *_07_tendermint.Header `protobuf:"bytes,3,opt,name=infraction_block_header,json=infractionBlockHeader,proto3" json:"infraction_block_header,omitempty"` +} + +func (m *MsgSubmitConsumerDoubleVoting) Reset() { *m = MsgSubmitConsumerDoubleVoting{} } +func (m *MsgSubmitConsumerDoubleVoting) String() string { return proto.CompactTextString(m) } +func (*MsgSubmitConsumerDoubleVoting) ProtoMessage() {} +func (*MsgSubmitConsumerDoubleVoting) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{4} +} +func (m *MsgSubmitConsumerDoubleVoting) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSubmitConsumerDoubleVoting) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSubmitConsumerDoubleVoting.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 *MsgSubmitConsumerDoubleVoting) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSubmitConsumerDoubleVoting.Merge(m, src) +} +func (m *MsgSubmitConsumerDoubleVoting) XXX_Size() int { + return m.Size() +} +func (m *MsgSubmitConsumerDoubleVoting) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSubmitConsumerDoubleVoting.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSubmitConsumerDoubleVoting proto.InternalMessageInfo + +type MsgSubmitConsumerDoubleVotingResponse struct { +} + +func (m *MsgSubmitConsumerDoubleVotingResponse) Reset() { *m = MsgSubmitConsumerDoubleVotingResponse{} } +func (m *MsgSubmitConsumerDoubleVotingResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSubmitConsumerDoubleVotingResponse) ProtoMessage() {} +func (*MsgSubmitConsumerDoubleVotingResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_43221a4391e9fbf4, []int{5} +} +func (m *MsgSubmitConsumerDoubleVotingResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSubmitConsumerDoubleVotingResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSubmitConsumerDoubleVotingResponse.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 *MsgSubmitConsumerDoubleVotingResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSubmitConsumerDoubleVotingResponse.Merge(m, src) +} +func (m *MsgSubmitConsumerDoubleVotingResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgSubmitConsumerDoubleVotingResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSubmitConsumerDoubleVotingResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSubmitConsumerDoubleVotingResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgAssignConsumerKey)(nil), "interchain_security.ccv.provider.v1.MsgAssignConsumerKey") proto.RegisterType((*MsgAssignConsumerKeyResponse)(nil), "interchain_security.ccv.provider.v1.MsgAssignConsumerKeyResponse") + proto.RegisterType((*MsgSubmitConsumerMisbehaviour)(nil), "interchain_security.ccv.provider.v1.MsgSubmitConsumerMisbehaviour") + 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") } func init() { @@ -121,31 +284,46 @@ func init() { } var fileDescriptor_43221a4391e9fbf4 = []byte{ - // 375 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x52, 0x3d, 0x4f, 0xeb, 0x30, - 0x14, 0x8d, 0x5f, 0xa5, 0xf7, 0xfa, 0xfc, 0xfa, 0x9e, 0xf4, 0xa2, 0x0e, 0x6d, 0x55, 0xa5, 0x10, - 0x16, 0x06, 0x88, 0x55, 0x3a, 0x20, 0x2a, 0x31, 0xb4, 0x4c, 0x08, 0x75, 0xe9, 0x82, 0xc4, 0x12, - 0xa5, 0x8e, 0x71, 0x2d, 0x1a, 0x3b, 0xb2, 0x9d, 0xa8, 0xf9, 0x07, 0x8c, 0x30, 0x21, 0xb6, 0xfe, - 0x1c, 0xc6, 0x8e, 0x4c, 0x08, 0xb5, 0x0b, 0x33, 0xbf, 0x00, 0x35, 0x1f, 0x54, 0x88, 0x0e, 0x88, - 0xed, 0xde, 0x7b, 0x8e, 0xcf, 0x39, 0xf2, 0xbd, 0x70, 0x8f, 0x71, 0x4d, 0x24, 0x1e, 0x7b, 0x8c, - 0xbb, 0x8a, 0xe0, 0x48, 0x32, 0x9d, 0x20, 0x8c, 0x63, 0x14, 0x4a, 0x11, 0x33, 0x9f, 0x48, 0x14, - 0xb7, 0x91, 0x9e, 0x3a, 0xa1, 0x14, 0x5a, 0x98, 0x3b, 0x1b, 0xd8, 0x0e, 0xc6, 0xb1, 0x53, 0xb0, - 0x9d, 0xb8, 0xdd, 0x68, 0x52, 0x21, 0xe8, 0x84, 0x20, 0x2f, 0x64, 0xc8, 0xe3, 0x5c, 0x68, 0x4f, - 0x33, 0xc1, 0x55, 0x26, 0xd1, 0xa8, 0x52, 0x41, 0x45, 0x5a, 0xa2, 0x55, 0x95, 0x4f, 0xeb, 0x58, - 0xa8, 0x40, 0x28, 0x37, 0x03, 0xb2, 0xa6, 0x80, 0x72, 0xb9, 0xb4, 0x1b, 0x45, 0x97, 0xc8, 0xe3, - 0x49, 0x06, 0xd9, 0x77, 0x00, 0x56, 0x07, 0x8a, 0xf6, 0x94, 0x62, 0x94, 0x9f, 0x08, 0xae, 0xa2, - 0x80, 0xc8, 0x33, 0x92, 0x98, 0x75, 0x58, 0xce, 0x42, 0x32, 0xbf, 0x06, 0xb6, 0xc0, 0xee, 0xef, - 0xe1, 0xaf, 0xb4, 0x3f, 0xf5, 0xcd, 0x43, 0xf8, 0xb7, 0x08, 0xeb, 0x7a, 0xbe, 0x2f, 0x6b, 0x3f, - 0x56, 0x78, 0xdf, 0x7c, 0x7d, 0x6a, 0xfd, 0x4b, 0xbc, 0x60, 0xd2, 0xb5, 0x57, 0x53, 0xa2, 0x94, - 0x3d, 0xac, 0x14, 0xc4, 0x9e, 0xef, 0x4b, 0x73, 0x1b, 0x56, 0x70, 0x6e, 0xe1, 0x5e, 0x91, 0xa4, - 0x56, 0x4a, 0x75, 0xff, 0xe0, 0xb5, 0x6d, 0xb7, 0x7c, 0x3d, 0x6b, 0x19, 0x2f, 0xb3, 0x96, 0x61, - 0x5b, 0xb0, 0xb9, 0x29, 0xd8, 0x90, 0xa8, 0x50, 0x70, 0x45, 0x0e, 0xee, 0x01, 0x2c, 0x0d, 0x14, - 0x35, 0x6f, 0x01, 0xfc, 0xff, 0x39, 0xfe, 0x91, 0xf3, 0x85, 0x7f, 0x76, 0x36, 0x19, 0x34, 0x7a, - 0xdf, 0x7e, 0x5a, 0x64, 0xeb, 0x9f, 0x3f, 0x2c, 0x2c, 0x30, 0x5f, 0x58, 0xe0, 0x79, 0x61, 0x81, - 0x9b, 0xa5, 0x65, 0xcc, 0x97, 0x96, 0xf1, 0xb8, 0xb4, 0x8c, 0x8b, 0x63, 0xca, 0xf4, 0x38, 0x1a, - 0x39, 0x58, 0x04, 0xf9, 0x8e, 0xd0, 0xda, 0x6d, 0xff, 0xfd, 0x7c, 0xe2, 0x0e, 0x9a, 0x7e, 0xbc, - 0x21, 0x9d, 0x84, 0x44, 0x8d, 0x7e, 0xa6, 0x5b, 0xeb, 0xbc, 0x05, 0x00, 0x00, 0xff, 0xff, 0x92, - 0xca, 0xcf, 0xe2, 0x74, 0x02, 0x00, 0x00, + // 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, 0x00, 0x07, 0x23, 0x89, 0x07, 0x56, 0x4c, 0xfc, 0x91, 0x4d, 0x4c, 0x4d, 0x30, 0xf1, + 0x60, 0xd3, 0x4e, 0x1f, 0xdd, 0x09, 0xed, 0xcc, 0x66, 0x66, 0xda, 0xd0, 0xff, 0x80, 0xa3, 0x9e, + 0x8c, 0x37, 0xfe, 0x00, 0xff, 0x10, 0x8f, 0x1c, 0x3d, 0x19, 0x03, 0x17, 0xcf, 0x5e, 0xbc, 0x9a, + 0x9d, 0xb6, 0x6c, 0x89, 0x15, 0x08, 0xde, 0xfa, 0xde, 0xfb, 0xbc, 0xf7, 0x3e, 0x9f, 0x37, 0xaf, + 0x0f, 0xad, 0x32, 0xae, 0x41, 0xd2, 0x81, 0xcf, 0xb8, 0xa7, 0x80, 0xa6, 0x92, 0xe9, 0x9c, 0x50, + 0x9a, 0x91, 0xa1, 0x14, 0x19, 0x0b, 0x41, 0x92, 0x6c, 0x8d, 0xe8, 0x7d, 0x3c, 0x94, 0x42, 0x0b, + 0xfb, 0x4e, 0x03, 0x1a, 0x53, 0x9a, 0xe1, 0x0a, 0x8d, 0xb3, 0xb5, 0xf6, 0x5c, 0x24, 0x22, 0x61, + 0xf0, 0x64, 0xf4, 0x55, 0xa4, 0xb6, 0x97, 0xa8, 0x50, 0x89, 0x50, 0x5e, 0x11, 0x28, 0x8c, 0x2a, + 0x14, 0x09, 0x11, 0xc5, 0x40, 0x8c, 0x15, 0xa4, 0xbb, 0xc4, 0xe7, 0x79, 0x19, 0x22, 0x2c, 0xa0, + 0x24, 0x66, 0xd1, 0x40, 0xd3, 0x98, 0x01, 0xd7, 0x8a, 0x68, 0xe0, 0x21, 0xc8, 0x84, 0x71, 0x6d, + 0x98, 0x9d, 0x5a, 0x65, 0x42, 0xa7, 0x16, 0xd7, 0xf9, 0x10, 0x14, 0x81, 0x11, 0x31, 0x4e, 0xa1, + 0x00, 0x74, 0x3f, 0x5a, 0x68, 0xae, 0xaf, 0xa2, 0x2d, 0xa5, 0x58, 0xc4, 0x9f, 0x08, 0xae, 0xd2, + 0x04, 0xe4, 0x4b, 0xc8, 0xed, 0x25, 0x34, 0x55, 0x08, 0x63, 0xe1, 0xa2, 0x75, 0xcb, 0xba, 0x3f, + 0xed, 0xfe, 0x6f, 0xec, 0xe7, 0xa1, 0xfd, 0x10, 0x5d, 0xab, 0x04, 0x7a, 0x7e, 0x18, 0xca, 0xc5, + 0x89, 0x51, 0xbc, 0x67, 0xff, 0xfc, 0xd6, 0xb9, 0x9e, 0xfb, 0x49, 0xbc, 0xd9, 0x1d, 0x79, 0x41, + 0xa9, 0xae, 0x3b, 0x5b, 0x01, 0xb7, 0xc2, 0x50, 0xda, 0xb7, 0xd1, 0x2c, 0x2d, 0x5b, 0x78, 0x7b, + 0x90, 0x2f, 0x4e, 0x9a, 0xba, 0x33, 0x74, 0xdc, 0x76, 0x73, 0xea, 0xe0, 0xb0, 0xd3, 0xfa, 0x71, + 0xd8, 0x69, 0x75, 0x1d, 0xb4, 0xdc, 0x44, 0xcc, 0x05, 0x35, 0x14, 0x5c, 0x41, 0xf7, 0x93, 0x85, + 0x6e, 0xf6, 0x55, 0xf4, 0x3a, 0x0d, 0x12, 0xa6, 0x2b, 0x40, 0x9f, 0xa9, 0x00, 0x06, 0x7e, 0xc6, + 0x44, 0x2a, 0xed, 0x65, 0x34, 0xad, 0x4c, 0x54, 0x83, 0x2c, 0x35, 0x8c, 0x1d, 0xf6, 0x2b, 0x34, + 0x9b, 0xd4, 0xd0, 0x46, 0xc4, 0xcc, 0xfa, 0x2a, 0x66, 0x01, 0xc5, 0xf5, 0x11, 0xe3, 0xda, 0x50, + 0xb3, 0x35, 0x5c, 0xef, 0xe0, 0x9e, 0xa9, 0x50, 0xe3, 0xbe, 0x82, 0xee, 0x9e, 0x4b, 0xed, 0x54, + 0xc4, 0xc1, 0x44, 0x83, 0x88, 0x6d, 0x91, 0x06, 0x31, 0xec, 0x08, 0xcd, 0x78, 0x74, 0x81, 0x08, + 0x0f, 0x2d, 0x84, 0xe9, 0x30, 0x66, 0xd4, 0xd7, 0xe0, 0x65, 0x42, 0x83, 0x57, 0xbd, 0x6f, 0xa9, + 0x67, 0xa5, 0x4e, 0xdf, 0x6c, 0x00, 0xde, 0xae, 0x12, 0x76, 0x84, 0x86, 0xa7, 0x25, 0xdc, 0x9d, + 0x0f, 0x9b, 0xdc, 0xf6, 0x3b, 0xb4, 0xc0, 0xf8, 0xae, 0xf4, 0xa9, 0x66, 0x82, 0x7b, 0x41, 0x2c, + 0xe8, 0x9e, 0x37, 0x00, 0x3f, 0x04, 0x69, 0x5e, 0x6f, 0x66, 0xfd, 0xde, 0x45, 0x03, 0x7b, 0x66, + 0xd0, 0xee, 0xfc, 0xb8, 0x4c, 0x6f, 0x54, 0xa5, 0x70, 0x5f, 0x30, 0xb3, 0xfa, 0x24, 0xaa, 0x99, + 0xad, 0xff, 0x9a, 0x44, 0x93, 0x7d, 0x15, 0xd9, 0x1f, 0x2c, 0x74, 0xe3, 0xcf, 0xbd, 0x7d, 0x84, + 0x2f, 0xf1, 0x53, 0xe2, 0xa6, 0xcd, 0x6a, 0x6f, 0x5d, 0x39, 0xb5, 0xe2, 0x66, 0x7f, 0xb6, 0x50, + 0xfb, 0x9c, 0x8d, 0xec, 0x5d, 0xb6, 0xc3, 0xdf, 0x6b, 0xb4, 0x5f, 0xfc, 0x7b, 0x8d, 0x73, 0xe8, + 0x9e, 0xd9, 0xbd, 0x2b, 0xd2, 0xad, 0xd7, 0xb8, 0x2a, 0xdd, 0xa6, 0x97, 0xef, 0xbd, 0xf9, 0x72, + 0xec, 0x58, 0x47, 0xc7, 0x8e, 0xf5, 0xfd, 0xd8, 0xb1, 0xde, 0x9f, 0x38, 0xad, 0xa3, 0x13, 0xa7, + 0xf5, 0xf5, 0xc4, 0x69, 0xbd, 0x7d, 0x1c, 0x31, 0x3d, 0x48, 0x03, 0x4c, 0x45, 0x52, 0x1e, 0x53, + 0x32, 0x6e, 0xfb, 0xe0, 0xf4, 0x92, 0x67, 0x1b, 0x64, 0xff, 0xec, 0x39, 0x37, 0xbf, 0x44, 0xf0, + 0x9f, 0x39, 0x86, 0x1b, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x4c, 0x5a, 0x31, 0xaa, 0xff, 0x05, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -161,6 +339,8 @@ const _ = grpc.SupportPackageIsVersion4 // 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 { 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) } type msgClient struct { @@ -180,9 +360,29 @@ func (c *msgClient) AssignConsumerKey(ctx context.Context, in *MsgAssignConsumer return out, nil } +func (c *msgClient) SubmitConsumerMisbehaviour(ctx context.Context, in *MsgSubmitConsumerMisbehaviour, opts ...grpc.CallOption) (*MsgSubmitConsumerMisbehaviourResponse, error) { + out := new(MsgSubmitConsumerMisbehaviourResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Msg/SubmitConsumerMisbehaviour", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) SubmitConsumerDoubleVoting(ctx context.Context, in *MsgSubmitConsumerDoubleVoting, opts ...grpc.CallOption) (*MsgSubmitConsumerDoubleVotingResponse, error) { + out := new(MsgSubmitConsumerDoubleVotingResponse) + err := c.cc.Invoke(ctx, "/interchain_security.ccv.provider.v1.Msg/SubmitConsumerDoubleVoting", 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) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -192,6 +392,12 @@ type UnimplementedMsgServer struct { func (*UnimplementedMsgServer) AssignConsumerKey(ctx context.Context, req *MsgAssignConsumerKey) (*MsgAssignConsumerKeyResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method AssignConsumerKey not implemented") } +func (*UnimplementedMsgServer) SubmitConsumerMisbehaviour(ctx context.Context, req *MsgSubmitConsumerMisbehaviour) (*MsgSubmitConsumerMisbehaviourResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SubmitConsumerMisbehaviour not implemented") +} +func (*UnimplementedMsgServer) SubmitConsumerDoubleVoting(ctx context.Context, req *MsgSubmitConsumerDoubleVoting) (*MsgSubmitConsumerDoubleVotingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SubmitConsumerDoubleVoting not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -215,6 +421,42 @@ func _Msg_AssignConsumerKey_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } +func _Msg_SubmitConsumerMisbehaviour_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSubmitConsumerMisbehaviour) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).SubmitConsumerMisbehaviour(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Msg/SubmitConsumerMisbehaviour", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).SubmitConsumerMisbehaviour(ctx, req.(*MsgSubmitConsumerMisbehaviour)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_SubmitConsumerDoubleVoting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSubmitConsumerDoubleVoting) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).SubmitConsumerDoubleVoting(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/interchain_security.ccv.provider.v1.Msg/SubmitConsumerDoubleVoting", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).SubmitConsumerDoubleVoting(ctx, req.(*MsgSubmitConsumerDoubleVoting)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "interchain_security.ccv.provider.v1.Msg", HandlerType: (*MsgServer)(nil), @@ -223,6 +465,14 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "AssignConsumerKey", Handler: _Msg_AssignConsumerKey_Handler, }, + { + MethodName: "SubmitConsumerMisbehaviour", + Handler: _Msg_SubmitConsumerMisbehaviour_Handler, + }, + { + MethodName: "SubmitConsumerDoubleVoting", + Handler: _Msg_SubmitConsumerDoubleVoting_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "interchain_security/ccv/provider/v1/tx.proto", @@ -295,6 +545,148 @@ func (m *MsgAssignConsumerKeyResponse) MarshalToSizedBuffer(dAtA []byte) (int, e return len(dAtA) - i, nil } +func (m *MsgSubmitConsumerMisbehaviour) 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 *MsgSubmitConsumerMisbehaviour) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSubmitConsumerMisbehaviour) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Misbehaviour != nil { + { + size, err := m.Misbehaviour.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Submitter) > 0 { + i -= len(m.Submitter) + copy(dAtA[i:], m.Submitter) + i = encodeVarintTx(dAtA, i, uint64(len(m.Submitter))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgSubmitConsumerMisbehaviourResponse) 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 *MsgSubmitConsumerMisbehaviourResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSubmitConsumerMisbehaviourResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgSubmitConsumerDoubleVoting) 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 *MsgSubmitConsumerDoubleVoting) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSubmitConsumerDoubleVoting) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.InfractionBlockHeader != nil { + { + size, err := m.InfractionBlockHeader.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.DuplicateVoteEvidence != nil { + { + size, err := m.DuplicateVoteEvidence.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Submitter) > 0 { + i -= len(m.Submitter) + copy(dAtA[i:], m.Submitter) + i = encodeVarintTx(dAtA, i, uint64(len(m.Submitter))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgSubmitConsumerDoubleVotingResponse) 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 *MsgSubmitConsumerDoubleVotingResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSubmitConsumerDoubleVotingResponse) 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 @@ -336,17 +728,73 @@ func (m *MsgAssignConsumerKeyResponse) Size() (n int) { 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 *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 *MsgAssignConsumerKey) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx + +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 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 { @@ -538,6 +986,378 @@ func (m *MsgAssignConsumerKeyResponse) Unmarshal(dAtA []byte) error { } 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 skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/ccv/types/codec.go b/x/ccv/types/codec.go index d2815ae9b7..3db65608b2 100644 --- a/x/ccv/types/codec.go +++ b/x/ccv/types/codec.go @@ -5,31 +5,12 @@ import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" ) -// 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) { -} - -// RegisterInterfaces register the ibc transfer module interfaces to protobuf -// Any. -func RegisterInterfaces(registry codectypes.InterfaceRegistry) { -} - -var ( - amino = codec.NewLegacyAmino() - - // ModuleCdc references the global x/ibc-transfer module codec. Note, the codec - // should ONLY be used in certain instances of tests and for JSON encoding. - // - // The actual codec used for serialization should be provided to x/ibc transfer and - // defined at the application level. - ModuleCdc = codec.NewProtoCodec(codectypes.NewInterfaceRegistry()) - - // AminoCdc is a amino codec created to support amino json compatible msgs. - AminoCdc = codec.NewAminoCodec(amino) -) +// ModuleCdc references the global x/ibc-transfer module codec. Note, the codec +// should ONLY be used in certain instances of tests and for JSON encoding. +// +// The actual codec used for serialization should be provided to x/ibc transfer and +// defined at the application level. +var ModuleCdc = codec.NewProtoCodec(codectypes.NewInterfaceRegistry()) func init() { - RegisterLegacyAminoCodec(amino) - amino.Seal() } diff --git a/x/ccv/types/errors.go b/x/ccv/types/errors.go index 79c0e1e31c..e492984e48 100644 --- a/x/ccv/types/errors.go +++ b/x/ccv/types/errors.go @@ -6,23 +6,20 @@ import ( // CCV sentinel errors var ( - ErrInvalidPacketData = errorsmod.Register(ModuleName, 2, "invalid CCV packet data") - ErrInvalidPacketTimeout = errorsmod.Register(ModuleName, 3, "invalid packet timeout") - ErrInvalidVersion = errorsmod.Register(ModuleName, 4, "invalid CCV version") - ErrInvalidChannelFlow = errorsmod.Register(ModuleName, 5, "invalid message sent to channel end") - ErrInvalidConsumerChain = errorsmod.Register(ModuleName, 6, "invalid consumer chain") - ErrInvalidProviderChain = errorsmod.Register(ModuleName, 7, "invalid provider chain") - ErrInvalidStatus = errorsmod.Register(ModuleName, 8, "invalid channel status") - ErrInvalidGenesis = errorsmod.Register(ModuleName, 9, "invalid genesis state") - ErrDuplicateChannel = errorsmod.Register(ModuleName, 10, "CCV channel already exists") - ErrInvalidVSCMaturedId = errorsmod.Register(ModuleName, 11, "invalid vscId for VSC packet") - ErrInvalidVSCMaturedTime = errorsmod.Register(ModuleName, 12, "invalid maturity time for VSC packet") - ErrInvalidConsumerState = errorsmod.Register(ModuleName, 13, "provider chain has invalid state for consumer chain") - ErrInvalidConsumerClient = errorsmod.Register(ModuleName, 14, "ccv channel is not built on correct client") - ErrInvalidProposal = errorsmod.Register(ModuleName, 15, "invalid proposal") - ErrInvalidHandshakeMetadata = errorsmod.Register(ModuleName, 16, "invalid provider handshake metadata") - ErrChannelNotFound = errorsmod.Register(ModuleName, 17, "channel not found") - ErrClientNotFound = errorsmod.Register(ModuleName, 18, "client not found") - ErrDuplicateConsumerChain = errorsmod.Register(ModuleName, 19, "consumer chain already exists") - ErrConsumerChainNotFound = errorsmod.Register(ModuleName, 20, "consumer chain not found") + ErrInvalidPacketData = errorsmod.Register(ModuleName, 1, "invalid CCV packet data") + ErrInvalidVersion = errorsmod.Register(ModuleName, 2, "invalid CCV version") + ErrInvalidChannelFlow = errorsmod.Register(ModuleName, 3, "invalid message sent to channel end") + ErrInvalidGenesis = errorsmod.Register(ModuleName, 4, "invalid genesis state") + ErrDuplicateChannel = errorsmod.Register(ModuleName, 5, "CCV channel already exists") + ErrInvalidVSCMaturedId = errorsmod.Register(ModuleName, 6, "invalid vscId for VSC packet") + ErrInvalidVSCMaturedTime = errorsmod.Register(ModuleName, 7, "invalid maturity time for VSC packet") + ErrInvalidHandshakeMetadata = errorsmod.Register(ModuleName, 8, "invalid provider handshake metadata") + ErrChannelNotFound = errorsmod.Register(ModuleName, 9, "channel not found") + ErrClientNotFound = errorsmod.Register(ModuleName, 10, "client not found") + ErrInvalidConsumerState = errorsmod.Register(ModuleName, 11, "provider chain has invalid state for consumer chain") + ErrInvalidConsumerClient = errorsmod.Register(ModuleName, 12, "ccv channel is not built on correct client") + ErrInvalidProposal = errorsmod.Register(ModuleName, 13, "invalid proposal") + ErrDuplicateConsumerChain = errorsmod.Register(ModuleName, 14, "consumer chain already exists") + ErrConsumerChainNotFound = errorsmod.Register(ModuleName, 15, "consumer chain not found") + ErrInvalidDoubleVotingEvidence = errorsmod.Register(ModuleName, 16, "invalid consumer double voting evidence") ) diff --git a/x/ccv/types/events.go b/x/ccv/types/events.go index 82462f6530..4c597ded56 100644 --- a/x/ccv/types/events.go +++ b/x/ccv/types/events.go @@ -2,31 +2,26 @@ package types // CCV events const ( - EventTypeTimeout = "timeout" - EventTypePacket = "ccv_packet" - EventTypeChannelEstablished = "channel_established" - EventTypeFeeTransferChannelOpened = "fee_transfer_channel_opened" - EventTypeConsumerClientCreated = "consumer_client_created" - EventTypeAssignConsumerKey = "assign_consumer_key" - EventTypeAddConsumerRewardDenom = "add_consumer_reward_denom" - EventTypeRemoveConsumerRewardDenom = "remove_consumer_reward_denom" + EventTypeTimeout = "timeout" + EventTypePacket = "ccv_packet" + EventTypeChannelEstablished = "channel_established" + EventTypeFeeTransferChannelOpened = "fee_transfer_channel_opened" + EventTypeConsumerClientCreated = "consumer_client_created" + EventTypeAssignConsumerKey = "assign_consumer_key" + EventTypeAddConsumerRewardDenom = "add_consumer_reward_denom" + EventTypeRemoveConsumerRewardDenom = "remove_consumer_reward_denom" + EventTypeSubmitConsumerMisbehaviour = "submit_consumer_misbehaviour" + EventTypeSubmitConsumerDoubleVoting = "submit_consumer_double_voting" + EventTypeExecuteConsumerChainSlash = "execute_consumer_chain_slash" + EventTypeFeeDistribution = "fee_distribution" + EventTypeConsumerSlashRequest = "consumer_slash_request" + EventTypeVSCMatured = "vsc_matured" - EventTypeExecuteConsumerChainSlash = "execute_consumer_chain_slash" - EventTypeFeeDistribution = "fee_distribution" - EventTypeConsumerSlashRequest = "consumer_slash_request" - EventTypeVSCMatured = "vsc_matured" - - AttributeKeyAckSuccess = "success" - AttributeKeyAck = "acknowledgement" - AttributeKeyAckError = "error" - - AttributeChainID = "chain_id" - AttributeValidatorAddress = "validator_address" - AttributeValidatorConsumerAddress = "validator_consumer_address" - AttributeInfractionType = "infraction_type" + AttributeKeyAckSuccess = "success" + AttributeKeyAck = "acknowledgement" + AttributeKeyAckError = "error" AttributeInfractionHeight = "infraction_height" AttributeConsumerHeight = "consumer_height" - AttributeValSetUpdateID = "valset_update_id" AttributeTimestamp = "timestamp" AttributeInitialHeight = "initial_height" AttributeInitializationTimeout = "initialization_timeout" @@ -34,13 +29,14 @@ const ( AttributeUnbondingPeriod = "unbonding_period" AttributeProviderValidatorAddress = "provider_validator_address" AttributeConsumerConsensusPubKey = "consumer_consensus_pub_key" - - AttributeDistributionCurrentHeight = "current_distribution_height" - //#nosec G101 -- (false positive) this is not a hardcoded credential - AttributeDistributionNextHeight = "next_distribution_height" - AttributeDistributionFraction = "distribution_fraction" - AttributeDistributionTotal = "total" - AttributeDistributionToProvider = "provider_amount" - - AttributeConsumerRewardDenom = "consumer_reward_denom" + AttributeSubmitterAddress = "submitter_address" + AttributeConsumerMisbehaviour = "consumer_misbehaviour" + AttributeMisbehaviourClientId = "misbehaviour_client_id" + AttributeMisbehaviourHeight1 = "misbehaviour_height_1" + AttributeMisbehaviourHeight2 = "misbehaviour_height_2" + AttributeConsumerDoubleVoting = "consumer_double_voting" + AttributeChainID = "chain_id" + AttributeValidatorAddress = "validator_address" + AttributeInfractionType = "infraction_type" + AttributeValSetUpdateID = "valset_update_id" ) diff --git a/x/ccv/types/expected_keepers.go b/x/ccv/types/expected_keepers.go index 2f203a47ea..10546dff21 100644 --- a/x/ccv/types/expected_keepers.go +++ b/x/ccv/types/expected_keepers.go @@ -15,7 +15,7 @@ import ( 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" - evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/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" @@ -31,10 +31,11 @@ type StakingKeeper interface { 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) - // slash the validator and delegators of the validator, specifying offence height, offence power, and slash fraction 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)) @@ -48,12 +49,10 @@ type StakingKeeper interface { MaxValidators(ctx sdk.Context) uint32 GetLastTotalPower(ctx sdk.Context) math.Int GetLastValidators(ctx sdk.Context) (validators []stakingtypes.Validator) - GetUnbondingType(ctx sdk.Context, id uint64) (unbondingType stakingtypes.UnbondingType, found bool) BondDenom(ctx sdk.Context) (res string) -} - -type EvidenceKeeper interface { - HandleEquivocationEvidence(ctx sdk.Context, evidence *evidencetypes.Equivocation) + 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) } // SlashingKeeper defines the contract expected to perform ccv slashing @@ -101,6 +100,9 @@ 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 + 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 @@ -145,3 +147,7 @@ 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 5aae1ed9b5..4189c2ec51 100644 --- a/x/ccv/types/genesis.go +++ b/x/ccv/types/genesis.go @@ -13,36 +13,13 @@ func NewInitialConsumerGenesisState(cs *ibctmtypes.ClientState, consState *ibctm initValSet []abci.ValidatorUpdate, params ConsumerParams, ) *ConsumerGenesisState { return &ConsumerGenesisState{ - Params: params, - NewChain: true, - ProviderClientState: cs, - ProviderConsensusState: consState, - InitialValSet: initValSet, - } -} - -// NewRestartConsumerGenesisState returns a ConsumerGenesisState that has already been established. -func NewRestartConsumerGenesisState( - clientID, channelID string, - maturingPackets []MaturingVSCPacket, - initValSet []abci.ValidatorUpdate, - heightToValsetUpdateIDs []HeightToValsetUpdateID, - pendingConsumerPackets ConsumerPacketDataList, - outstandingDowntimes []OutstandingDowntime, - lastTransBlockHeight LastTransmissionBlockHeight, - params ConsumerParams, -) *ConsumerGenesisState { - return &ConsumerGenesisState{ - Params: params, - ProviderClientId: clientID, - ProviderChannelId: channelID, - MaturingPackets: maturingPackets, - NewChain: false, - InitialValSet: initValSet, - HeightToValsetUpdateId: heightToValsetUpdateIDs, - PendingConsumerPackets: pendingConsumerPackets, - OutstandingDowntimeSlashing: outstandingDowntimes, - LastTransmissionBlockHeight: lastTransBlockHeight, + NewChain: true, + Params: params, + Provider: ProviderInfo{ + ClientState: cs, + ConsensusState: consState, + InitialValSet: initValSet, + }, } } @@ -54,28 +31,11 @@ func DefaultConsumerGenesisState() *ConsumerGenesisState { } } -// Validate performs basic genesis state validation returning an error upon any failure. -// -// The three cases where a consumer chain starts/restarts -// expect the following optional and mandatory genesis states: -// -// 1. New chain starts: -// - Params, InitialValset, provider client state, provider consensus state // mandatory -// -// 2. Chain restarts with CCV handshake still in progress: -// - Params, InitialValset, ProviderID, HeightToValidatorSetUpdateID // mandatory -// - PendingConsumerPacket // optional -// -// 3. Chain restarts with CCV handshake completed: -// - Params, InitialValset, ProviderID, channelID, HeightToValidatorSetUpdateID // mandatory -// - MaturingVSCPackets, OutstandingDowntime, PendingConsumerPacket, LastTransmissionBlockHeight // optional -// - func (gs ConsumerGenesisState) Validate() error { if !gs.Params.Enabled { return nil } - if len(gs.InitialValSet) == 0 { + if len(gs.Provider.InitialValSet) == 0 { return errorsmod.Wrap(ErrInvalidGenesis, "initial validator set is empty") } if err := gs.Params.Validate(); err != nil { @@ -83,85 +43,20 @@ func (gs ConsumerGenesisState) Validate() error { } if gs.NewChain { - if gs.ProviderClientState == nil { + if gs.Provider.ClientState == nil { return errorsmod.Wrap(ErrInvalidGenesis, "provider client state cannot be nil for new chain") } - if err := gs.ProviderClientState.Validate(); err != nil { + if err := gs.Provider.ClientState.Validate(); err != nil { return errorsmod.Wrapf(ErrInvalidGenesis, "provider client state invalid for new chain %s", err.Error()) } - if gs.ProviderConsensusState == nil { + if gs.Provider.ConsensusState == nil { return errorsmod.Wrap(ErrInvalidGenesis, "provider consensus state cannot be nil for new chain") } - if err := gs.ProviderConsensusState.ValidateBasic(); err != nil { + if err := gs.Provider.ConsensusState.ValidateBasic(); err != nil { return errorsmod.Wrapf(ErrInvalidGenesis, "provider consensus state invalid for new chain %s", err.Error()) } - if gs.ProviderClientId != "" { - return errorsmod.Wrap(ErrInvalidGenesis, "provider client id cannot be set for new chain. It must be established on handshake") - } - if gs.ProviderChannelId != "" { - return errorsmod.Wrap(ErrInvalidGenesis, "provider channel id cannot be set for new chain. It must be established on handshake") - } - if len(gs.MaturingPackets) != 0 { - return errorsmod.Wrap(ErrInvalidGenesis, "maturing packets must be empty for new chain") - } - if len(gs.PendingConsumerPackets.List) != 0 { - return errorsmod.Wrap(ErrInvalidGenesis, "pending consumer packets must be empty for new chain") - } - if gs.LastTransmissionBlockHeight.Height != 0 { - return errorsmod.Wrap(ErrInvalidGenesis, "last transmission block height must be empty for new chain") - } - } else { - // NOTE: For restart genesis, we will verify initial validator set in InitGenesis. - if gs.ProviderClientId == "" { - return errorsmod.Wrap(ErrInvalidGenesis, "provider client id must be set for a restarting consumer genesis state") - } - // handshake is still in progress - handshakeInProgress := gs.ProviderChannelId == "" - if handshakeInProgress { - if len(gs.MaturingPackets) != 0 { - return errorsmod.Wrap( - ErrInvalidGenesis, "maturing packets must be empty when handshake isn't completed") - } - if len(gs.OutstandingDowntimeSlashing) != 0 { - return errorsmod.Wrap( - ErrInvalidGenesis, "outstanding downtime must be empty when handshake isn't completed") - } - if gs.LastTransmissionBlockHeight.Height != 0 { - return errorsmod.Wrap( - ErrInvalidGenesis, "last transmission block height must be zero when handshake isn't completed") - } - if len(gs.PendingConsumerPackets.List) != 0 { - for _, packet := range gs.PendingConsumerPackets.List { - if packet.Type == VscMaturedPacket { - return errorsmod.Wrap(ErrInvalidGenesis, "pending maturing packets must be empty when handshake isn't completed") - } - } - } - } - if gs.HeightToValsetUpdateId == nil { - return errorsmod.Wrap( - ErrInvalidGenesis, - "empty height to validator set update id mapping", - ) - } - if gs.ProviderClientState != nil || gs.ProviderConsensusState != nil { - return errorsmod.Wrap(ErrInvalidGenesis, "provider client state and consensus state must be nil for a restarting genesis state") - } - for _, mat := range gs.MaturingPackets { - if err := mat.Validate(); err != nil { - return errorsmod.Wrap(err, "invalid unbonding sequences") - } - } - } - return nil -} - -func (mat MaturingVSCPacket) Validate() error { - if mat.MaturityTime.IsZero() { - return errorsmod.Wrap(ErrInvalidVSCMaturedTime, "cannot have 0 maturity time") - } - if mat.VscId == 0 { - return errorsmod.Wrap(ErrInvalidVSCMaturedId, "cannot have 0 maturity time") + } else if gs.Provider.ClientState != nil || gs.Provider.ConsensusState != nil { + return errorsmod.Wrap(ErrInvalidGenesis, "provider client state and consensus state must be nil for a restarting genesis state") } return nil } diff --git a/x/ccv/types/params.go b/x/ccv/types/params.go index 1e2d6d180a..c80e353d66 100644 --- a/x/ccv/types/params.go +++ b/x/ccv/types/params.go @@ -39,6 +39,9 @@ const ( // 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 ) // Reflection based keys for params subspace @@ -54,6 +57,7 @@ var ( KeySoftOptOutThreshold = []byte("SoftOptOutThreshold") KeyRewardDenoms = []byte("RewardDenoms") KeyProviderRewardDenoms = []byte("ProviderRewardDenoms") + KeyRetryDelayPeriod = []byte("RetryDelayPeriod") ) // ParamKeyTable type declaration for parameters @@ -66,7 +70,8 @@ func NewParams(enabled bool, blocksPerDistributionTransmission int64, distributionTransmissionChannel, providerFeePoolAddrStr string, ccvTimeoutPeriod, transferTimeoutPeriod time.Duration, consumerRedistributionFraction string, historicalEntries int64, - consumerUnbondingPeriod time.Duration, softOptOutThreshold string, rewardDenoms, providerRewardDenoms []string, + consumerUnbondingPeriod time.Duration, softOptOutThreshold string, + rewardDenoms, providerRewardDenoms []string, retryDelayPeriod time.Duration, ) ConsumerParams { return ConsumerParams{ Enabled: enabled, @@ -81,6 +86,7 @@ func NewParams(enabled bool, blocksPerDistributionTransmission int64, SoftOptOutThreshold: softOptOutThreshold, RewardDenoms: rewardDenoms, ProviderRewardDenoms: providerRewardDenoms, + RetryDelayPeriod: retryDelayPeriod, } } @@ -101,6 +107,7 @@ func DefaultParams() ConsumerParams { DefaultSoftOptOutThreshold, rewardDenoms, provideRewardDenoms, + DefaultRetryDelayPeriod, ) } @@ -142,6 +149,9 @@ func (p ConsumerParams) Validate() error { if err := ValidateDenoms(p.ProviderRewardDenoms); err != nil { return err } + if err := ValidateDuration(p.RetryDelayPeriod); err != nil { + return err + } return nil } @@ -171,6 +181,8 @@ func (p *ConsumerParams) ParamSetPairs() paramtypes.ParamSetPairs { p.RewardDenoms, ValidateDenoms), paramtypes.NewParamSetPair(KeyProviderRewardDenoms, p.ProviderRewardDenoms, ValidateDenoms), + paramtypes.NewParamSetPair(KeyRetryDelayPeriod, + p.RetryDelayPeriod, ValidateDuration), } } diff --git a/x/ccv/types/shared_consumer.pb.go b/x/ccv/types/shared_consumer.pb.go index d52508dc6b..699f9ac52d 100644 --- a/x/ccv/types/shared_consumer.pb.go +++ b/x/ccv/types/shared_consumer.pb.go @@ -9,10 +9,8 @@ import ( _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" - _ "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" _07_tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint" _ "google.golang.org/protobuf/types/known/durationpb" - _ "google.golang.org/protobuf/types/known/timestamppb" io "io" math "math" math_bits "math/bits" @@ -34,7 +32,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // ConsumerParams defines the parameters for CCV consumer module. // // Note this type is referenced in both the consumer and provider CCV modules, -// and persisted on the provider, see MakeConsumerGenesis and SetConsumerGenesis. +// and persisted on the provider, see MakeConsumerGenesis and +// SetConsumerGenesis. type ConsumerParams struct { // TODO: Remove enabled flag and find a better way to setup integration tests // See: https://github.com/cosmos/interchain-security/issues/339 @@ -77,6 +76,8 @@ type ConsumerParams struct { // Provider-originated reward denoms. These are denoms coming from the // provider which are allowed to be used as rewards. e.g. "uatom" ProviderRewardDenoms []string `protobuf:"bytes,12,rep,name=provider_reward_denoms,json=providerRewardDenoms,proto3" json:"provider_reward_denoms,omitempty"` + // The period after which a consumer can retry sending a throttled packet. + RetryDelayPeriod time.Duration `protobuf:"bytes,13,opt,name=retry_delay_period,json=retryDelayPeriod,proto3,stdduration" json:"retry_delay_period"` } func (m *ConsumerParams) Reset() { *m = ConsumerParams{} } @@ -196,32 +197,20 @@ func (m *ConsumerParams) GetProviderRewardDenoms() []string { return nil } -// ConsumerGenesisState defines the CCV consumer chain genesis state. -// -// Note this type is referenced in both the consumer and provider CCV modules, -// and persisted on the provider, see MakeConsumerGenesis and SetConsumerGenesis. +func (m *ConsumerParams) GetRetryDelayPeriod() time.Duration { + if m != nil { + return m.RetryDelayPeriod + } + return 0 +} + +// ConsumerGenesisState defines shared genesis information between provider and +// consumer type ConsumerGenesisState struct { - Params ConsumerParams `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` - ProviderClientId string `protobuf:"bytes,2,opt,name=provider_client_id,json=providerClientId,proto3" json:"provider_client_id,omitempty"` - ProviderChannelId string `protobuf:"bytes,3,opt,name=provider_channel_id,json=providerChannelId,proto3" json:"provider_channel_id,omitempty"` - NewChain bool `protobuf:"varint,4,opt,name=new_chain,json=newChain,proto3" json:"new_chain,omitempty"` - // ProviderClientState filled in on new chain, nil on restart. - ProviderClientState *_07_tendermint.ClientState `protobuf:"bytes,5,opt,name=provider_client_state,json=providerClientState,proto3" json:"provider_client_state,omitempty"` - // ProviderConsensusState filled in on new chain, nil on restart. - ProviderConsensusState *_07_tendermint.ConsensusState `protobuf:"bytes,6,opt,name=provider_consensus_state,json=providerConsensusState,proto3" json:"provider_consensus_state,omitempty"` - // MaturingPackets nil on new chain, filled in on restart. - MaturingPackets []MaturingVSCPacket `protobuf:"bytes,7,rep,name=maturing_packets,json=maturingPackets,proto3" json:"maturing_packets"` - // InitialValset filled in on new chain and on restart. - InitialValSet []types.ValidatorUpdate `protobuf:"bytes,8,rep,name=initial_val_set,json=initialValSet,proto3" json:"initial_val_set"` - // HeightToValsetUpdateId nil on new chain, filled in on restart. - HeightToValsetUpdateId []HeightToValsetUpdateID `protobuf:"bytes,9,rep,name=height_to_valset_update_id,json=heightToValsetUpdateId,proto3" json:"height_to_valset_update_id"` - // OutstandingDowntimes nil on new chain, filled in on restart. - OutstandingDowntimeSlashing []OutstandingDowntime `protobuf:"bytes,10,rep,name=outstanding_downtime_slashing,json=outstandingDowntimeSlashing,proto3" json:"outstanding_downtime_slashing"` - // PendingConsumerPackets nil on new chain, filled in on restart. - PendingConsumerPackets ConsumerPacketDataList `protobuf:"bytes,11,opt,name=pending_consumer_packets,json=pendingConsumerPackets,proto3" json:"pending_consumer_packets"` - // LastTransmissionBlockHeight nil on new chain, filled in on restart. - LastTransmissionBlockHeight LastTransmissionBlockHeight `protobuf:"bytes,12,opt,name=last_transmission_block_height,json=lastTransmissionBlockHeight,proto3" json:"last_transmission_block_height"` - PreCCV bool `protobuf:"varint,13,opt,name=preCCV,proto3" json:"preCCV,omitempty"` + Params ConsumerParams `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + Provider ProviderInfo `protobuf:"bytes,2,opt,name=provider,proto3" json:"provider"` + // true for new chain, false for chain restart. + NewChain bool `protobuf:"varint,3,opt,name=new_chain,json=newChain,proto3" json:"new_chain,omitempty"` } func (m *ConsumerGenesisState) Reset() { *m = ConsumerGenesisState{} } @@ -264,18 +253,11 @@ func (m *ConsumerGenesisState) GetParams() ConsumerParams { return ConsumerParams{} } -func (m *ConsumerGenesisState) GetProviderClientId() string { - if m != nil { - return m.ProviderClientId - } - return "" -} - -func (m *ConsumerGenesisState) GetProviderChannelId() string { +func (m *ConsumerGenesisState) GetProvider() ProviderInfo { if m != nil { - return m.ProviderChannelId + return m.Provider } - return "" + return ProviderInfo{} } func (m *ConsumerGenesisState) GetNewChain() bool { @@ -285,238 +267,29 @@ func (m *ConsumerGenesisState) GetNewChain() bool { return false } -func (m *ConsumerGenesisState) GetProviderClientState() *_07_tendermint.ClientState { - if m != nil { - return m.ProviderClientState - } - return nil -} - -func (m *ConsumerGenesisState) GetProviderConsensusState() *_07_tendermint.ConsensusState { - if m != nil { - return m.ProviderConsensusState - } - return nil -} - -func (m *ConsumerGenesisState) GetMaturingPackets() []MaturingVSCPacket { - if m != nil { - return m.MaturingPackets - } - return nil -} - -func (m *ConsumerGenesisState) GetInitialValSet() []types.ValidatorUpdate { - if m != nil { - return m.InitialValSet - } - return nil -} - -func (m *ConsumerGenesisState) GetHeightToValsetUpdateId() []HeightToValsetUpdateID { - if m != nil { - return m.HeightToValsetUpdateId - } - return nil -} - -func (m *ConsumerGenesisState) GetOutstandingDowntimeSlashing() []OutstandingDowntime { - if m != nil { - return m.OutstandingDowntimeSlashing - } - return nil -} - -func (m *ConsumerGenesisState) GetPendingConsumerPackets() ConsumerPacketDataList { - if m != nil { - return m.PendingConsumerPackets - } - return ConsumerPacketDataList{} -} - -func (m *ConsumerGenesisState) GetLastTransmissionBlockHeight() LastTransmissionBlockHeight { - if m != nil { - return m.LastTransmissionBlockHeight - } - return LastTransmissionBlockHeight{} -} - -func (m *ConsumerGenesisState) GetPreCCV() bool { - if m != nil { - return m.PreCCV - } - return false -} - -// HeightValsetUpdateID represents a mapping internal to the consumer CCV module -// AND used in shared consumer genesis state, which links a block height to each recv valset update id. -type HeightToValsetUpdateID struct { - Height uint64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` - ValsetUpdateId uint64 `protobuf:"varint,2,opt,name=valset_update_id,json=valsetUpdateId,proto3" json:"valset_update_id,omitempty"` +// ProviderInfo defines all information a consumer needs from a provider +// Shared data type between provider and consumer +type ProviderInfo struct { + // ProviderClientState filled in on new chain, nil on restart. + ClientState *_07_tendermint.ClientState `protobuf:"bytes,1,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty"` + // ProviderConsensusState filled in on new chain, nil on restart. + ConsensusState *_07_tendermint.ConsensusState `protobuf:"bytes,2,opt,name=consensus_state,json=consensusState,proto3" json:"consensus_state,omitempty"` + // InitialValset filled in on new chain and on restart. + InitialValSet []types.ValidatorUpdate `protobuf:"bytes,3,rep,name=initial_val_set,json=initialValSet,proto3" json:"initial_val_set"` } -func (m *HeightToValsetUpdateID) Reset() { *m = HeightToValsetUpdateID{} } -func (m *HeightToValsetUpdateID) String() string { return proto.CompactTextString(m) } -func (*HeightToValsetUpdateID) ProtoMessage() {} -func (*HeightToValsetUpdateID) Descriptor() ([]byte, []int) { +func (m *ProviderInfo) Reset() { *m = ProviderInfo{} } +func (m *ProviderInfo) String() string { return proto.CompactTextString(m) } +func (*ProviderInfo) ProtoMessage() {} +func (*ProviderInfo) Descriptor() ([]byte, []int) { return fileDescriptor_d0a8be0efc64dfbc, []int{2} } -func (m *HeightToValsetUpdateID) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *HeightToValsetUpdateID) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_HeightToValsetUpdateID.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 *HeightToValsetUpdateID) XXX_Merge(src proto.Message) { - xxx_messageInfo_HeightToValsetUpdateID.Merge(m, src) -} -func (m *HeightToValsetUpdateID) XXX_Size() int { - return m.Size() -} -func (m *HeightToValsetUpdateID) XXX_DiscardUnknown() { - xxx_messageInfo_HeightToValsetUpdateID.DiscardUnknown(m) -} - -var xxx_messageInfo_HeightToValsetUpdateID proto.InternalMessageInfo - -func (m *HeightToValsetUpdateID) GetHeight() uint64 { - if m != nil { - return m.Height - } - return 0 -} - -func (m *HeightToValsetUpdateID) GetValsetUpdateId() uint64 { - if m != nil { - return m.ValsetUpdateId - } - return 0 -} - -// OutstandingDowntime defines the type used internally to the consumer CCV module, -// AND used in shared consumer genesis state, in order to not send multiple slashing -// requests for the same downtime infraction. -type OutstandingDowntime struct { - ValidatorConsensusAddress string `protobuf:"bytes,1,opt,name=validator_consensus_address,json=validatorConsensusAddress,proto3" json:"validator_consensus_address,omitempty"` -} - -func (m *OutstandingDowntime) Reset() { *m = OutstandingDowntime{} } -func (m *OutstandingDowntime) String() string { return proto.CompactTextString(m) } -func (*OutstandingDowntime) ProtoMessage() {} -func (*OutstandingDowntime) Descriptor() ([]byte, []int) { - return fileDescriptor_d0a8be0efc64dfbc, []int{3} -} -func (m *OutstandingDowntime) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *OutstandingDowntime) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_OutstandingDowntime.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 *OutstandingDowntime) XXX_Merge(src proto.Message) { - xxx_messageInfo_OutstandingDowntime.Merge(m, src) -} -func (m *OutstandingDowntime) XXX_Size() int { - return m.Size() -} -func (m *OutstandingDowntime) XXX_DiscardUnknown() { - xxx_messageInfo_OutstandingDowntime.DiscardUnknown(m) -} - -var xxx_messageInfo_OutstandingDowntime proto.InternalMessageInfo - -func (m *OutstandingDowntime) GetValidatorConsensusAddress() string { - if m != nil { - return m.ValidatorConsensusAddress - } - return "" -} - -// LastTransmissionBlockHeight is the last time validator holding -// pools were transmitted to the provider chain. This type is used internally -// to the consumer CCV module AND used in shared consumer genesis state. -type LastTransmissionBlockHeight struct { - Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` -} - -func (m *LastTransmissionBlockHeight) Reset() { *m = LastTransmissionBlockHeight{} } -func (m *LastTransmissionBlockHeight) String() string { return proto.CompactTextString(m) } -func (*LastTransmissionBlockHeight) ProtoMessage() {} -func (*LastTransmissionBlockHeight) Descriptor() ([]byte, []int) { - return fileDescriptor_d0a8be0efc64dfbc, []int{4} -} -func (m *LastTransmissionBlockHeight) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *LastTransmissionBlockHeight) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_LastTransmissionBlockHeight.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 *LastTransmissionBlockHeight) XXX_Merge(src proto.Message) { - xxx_messageInfo_LastTransmissionBlockHeight.Merge(m, src) -} -func (m *LastTransmissionBlockHeight) XXX_Size() int { - return m.Size() -} -func (m *LastTransmissionBlockHeight) XXX_DiscardUnknown() { - xxx_messageInfo_LastTransmissionBlockHeight.DiscardUnknown(m) -} - -var xxx_messageInfo_LastTransmissionBlockHeight proto.InternalMessageInfo - -func (m *LastTransmissionBlockHeight) GetHeight() int64 { - if m != nil { - return m.Height - } - return 0 -} - -// MaturingVSCPacket represents a vsc packet that is maturing internal to the -// consumer CCV module, where the consumer has not yet relayed a VSCMatured packet -// back to the provider. This type is used internally to the consumer CCV module -// AND used in shared consumer genesis state. -type MaturingVSCPacket struct { - VscId uint64 `protobuf:"varint,1,opt,name=vscId,proto3" json:"vscId,omitempty"` - MaturityTime time.Time `protobuf:"bytes,2,opt,name=maturity_time,json=maturityTime,proto3,stdtime" json:"maturity_time"` -} - -func (m *MaturingVSCPacket) Reset() { *m = MaturingVSCPacket{} } -func (m *MaturingVSCPacket) String() string { return proto.CompactTextString(m) } -func (*MaturingVSCPacket) ProtoMessage() {} -func (*MaturingVSCPacket) Descriptor() ([]byte, []int) { - return fileDescriptor_d0a8be0efc64dfbc, []int{5} -} -func (m *MaturingVSCPacket) XXX_Unmarshal(b []byte) error { +func (m *ProviderInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *MaturingVSCPacket) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *ProviderInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_MaturingVSCPacket.Marshal(b, m, deterministic) + return xxx_messageInfo_ProviderInfo.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -526,78 +299,35 @@ func (m *MaturingVSCPacket) XXX_Marshal(b []byte, deterministic bool) ([]byte, e return b[:n], nil } } -func (m *MaturingVSCPacket) XXX_Merge(src proto.Message) { - xxx_messageInfo_MaturingVSCPacket.Merge(m, src) +func (m *ProviderInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProviderInfo.Merge(m, src) } -func (m *MaturingVSCPacket) XXX_Size() int { +func (m *ProviderInfo) XXX_Size() int { return m.Size() } -func (m *MaturingVSCPacket) XXX_DiscardUnknown() { - xxx_messageInfo_MaturingVSCPacket.DiscardUnknown(m) +func (m *ProviderInfo) XXX_DiscardUnknown() { + xxx_messageInfo_ProviderInfo.DiscardUnknown(m) } -var xxx_messageInfo_MaturingVSCPacket proto.InternalMessageInfo +var xxx_messageInfo_ProviderInfo proto.InternalMessageInfo -func (m *MaturingVSCPacket) GetVscId() uint64 { +func (m *ProviderInfo) GetClientState() *_07_tendermint.ClientState { if m != nil { - return m.VscId + return m.ClientState } - return 0 + return nil } -func (m *MaturingVSCPacket) GetMaturityTime() time.Time { +func (m *ProviderInfo) GetConsensusState() *_07_tendermint.ConsensusState { if m != nil { - return m.MaturityTime - } - return time.Time{} -} - -// ConsumerPacketDataList is a list of consumer packet data packets. -// -// Note this type is is used internally to the consumer CCV module -// for exporting / importing state in InitGenesis and ExportGenesis, -// AND included in the consumer genesis type (reffed by provider and consumer modules), -// hence this is a shared type. -type ConsumerPacketDataList struct { - List []ConsumerPacketData `protobuf:"bytes,1,rep,name=list,proto3" json:"list"` -} - -func (m *ConsumerPacketDataList) Reset() { *m = ConsumerPacketDataList{} } -func (m *ConsumerPacketDataList) String() string { return proto.CompactTextString(m) } -func (*ConsumerPacketDataList) ProtoMessage() {} -func (*ConsumerPacketDataList) Descriptor() ([]byte, []int) { - return fileDescriptor_d0a8be0efc64dfbc, []int{6} -} -func (m *ConsumerPacketDataList) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ConsumerPacketDataList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ConsumerPacketDataList.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 m.ConsensusState } -} -func (m *ConsumerPacketDataList) XXX_Merge(src proto.Message) { - xxx_messageInfo_ConsumerPacketDataList.Merge(m, src) -} -func (m *ConsumerPacketDataList) XXX_Size() int { - return m.Size() -} -func (m *ConsumerPacketDataList) XXX_DiscardUnknown() { - xxx_messageInfo_ConsumerPacketDataList.DiscardUnknown(m) + return nil } -var xxx_messageInfo_ConsumerPacketDataList proto.InternalMessageInfo - -func (m *ConsumerPacketDataList) GetList() []ConsumerPacketData { +func (m *ProviderInfo) GetInitialValSet() []types.ValidatorUpdate { if m != nil { - return m.List + return m.InitialValSet } return nil } @@ -605,11 +335,7 @@ func (m *ConsumerPacketDataList) GetList() []ConsumerPacketData { func init() { proto.RegisterType((*ConsumerParams)(nil), "interchain_security.ccv.v1.ConsumerParams") proto.RegisterType((*ConsumerGenesisState)(nil), "interchain_security.ccv.v1.ConsumerGenesisState") - proto.RegisterType((*HeightToValsetUpdateID)(nil), "interchain_security.ccv.v1.HeightToValsetUpdateID") - proto.RegisterType((*OutstandingDowntime)(nil), "interchain_security.ccv.v1.OutstandingDowntime") - proto.RegisterType((*LastTransmissionBlockHeight)(nil), "interchain_security.ccv.v1.LastTransmissionBlockHeight") - proto.RegisterType((*MaturingVSCPacket)(nil), "interchain_security.ccv.v1.MaturingVSCPacket") - proto.RegisterType((*ConsumerPacketDataList)(nil), "interchain_security.ccv.v1.ConsumerPacketDataList") + proto.RegisterType((*ProviderInfo)(nil), "interchain_security.ccv.v1.ProviderInfo") } func init() { @@ -617,81 +343,58 @@ func init() { } var fileDescriptor_d0a8be0efc64dfbc = []byte{ - // 1182 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0x4f, 0x53, 0x1b, 0x37, - 0x14, 0xc7, 0x81, 0x10, 0x5b, 0x40, 0x42, 0x04, 0x71, 0x37, 0x30, 0x35, 0x8e, 0xdb, 0xce, 0x78, - 0xda, 0x66, 0xb7, 0x21, 0xe9, 0x74, 0xa6, 0x87, 0xce, 0x04, 0xd3, 0x14, 0x3a, 0x69, 0xa0, 0x0b, - 0xe1, 0x90, 0xce, 0x54, 0x23, 0x4b, 0xc2, 0xd6, 0x64, 0x2d, 0x79, 0x24, 0xed, 0x52, 0xae, 0x3d, - 0xf7, 0x90, 0x63, 0x3f, 0x52, 0x8e, 0x39, 0xe6, 0xd4, 0x76, 0x92, 0x2f, 0xd2, 0xd1, 0x9f, 0x35, - 0x76, 0x00, 0x97, 0xde, 0x56, 0x7a, 0xbf, 0xdf, 0xfb, 0xff, 0xf4, 0x16, 0x7c, 0xc5, 0x85, 0x61, - 0x8a, 0xf4, 0x31, 0x17, 0x48, 0x33, 0x92, 0x2b, 0x6e, 0x4e, 0x13, 0x42, 0x8a, 0xa4, 0x78, 0x90, - 0xe8, 0x3e, 0x56, 0x8c, 0x22, 0x22, 0x85, 0xce, 0x07, 0x4c, 0xc5, 0x43, 0x25, 0x8d, 0x84, 0x6b, - 0x17, 0x30, 0x62, 0x42, 0x8a, 0xb8, 0x78, 0xb0, 0xb6, 0x6e, 0x98, 0xa0, 0x4c, 0x0d, 0xb8, 0x30, - 0x09, 0xee, 0x12, 0x9e, 0x98, 0xd3, 0x21, 0xd3, 0x9e, 0xb8, 0x96, 0xf0, 0x2e, 0x49, 0x32, 0xde, - 0xeb, 0x1b, 0x92, 0x71, 0x26, 0x8c, 0x4e, 0xc6, 0xd0, 0xc5, 0x83, 0xb1, 0x53, 0x20, 0xdc, 0xb3, - 0x04, 0x22, 0x15, 0x4b, 0x48, 0x1f, 0x0b, 0xc1, 0x32, 0x8b, 0x0a, 0x9f, 0x01, 0xd2, 0xe8, 0x49, - 0xd9, 0xcb, 0x58, 0xe2, 0x4e, 0xdd, 0xfc, 0x38, 0xa1, 0xb9, 0xc2, 0x86, 0x4b, 0x11, 0xe4, 0xab, - 0x3d, 0xd9, 0x93, 0xee, 0x33, 0xb1, 0x5f, 0xe1, 0xf6, 0xb3, 0x29, 0x41, 0x9f, 0x70, 0xc5, 0x02, - 0x6c, 0xe3, 0x43, 0xe5, 0x86, 0x0f, 0x98, 0x36, 0x78, 0x30, 0xf4, 0x80, 0xd6, 0x1f, 0xf3, 0xe0, - 0x66, 0x27, 0x64, 0x67, 0x1f, 0x2b, 0x3c, 0xd0, 0x30, 0x02, 0x37, 0x98, 0xc0, 0xdd, 0x8c, 0xd1, - 0xa8, 0xd2, 0xac, 0xb4, 0xab, 0x69, 0x79, 0x84, 0x7b, 0xe0, 0xd3, 0x6e, 0x26, 0xc9, 0x4b, 0x8d, - 0x86, 0x4c, 0x21, 0xca, 0xb5, 0x51, 0xbc, 0x9b, 0x5b, 0x5f, 0x91, 0x51, 0x58, 0xe8, 0x01, 0xd7, - 0x9a, 0x4b, 0x11, 0x5d, 0x6b, 0x56, 0xda, 0xb3, 0xe9, 0x3d, 0x8f, 0xdd, 0x67, 0x6a, 0x7b, 0x0c, - 0x79, 0x38, 0x06, 0x84, 0x3f, 0x82, 0x7b, 0x97, 0x6a, 0x41, 0x21, 0x4d, 0xd1, 0x6c, 0xb3, 0xd2, - 0xae, 0xa5, 0x1b, 0xf4, 0x12, 0x25, 0x1d, 0x0f, 0x83, 0xdf, 0x82, 0xb5, 0xa1, 0x92, 0x05, 0xa7, - 0x4c, 0xa1, 0x63, 0xc6, 0xd0, 0x50, 0xca, 0x0c, 0x61, 0x4a, 0x15, 0xd2, 0x46, 0x45, 0x73, 0x4e, - 0x49, 0xbd, 0x44, 0x3c, 0x61, 0x6c, 0x5f, 0xca, 0xec, 0x31, 0xa5, 0xea, 0xc0, 0x28, 0xf8, 0x33, - 0x80, 0x84, 0x14, 0xc8, 0x26, 0x47, 0xe6, 0xc6, 0x46, 0xc7, 0x25, 0x8d, 0xae, 0x37, 0x2b, 0xed, - 0x85, 0xcd, 0xbb, 0xb1, 0xcf, 0x61, 0x5c, 0xe6, 0x30, 0xde, 0x0e, 0x05, 0xda, 0xaa, 0xbe, 0xfe, - 0x6b, 0x63, 0xe6, 0xcf, 0xbf, 0x37, 0x2a, 0xe9, 0x32, 0x21, 0xc5, 0xa1, 0x67, 0xef, 0x3b, 0x32, - 0xfc, 0x05, 0x7c, 0xe4, 0xa2, 0x39, 0x66, 0xea, 0x43, 0xbd, 0xf3, 0x57, 0xd7, 0x7b, 0xa7, 0xd4, - 0x31, 0xa9, 0x7c, 0x07, 0x34, 0xcb, 0x96, 0x46, 0x8a, 0x4d, 0xa4, 0xf0, 0x58, 0x61, 0x62, 0x3f, - 0xa2, 0x1b, 0x2e, 0xe2, 0x46, 0x89, 0x4b, 0x27, 0x60, 0x4f, 0x02, 0x0a, 0xde, 0x07, 0xb0, 0xcf, - 0xb5, 0x91, 0x8a, 0x13, 0x9c, 0x21, 0x26, 0x8c, 0xe2, 0x4c, 0x47, 0x55, 0x57, 0xc0, 0xdb, 0x67, - 0x92, 0xef, 0xbd, 0x00, 0x3e, 0x03, 0xcb, 0xb9, 0xe8, 0x4a, 0x41, 0xb9, 0xe8, 0x95, 0xe1, 0xd4, - 0xae, 0x1e, 0xce, 0xad, 0x11, 0x39, 0x04, 0xf2, 0x10, 0xd4, 0xb5, 0x3c, 0x36, 0x48, 0x0e, 0x0d, - 0xb2, 0x19, 0x32, 0x7d, 0xc5, 0x74, 0x5f, 0x66, 0x34, 0x02, 0xce, 0xfd, 0x15, 0x2b, 0xdd, 0x1b, - 0x9a, 0xbd, 0xdc, 0x1c, 0x96, 0x22, 0xf8, 0x09, 0x58, 0x52, 0xec, 0x04, 0x2b, 0x8a, 0x28, 0x13, - 0x72, 0xa0, 0xa3, 0x85, 0xe6, 0x6c, 0xbb, 0x96, 0x2e, 0xfa, 0xcb, 0x6d, 0x77, 0x07, 0x1f, 0x81, - 0x51, 0xb1, 0xd1, 0x24, 0x7a, 0xd1, 0xa1, 0x57, 0x4b, 0x69, 0x3a, 0xc6, 0x6a, 0xbd, 0xad, 0x82, - 0xd5, 0x72, 0x1c, 0x7e, 0x60, 0x82, 0x69, 0xae, 0x0f, 0x0c, 0x36, 0x0c, 0xee, 0x80, 0xf9, 0xa1, - 0x1b, 0x0f, 0x37, 0x13, 0x0b, 0x9b, 0x9f, 0xc7, 0x97, 0xbf, 0x21, 0xf1, 0xe4, 0x40, 0x6d, 0xcd, - 0xd9, 0xf8, 0xd3, 0xc0, 0x87, 0x5f, 0x02, 0x38, 0x72, 0xcc, 0xbf, 0x22, 0x88, 0x53, 0x37, 0x32, - 0xb5, 0x74, 0xb9, 0x94, 0x74, 0x9c, 0x60, 0x97, 0xc2, 0x18, 0xac, 0x9c, 0xa1, 0x7d, 0xa7, 0x5b, - 0xb8, 0x9f, 0x89, 0xdb, 0x23, 0xb8, 0x97, 0xec, 0x52, 0xb8, 0x0e, 0x6a, 0x82, 0x9d, 0x20, 0xe7, - 0x97, 0x6b, 0xfa, 0x6a, 0x5a, 0x15, 0xec, 0xa4, 0x63, 0xcf, 0x10, 0x81, 0x3b, 0x1f, 0x9a, 0xd6, - 0x36, 0xba, 0xd0, 0xe9, 0x5f, 0xc4, 0xbc, 0x4b, 0xe2, 0xf1, 0xe7, 0x2d, 0x1e, 0x7b, 0xd0, 0x6c, - 0x5c, 0xee, 0xd6, 0x25, 0x24, 0x5d, 0x99, 0x74, 0xd5, 0x67, 0xa9, 0x0f, 0xa2, 0x33, 0x03, 0x52, - 0x68, 0x26, 0x74, 0xae, 0x83, 0x0d, 0xdf, 0xf5, 0xf1, 0x7f, 0xda, 0x28, 0x69, 0xde, 0xcc, 0xa8, - 0x88, 0x93, 0xf7, 0xf0, 0x57, 0xb0, 0x3c, 0xc0, 0x26, 0x57, 0xae, 0x0f, 0x31, 0x79, 0xc9, 0x8c, - 0x8e, 0x6e, 0x34, 0x67, 0xdb, 0x0b, 0x9b, 0xf7, 0xa7, 0x55, 0xe6, 0xa7, 0xc0, 0x39, 0x3a, 0xe8, - 0xec, 0x3b, 0x56, 0x28, 0xce, 0xad, 0x52, 0x99, 0xbf, 0xb5, 0x8d, 0x7e, 0x8b, 0x0b, 0x6e, 0x38, - 0xce, 0x50, 0x81, 0x33, 0xa4, 0x99, 0x89, 0xaa, 0x4e, 0x7d, 0x73, 0xdc, 0x5f, 0xbb, 0x20, 0xe2, - 0x23, 0x9c, 0x71, 0x8a, 0x8d, 0x54, 0xcf, 0x87, 0x14, 0x1b, 0x16, 0x34, 0x2e, 0x05, 0xfa, 0x11, - 0xce, 0x0e, 0x98, 0x81, 0x06, 0xac, 0xf5, 0x99, 0x8d, 0x1a, 0x19, 0x69, 0x35, 0x6a, 0x66, 0x50, - 0xee, 0xf0, 0xb6, 0x9c, 0x35, 0xa7, 0x7a, 0x73, 0x9a, 0xe7, 0x3b, 0x8e, 0x7d, 0x28, 0x8f, 0x1c, - 0xd7, 0x9b, 0xda, 0xdd, 0x0e, 0xc6, 0xea, 0xfd, 0x8b, 0xa4, 0x14, 0x9e, 0x82, 0x8f, 0x65, 0x6e, - 0xb4, 0xc1, 0x7e, 0x60, 0xa9, 0x3c, 0x11, 0xf6, 0x2d, 0x42, 0x3a, 0xc3, 0xba, 0xcf, 0x45, 0x2f, - 0x02, 0xce, 0x70, 0x32, 0xcd, 0xf0, 0xde, 0x99, 0x82, 0xed, 0xc0, 0x0f, 0x56, 0xd7, 0xe5, 0x79, - 0xd1, 0x41, 0xd0, 0x0c, 0x15, 0x88, 0x86, 0xcc, 0x9b, 0x1d, 0x3d, 0x55, 0x65, 0xa1, 0x16, 0x5c, - 0x2b, 0x6c, 0x5e, 0x6d, 0x84, 0x2c, 0x65, 0x1b, 0x1b, 0xfc, 0x94, 0xeb, 0xb2, 0x5a, 0xf5, 0xa0, - 0x79, 0x12, 0xa4, 0xe1, 0xef, 0x15, 0xd0, 0xc8, 0xb0, 0x36, 0x93, 0x7b, 0xc4, 0xad, 0x21, 0xe4, - 0x33, 0x14, 0x2d, 0x3a, 0xd3, 0xdf, 0x4c, 0x33, 0xfd, 0x14, 0x6b, 0x33, 0xbe, 0x60, 0xb6, 0x2c, - 0xdf, 0xa7, 0xbf, 0x0c, 0x3c, 0xbb, 0x1c, 0x02, 0xeb, 0x60, 0x7e, 0xa8, 0x58, 0xa7, 0x73, 0x14, - 0x2d, 0xb9, 0xf1, 0x0b, 0xa7, 0xd6, 0x0b, 0x50, 0xbf, 0xb8, 0x86, 0x96, 0x11, 0xbc, 0xb3, 0x6f, - 0xcb, 0x5c, 0x1a, 0x4e, 0xb0, 0x0d, 0x96, 0xcf, 0x75, 0xca, 0x35, 0x87, 0xb8, 0x59, 0x4c, 0xd4, - 0xb9, 0xf5, 0x1c, 0xac, 0x5c, 0x50, 0x26, 0xf8, 0x1d, 0x58, 0x2f, 0xca, 0xe6, 0x1c, 0x9b, 0x47, - 0xbb, 0x14, 0x99, 0xf6, 0x2f, 0x59, 0x2d, 0xbd, 0x3b, 0x82, 0x8c, 0x46, 0xec, 0xb1, 0x07, 0xb4, - 0xbe, 0x06, 0xeb, 0x4f, 0xa7, 0x47, 0x3a, 0xe6, 0xf7, 0x6c, 0xe9, 0x77, 0xcb, 0x80, 0xdb, 0xe7, - 0xe6, 0x0c, 0xae, 0x82, 0xeb, 0x85, 0x26, 0xbb, 0x34, 0xc4, 0xe8, 0x0f, 0x70, 0x17, 0x2c, 0xf9, - 0xc9, 0x33, 0xa7, 0x6e, 0x4b, 0xba, 0xf8, 0x16, 0x36, 0xd7, 0xce, 0x2d, 0x93, 0xc3, 0xf2, 0xbf, - 0xc5, 0x6f, 0x93, 0x57, 0x76, 0x9b, 0x2c, 0x96, 0x54, 0x2b, 0x6c, 0x75, 0x41, 0xfd, 0xe2, 0xa6, - 0x81, 0x3b, 0x60, 0x2e, 0xe3, 0xda, 0x7a, 0x39, 0xeb, 0x5f, 0xa0, 0xff, 0xd3, 0x76, 0xa1, 0xe4, - 0x4e, 0xc3, 0xd6, 0xb3, 0xd7, 0xef, 0x1a, 0x95, 0x37, 0xef, 0x1a, 0x95, 0x7f, 0xde, 0x35, 0x2a, - 0xaf, 0xde, 0x37, 0x66, 0xde, 0xbc, 0x6f, 0xcc, 0xbc, 0x7d, 0xdf, 0x98, 0x79, 0xf1, 0xa8, 0xc7, - 0x4d, 0x3f, 0xef, 0xc6, 0x44, 0x0e, 0x12, 0x22, 0xf5, 0x40, 0xea, 0xe4, 0xcc, 0xcc, 0xfd, 0xd1, - 0x1f, 0x5a, 0xf1, 0x30, 0xf9, 0xcd, 0xfd, 0xa6, 0xb9, 0xbf, 0xca, 0xee, 0xbc, 0x8b, 0xef, 0xe1, - 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe0, 0xb5, 0xe5, 0x15, 0xc3, 0x0a, 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, 0xe9, 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, 0xec, + 0xa1, 0x87, 0x46, 0xcd, 0x2c, 0x51, 0x85, 0x25, 0x75, 0x85, 0x6c, 0xaa, 0xc1, 0xa4, 0x2a, 0xe3, + 0x3e, 0x72, 0xbf, 0xff, 0x41, 0x9d, 0x3d, 0x2e, 0xec, 0x71, 0x69, 0x4f, 0xbb, 0x14, 0xfe, 0x04, + 0xad, 0x69, 0x38, 0xa3, 0x9a, 0x13, 0x0e, 0x52, 0xe5, 0xc6, 0x1f, 0x05, 0x83, 0xc9, 0x4a, 0xbc, + 0xda, 0x6c, 0x1e, 0xba, 0x3d, 0xfc, 0x14, 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, 0x3c, 0x9d, 0x0b, 0x9b, + 0x96, 0x49, 0xc8, 0x54, 0x1e, 0x31, 0x65, 0x72, 0x65, 0xa2, 0xeb, 0xb3, 0x78, 0x72, 0xf5, 0x6a, + 0x54, 0x7b, 0xd1, 0xcf, 0xee, 0xe9, 0x70, 0x43, 0x3f, 0x59, 0x76, 0x97, 0x6a, 0xef, 0xef, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x5c, 0xb4, 0xca, 0xd3, 0x62, 0x06, 0x00, 0x00, } func (m *ConsumerParams) Marshal() (dAtA []byte, err error) { @@ -714,6 +417,14 @@ func (m *ConsumerParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + n1, err1 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.RetryDelayPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.RetryDelayPeriod):]) + if err1 != nil { + return 0, err1 + } + i -= n1 + i = encodeVarintSharedConsumer(dAtA, i, uint64(n1)) + i-- + dAtA[i] = 0x6a if len(m.ProviderRewardDenoms) > 0 { for iNdEx := len(m.ProviderRewardDenoms) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.ProviderRewardDenoms[iNdEx]) @@ -739,12 +450,12 @@ func (m *ConsumerParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x52 } - n1, err1 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingPeriod):]) - if err1 != nil { - return 0, err1 + n2, err2 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.UnbondingPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.UnbondingPeriod):]) + if err2 != nil { + return 0, err2 } - i -= n1 - i = encodeVarintSharedConsumer(dAtA, i, uint64(n1)) + i -= n2 + i = encodeVarintSharedConsumer(dAtA, i, uint64(n2)) i-- dAtA[i] = 0x4a if m.HistoricalEntries != 0 { @@ -759,21 +470,21 @@ func (m *ConsumerParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x3a } - n2, err2 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.TransferTimeoutPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.TransferTimeoutPeriod):]) - if err2 != nil { - return 0, err2 - } - i -= n2 - i = encodeVarintSharedConsumer(dAtA, i, uint64(n2)) - i-- - dAtA[i] = 0x32 - n3, err3 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.CcvTimeoutPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.CcvTimeoutPeriod):]) + n3, err3 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.TransferTimeoutPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.TransferTimeoutPeriod):]) if err3 != nil { return 0, err3 } i -= n3 i = encodeVarintSharedConsumer(dAtA, i, uint64(n3)) i-- + dAtA[i] = 0x32 + n4, err4 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.CcvTimeoutPeriod, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.CcvTimeoutPeriod):]) + if err4 != nil { + return 0, err4 + } + i -= n4 + i = encodeVarintSharedConsumer(dAtA, i, uint64(n4)) + i-- dAtA[i] = 0x2a if len(m.ProviderFeePoolAddrStr) > 0 { i -= len(m.ProviderFeePoolAddrStr) @@ -827,18 +538,18 @@ func (m *ConsumerGenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.PreCCV { + if m.NewChain { i-- - if m.PreCCV { + if m.NewChain { dAtA[i] = 1 } else { dAtA[i] = 0 } i-- - dAtA[i] = 0x68 + dAtA[i] = 0x18 } { - size, err := m.LastTransmissionBlockHeight.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Provider.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -846,9 +557,9 @@ func (m *ConsumerGenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintSharedConsumer(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x62 + dAtA[i] = 0x12 { - size, err := m.PendingConsumerPackets.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -856,35 +567,30 @@ func (m *ConsumerGenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintSharedConsumer(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x5a - if len(m.OutstandingDowntimeSlashing) > 0 { - for iNdEx := len(m.OutstandingDowntimeSlashing) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.OutstandingDowntimeSlashing[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSharedConsumer(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x52 - } - } - if len(m.HeightToValsetUpdateId) > 0 { - for iNdEx := len(m.HeightToValsetUpdateId) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.HeightToValsetUpdateId[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSharedConsumer(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x4a - } + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ProviderInfo) 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 *ProviderInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ProviderInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l if len(m.InitialValSet) > 0 { for iNdEx := len(m.InitialValSet) - 1; iNdEx >= 0; iNdEx-- { { @@ -896,26 +602,12 @@ func (m *ConsumerGenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintSharedConsumer(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x42 - } - } - if len(m.MaturingPackets) > 0 { - for iNdEx := len(m.MaturingPackets) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.MaturingPackets[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSharedConsumer(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x3a + dAtA[i] = 0x1a } } - if m.ProviderConsensusState != nil { + if m.ConsensusState != nil { { - size, err := m.ProviderConsensusState.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ConsensusState.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -923,11 +615,11 @@ func (m *ConsumerGenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintSharedConsumer(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x32 + dAtA[i] = 0x12 } - if m.ProviderClientState != nil { + if m.ClientState != nil { { - size, err := m.ProviderClientState.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ClientState.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -935,205 +627,7 @@ func (m *ConsumerGenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintSharedConsumer(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a - } - if m.NewChain { - i-- - if m.NewChain { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x20 - } - if len(m.ProviderChannelId) > 0 { - i -= len(m.ProviderChannelId) - copy(dAtA[i:], m.ProviderChannelId) - i = encodeVarintSharedConsumer(dAtA, i, uint64(len(m.ProviderChannelId))) - i-- - dAtA[i] = 0x1a - } - if len(m.ProviderClientId) > 0 { - i -= len(m.ProviderClientId) - copy(dAtA[i:], m.ProviderClientId) - i = encodeVarintSharedConsumer(dAtA, i, uint64(len(m.ProviderClientId))) - i-- - dAtA[i] = 0x12 - } - { - size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSharedConsumer(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} - -func (m *HeightToValsetUpdateID) 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 *HeightToValsetUpdateID) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *HeightToValsetUpdateID) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.ValsetUpdateId != 0 { - i = encodeVarintSharedConsumer(dAtA, i, uint64(m.ValsetUpdateId)) - i-- - dAtA[i] = 0x10 - } - if m.Height != 0 { - i = encodeVarintSharedConsumer(dAtA, i, uint64(m.Height)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *OutstandingDowntime) 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 *OutstandingDowntime) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *OutstandingDowntime) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.ValidatorConsensusAddress) > 0 { - i -= len(m.ValidatorConsensusAddress) - copy(dAtA[i:], m.ValidatorConsensusAddress) - i = encodeVarintSharedConsumer(dAtA, i, uint64(len(m.ValidatorConsensusAddress))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *LastTransmissionBlockHeight) 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 *LastTransmissionBlockHeight) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *LastTransmissionBlockHeight) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Height != 0 { - i = encodeVarintSharedConsumer(dAtA, i, uint64(m.Height)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *MaturingVSCPacket) 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 *MaturingVSCPacket) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *MaturingVSCPacket) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - n9, err9 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.MaturityTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.MaturityTime):]) - if err9 != nil { - return 0, err9 - } - i -= n9 - i = encodeVarintSharedConsumer(dAtA, i, uint64(n9)) - i-- - dAtA[i] = 0x12 - if m.VscId != 0 { - i = encodeVarintSharedConsumer(dAtA, i, uint64(m.VscId)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *ConsumerPacketDataList) 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 *ConsumerPacketDataList) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ConsumerPacketDataList) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.List) > 0 { - for iNdEx := len(m.List) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.List[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSharedConsumer(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } + dAtA[i] = 0xa } return len(dAtA) - i, nil } @@ -1198,6 +692,8 @@ func (m *ConsumerParams) Size() (n int) { n += 1 + l + sovSharedConsumer(uint64(l)) } } + l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.RetryDelayPeriod) + n += 1 + l + sovSharedConsumer(uint64(l)) return n } @@ -1209,121 +705,30 @@ func (m *ConsumerGenesisState) Size() (n int) { _ = l l = m.Params.Size() n += 1 + l + sovSharedConsumer(uint64(l)) - l = len(m.ProviderClientId) - if l > 0 { - n += 1 + l + sovSharedConsumer(uint64(l)) - } - l = len(m.ProviderChannelId) - if l > 0 { - n += 1 + l + sovSharedConsumer(uint64(l)) - } - if m.NewChain { - n += 2 - } - if m.ProviderClientState != nil { - l = m.ProviderClientState.Size() - n += 1 + l + sovSharedConsumer(uint64(l)) - } - if m.ProviderConsensusState != nil { - l = m.ProviderConsensusState.Size() - n += 1 + l + sovSharedConsumer(uint64(l)) - } - if len(m.MaturingPackets) > 0 { - for _, e := range m.MaturingPackets { - l = e.Size() - n += 1 + l + sovSharedConsumer(uint64(l)) - } - } - if len(m.InitialValSet) > 0 { - for _, e := range m.InitialValSet { - l = e.Size() - n += 1 + l + sovSharedConsumer(uint64(l)) - } - } - if len(m.HeightToValsetUpdateId) > 0 { - for _, e := range m.HeightToValsetUpdateId { - l = e.Size() - n += 1 + l + sovSharedConsumer(uint64(l)) - } - } - if len(m.OutstandingDowntimeSlashing) > 0 { - for _, e := range m.OutstandingDowntimeSlashing { - l = e.Size() - n += 1 + l + sovSharedConsumer(uint64(l)) - } - } - l = m.PendingConsumerPackets.Size() - n += 1 + l + sovSharedConsumer(uint64(l)) - l = m.LastTransmissionBlockHeight.Size() + l = m.Provider.Size() n += 1 + l + sovSharedConsumer(uint64(l)) - if m.PreCCV { + if m.NewChain { n += 2 } return n } -func (m *HeightToValsetUpdateID) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Height != 0 { - n += 1 + sovSharedConsumer(uint64(m.Height)) - } - if m.ValsetUpdateId != 0 { - n += 1 + sovSharedConsumer(uint64(m.ValsetUpdateId)) - } - return n -} - -func (m *OutstandingDowntime) Size() (n int) { +func (m *ProviderInfo) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.ValidatorConsensusAddress) - if l > 0 { + if m.ClientState != nil { + l = m.ClientState.Size() n += 1 + l + sovSharedConsumer(uint64(l)) } - return n -} - -func (m *LastTransmissionBlockHeight) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Height != 0 { - n += 1 + sovSharedConsumer(uint64(m.Height)) - } - return n -} - -func (m *MaturingVSCPacket) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.VscId != 0 { - n += 1 + sovSharedConsumer(uint64(m.VscId)) - } - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.MaturityTime) - n += 1 + l + sovSharedConsumer(uint64(l)) - return n -} - -func (m *ConsumerPacketDataList) Size() (n int) { - if m == nil { - return 0 + if m.ConsensusState != nil { + l = m.ConsensusState.Size() + n += 1 + l + sovSharedConsumer(uint64(l)) } - var l int - _ = l - if len(m.List) > 0 { - for _, e := range m.List { + if len(m.InitialValSet) > 0 { + for _, e := range m.InitialValSet { l = e.Size() n += 1 + l + sovSharedConsumer(uint64(l)) } @@ -1653,414 +1058,9 @@ func (m *ConsumerParams) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 11: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RewardDenoms", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - 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 ErrInvalidLengthSharedConsumer - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSharedConsumer - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.RewardDenoms = append(m.RewardDenoms, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 12: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProviderRewardDenoms", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - 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 ErrInvalidLengthSharedConsumer - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSharedConsumer - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ProviderRewardDenoms = append(m.ProviderRewardDenoms, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSharedConsumer(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSharedConsumer - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ConsumerGenesisState) 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 ErrIntOverflowSharedConsumer - } - 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: ConsumerGenesisState: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ConsumerGenesisState: 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) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSharedConsumer - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSharedConsumer - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProviderClientId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - 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 ErrInvalidLengthSharedConsumer - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSharedConsumer - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ProviderClientId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProviderChannelId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - 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 ErrInvalidLengthSharedConsumer - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSharedConsumer - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ProviderChannelId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NewChain", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.NewChain = bool(v != 0) - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProviderClientState", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSharedConsumer - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSharedConsumer - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ProviderClientState == nil { - m.ProviderClientState = &_07_tendermint.ClientState{} - } - if err := m.ProviderClientState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ProviderConsensusState", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSharedConsumer - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSharedConsumer - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ProviderConsensusState == nil { - m.ProviderConsensusState = &_07_tendermint.ConsensusState{} - } - if err := m.ProviderConsensusState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MaturingPackets", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSharedConsumer - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSharedConsumer - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.MaturingPackets = append(m.MaturingPackets, MaturingVSCPacket{}) - if err := m.MaturingPackets[len(m.MaturingPackets)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field InitialValSet", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSharedConsumer - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSharedConsumer - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.InitialValSet = append(m.InitialValSet, types.ValidatorUpdate{}) - if err := m.InitialValSet[len(m.InitialValSet)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 9: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field HeightToValsetUpdateId", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSharedConsumer - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSharedConsumer - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.HeightToValsetUpdateId = append(m.HeightToValsetUpdateId, HeightToValsetUpdateID{}) - if err := m.HeightToValsetUpdateId[len(m.HeightToValsetUpdateId)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field OutstandingDowntimeSlashing", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RewardDenoms", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSharedConsumer @@ -2070,31 +1070,29 @@ func (m *ConsumerGenesisState) 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 ErrInvalidLengthSharedConsumer } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthSharedConsumer } if postIndex > l { return io.ErrUnexpectedEOF } - m.OutstandingDowntimeSlashing = append(m.OutstandingDowntimeSlashing, OutstandingDowntime{}) - if err := m.OutstandingDowntimeSlashing[len(m.OutstandingDowntimeSlashing)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.RewardDenoms = append(m.RewardDenoms, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 11: + case 12: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PendingConsumerPackets", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ProviderRewardDenoms", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSharedConsumer @@ -2104,28 +1102,27 @@ func (m *ConsumerGenesisState) 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 ErrInvalidLengthSharedConsumer } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthSharedConsumer } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.PendingConsumerPackets.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ProviderRewardDenoms = append(m.ProviderRewardDenoms, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 12: + case 13: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LastTransmissionBlockHeight", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RetryDelayPeriod", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -2152,30 +1149,10 @@ func (m *ConsumerGenesisState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.LastTransmissionBlockHeight.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.RetryDelayPeriod, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 13: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field PreCCV", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.PreCCV = bool(v != 0) default: iNdEx = preIndex skippy, err := skipSharedConsumer(dAtA[iNdEx:]) @@ -2197,7 +1174,7 @@ func (m *ConsumerGenesisState) Unmarshal(dAtA []byte) error { } return nil } -func (m *HeightToValsetUpdateID) Unmarshal(dAtA []byte) error { +func (m *ConsumerGenesisState) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2220,36 +1197,17 @@ func (m *HeightToValsetUpdateID) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: HeightToValsetUpdateID: wiretype end group for non-group") + return fmt.Errorf("proto: ConsumerGenesisState: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: HeightToValsetUpdateID: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ConsumerGenesisState: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) - } - m.Height = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSharedConsumer - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Height |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ValsetUpdateId", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) } - m.ValsetUpdateId = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSharedConsumer @@ -2259,66 +1217,30 @@ func (m *HeightToValsetUpdateID) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ValsetUpdateId |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - default: - iNdEx = preIndex - skippy, err := skipSharedConsumer(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { + if msglen < 0 { return ErrInvalidLengthSharedConsumer } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *OutstandingDowntime) 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 ErrIntOverflowSharedConsumer + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSharedConsumer } - if iNdEx >= l { + if postIndex > l { return io.ErrUnexpectedEOF } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: OutstandingDowntime: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: OutstandingDowntime: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + iNdEx = postIndex + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ValidatorConsensusAddress", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Provider", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSharedConsumer @@ -2328,79 +1250,30 @@ func (m *OutstandingDowntime) 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 ErrInvalidLengthSharedConsumer } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthSharedConsumer } if postIndex > l { return io.ErrUnexpectedEOF } - m.ValidatorConsensusAddress = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSharedConsumer(dAtA[iNdEx:]) - if err != nil { + if err := m.Provider.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSharedConsumer - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *LastTransmissionBlockHeight) 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 ErrIntOverflowSharedConsumer - } - 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: LastTransmissionBlockHeight: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: LastTransmissionBlockHeight: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + iNdEx = postIndex + case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field NewChain", wireType) } - m.Height = 0 + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSharedConsumer @@ -2410,11 +1283,12 @@ func (m *LastTransmissionBlockHeight) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Height |= int64(b&0x7F) << shift + v |= int(b&0x7F) << shift if b < 0x80 { break } } + m.NewChain = bool(v != 0) default: iNdEx = preIndex skippy, err := skipSharedConsumer(dAtA[iNdEx:]) @@ -2436,7 +1310,7 @@ func (m *LastTransmissionBlockHeight) Unmarshal(dAtA []byte) error { } return nil } -func (m *MaturingVSCPacket) Unmarshal(dAtA []byte) error { +func (m *ProviderInfo) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2459,17 +1333,17 @@ func (m *MaturingVSCPacket) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MaturingVSCPacket: wiretype end group for non-group") + return fmt.Errorf("proto: ProviderInfo: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MaturingVSCPacket: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ProviderInfo: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field VscId", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClientState", wireType) } - m.VscId = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSharedConsumer @@ -2479,14 +1353,31 @@ func (m *MaturingVSCPacket) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.VscId |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthSharedConsumer + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSharedConsumer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ClientState == nil { + m.ClientState = &_07_tendermint.ClientState{} + } + if err := m.ClientState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MaturityTime", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConsensusState", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -2513,63 +1404,16 @@ func (m *MaturingVSCPacket) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.MaturityTime, dAtA[iNdEx:postIndex]); err != nil { - return err + if m.ConsensusState == nil { + m.ConsensusState = &_07_tendermint.ConsensusState{} } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSharedConsumer(dAtA[iNdEx:]) - if err != nil { + if err := m.ConsensusState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSharedConsumer - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ConsumerPacketDataList) 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 ErrIntOverflowSharedConsumer - } - 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: ConsumerPacketDataList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ConsumerPacketDataList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + iNdEx = postIndex + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field List", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field InitialValSet", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -2596,8 +1440,8 @@ func (m *ConsumerPacketDataList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.List = append(m.List, ConsumerPacketData{}) - if err := m.List[len(m.List)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.InitialValSet = append(m.InitialValSet, types.ValidatorUpdate{}) + if err := m.InitialValSet[len(m.InitialValSet)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex