From 86046926502f7b0ba795bebcdd1fdc97ac776573 Mon Sep 17 00:00:00 2001 From: Marius Poke Date: Fri, 19 Jan 2024 19:02:48 +0100 Subject: [PATCH] fix!: Validation of SlashAcks fails due to marshaling to Bech32 (#1570) * add different Bech32Prefix for consumer and provider * separate app encoding and params * remove ConsumerValPubKey from ValidatorConfig * update addresses in tests * make SlashAcks consistent across chains * add comments for clarity * Regenerate traces * Fix argument order * set bech32prefix for provider to cosmos * add changelog entries * add consumer-double-downtime e2e test * update nightly-e2e workflow * fix typo * add consumer-double-downtime to testConfigs * remove changes on provider * skip invalid SlashAcks * seal the config * clear the outstanding downtime flag for new vals * add info on upgrading to v4.0.0 * fix upgrade handler * fix changeover e2e test * Update tests/e2e/config.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * Update tests/e2e/config.go Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> * add AccountPrefix to ChainConfig * fix docstrings * update AccountAddressPrefix in app.go * fix consumer-misb e2e test --------- Co-authored-by: Philip Offtermatt Co-authored-by: Simon Noetzlin Co-authored-by: Philip Offtermatt <57488781+p-offtermatt@users.noreply.github.com> --- .../bug-fixes/1570-slashack-bech32.md | 2 + .../state-breaking/1570-slashack-bech32.md | 2 + .github/workflows/manual-e2e.yml | 103 ------- .github/workflows/nightly-e2e.yml | 55 +++- UPGRADING.md | 22 +- app/consumer-democracy/app.go | 12 +- .../ante/disabled_modules_ante_test.go | 4 +- app/consumer/ante/msg_filter_ante_test.go | 4 +- app/consumer/app.go | 12 +- app/{params/proto.go => encoding/encoding.go} | 12 +- app/params/config.go | 43 ++- app/params/doc.go | 19 -- app/params/encoding.go | 16 -- app/params/params.go | 7 - app/params/weights.go | 42 --- app/provider/app.go | 10 +- app/sovereign/app.go | 12 +- cmd/interchain-security-cd/cmd/root.go | 8 +- cmd/interchain-security-cd/main.go | 3 +- cmd/interchain-security-cdd/cmd/root.go | 8 +- cmd/interchain-security-cdd/main.go | 3 +- cmd/interchain-security-pd/cmd/root.go | 8 +- cmd/interchain-security-pd/main.go | 3 +- cmd/interchain-security-sd/cmd/root.go | 8 +- cmd/interchain-security-sd/main.go | 3 +- tests/e2e/actions.go | 109 ++++++-- tests/e2e/config.go | 253 ++++++++++++------ tests/e2e/main.go | 24 +- tests/e2e/state.go | 65 +++-- tests/e2e/steps.go | 8 + tests/e2e/steps_consumer_misbehaviour.go | 6 +- tests/e2e/steps_downtime.go | 198 ++++++++++++++ tests/e2e/steps_start_chains.go | 32 +-- tests/e2e/testnet-scripts/fork-consumer.sh | 2 +- .../testnet-scripts/sovereign-genesis.json | 10 +- x/ccv/consumer/keeper/keeper.go | 8 +- x/ccv/consumer/keeper/relay.go | 15 +- x/ccv/consumer/keeper/relay_test.go | 4 +- x/ccv/consumer/keeper/validators.go | 4 + x/ccv/types/utils.go | 17 ++ x/ccv/types/wire.go | 7 - x/ccv/types/wire_test.go | 73 +---- 42 files changed, 756 insertions(+), 500 deletions(-) create mode 100644 .changelog/unreleased/bug-fixes/1570-slashack-bech32.md create mode 100644 .changelog/unreleased/state-breaking/1570-slashack-bech32.md delete mode 100644 .github/workflows/manual-e2e.yml rename app/{params/proto.go => encoding/encoding.go} (61%) delete mode 100644 app/params/doc.go delete mode 100644 app/params/encoding.go delete mode 100644 app/params/params.go delete mode 100644 app/params/weights.go diff --git a/.changelog/unreleased/bug-fixes/1570-slashack-bech32.md b/.changelog/unreleased/bug-fixes/1570-slashack-bech32.md new file mode 100644 index 0000000000..a0e9fe9262 --- /dev/null +++ b/.changelog/unreleased/bug-fixes/1570-slashack-bech32.md @@ -0,0 +1,2 @@ +- Fix the validation of VSCPackets to not fail due to marshaling to string using Bech32. + ([\#1570](https://github.com/cosmos/interchain-security/pull/1570)) \ No newline at end of file diff --git a/.changelog/unreleased/state-breaking/1570-slashack-bech32.md b/.changelog/unreleased/state-breaking/1570-slashack-bech32.md new file mode 100644 index 0000000000..a0e9fe9262 --- /dev/null +++ b/.changelog/unreleased/state-breaking/1570-slashack-bech32.md @@ -0,0 +1,2 @@ +- Fix the validation of VSCPackets to not fail due to marshaling to string using Bech32. + ([\#1570](https://github.com/cosmos/interchain-security/pull/1570)) \ No newline at end of file diff --git a/.github/workflows/manual-e2e.yml b/.github/workflows/manual-e2e.yml deleted file mode 100644 index f9ca0ca33d..0000000000 --- a/.github/workflows/manual-e2e.yml +++ /dev/null @@ -1,103 +0,0 @@ -# manually run full E2E test suite -# all tests are run sequentially -name: manual-e2e-main -on: - workflow_dispatch: - -jobs: - happy-path-test: - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - uses: actions/setup-go@v5 - with: - go-version: "1.21" - - uses: actions/checkout@v4 - - name: Checkout LFS objects - run: git lfs checkout - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: "1.21" # The Go version to download (if necessary) and use. - - name: E2E happy-path test - run: go run ./tests/e2e/... --tc happy-path - changeover-test: - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - uses: actions/setup-go@v5 - with: - go-version: "1.21" - - uses: actions/checkout@v4 - - name: Checkout LFS objects - run: git lfs checkout - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: "1.21" # The Go version to download (if necessary) and use. - - name: E2E changeover test - run: go run ./tests/e2e/... --tc changeover - democracy-reward-test: - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - uses: actions/setup-go@v5 - with: - go-version: "1.21" - - uses: actions/checkout@v4 - - name: Checkout LFS objects - run: git lfs checkout - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: "1.21" # The Go version to download (if necessary) and use. - - name: E2E democracy-reward tests - run: go run ./tests/e2e/... --tc democracy-reward - democracy-test: - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - uses: actions/setup-go@v5 - with: - go-version: "1.21" - - uses: actions/checkout@v4 - - name: Checkout LFS objects - run: git lfs checkout - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: "1.21" # The Go version to download (if necessary) and use. - - name: E2E democracy tests - run: go run ./tests/e2e/... --tc democracy - slash-throttle-test: - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - uses: actions/setup-go@v5 - with: - go-version: "1.21" - - uses: actions/checkout@v4 - - name: Checkout LFS objects - run: git lfs checkout - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: "1.21" # The Go version to download (if necessary) and use. - - name: E2E slash-throttle tests - run: go run ./tests/e2e/... --tc slash-throttle - multiconsumer-test: - runs-on: ubuntu-latest - timeout-minutes: 40 - steps: - - uses: actions/setup-go@v5 - with: - go-version: "1.21" - - uses: actions/checkout@v4 - - name: Checkout LFS objects - run: git lfs checkout - - name: Setup Go - uses: actions/setup-go@v5 - with: - go-version: "1.21" # The Go version to download (if necessary) and use. - - name: E2E multi-consumer tests - run: go run ./tests/e2e/... --tc multiconsumer diff --git a/.github/workflows/nightly-e2e.yml b/.github/workflows/nightly-e2e.yml index 2e6e60d042..043f19fc1a 100644 --- a/.github/workflows/nightly-e2e.yml +++ b/.github/workflows/nightly-e2e.yml @@ -1,9 +1,7 @@ # Run integration tests nightly on main - -# !! Relevant changes to this file should be propagated manual-integration.yml - name: nightly-e2e-main on: + workflow_dispatch: schedule: # run every day at 03:00 UTC # ┌───────────── minute (0 - 59) @@ -114,6 +112,54 @@ jobs: go-version: "1.21" # The Go version to download (if necessary) and use. - name: E2E multi-consumer tests run: go run ./tests/e2e/... --tc multiconsumer + consumer-misbehaviour-test: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/setup-go@v5 + with: + go-version: "1.21" + - uses: actions/checkout@v4 + - name: Checkout LFS objects + run: git lfs checkout + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: "1.21" # The Go version to download (if necessary) and use. + - name: E2E consumer-misbehaviour tests + run: go run ./tests/e2e/... --tc consumer-misbehaviour + consumer-double-sign-test: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/setup-go@v5 + with: + go-version: "1.21" + - uses: actions/checkout@v4 + - name: Checkout LFS objects + run: git lfs checkout + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: "1.21" # The Go version to download (if necessary) and use. + - name: E2E consumer-double-sign tests + run: go run ./tests/e2e/... --tc consumer-double-sign + consumer-double-downtime-test: + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/setup-go@v5 + with: + go-version: "1.21" + - uses: actions/checkout@v4 + - name: Checkout LFS objects + run: git lfs checkout + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: "1.21" # The Go version to download (if necessary) and use. + - name: E2E consumer-double-downtime tests + run: go run ./tests/e2e/... --tc consumer-double-downtime nightly-test-fail: needs: @@ -123,6 +169,9 @@ jobs: - democracy-test - slash-throttle-test - multiconsumer-test + - consumer-misbehaviour-test + - consumer-double-sign-test + - consumer-double-downtime-test if: ${{ failure() }} runs-on: ubuntu-latest steps: diff --git a/UPGRADING.md b/UPGRADING.md index cc7de42395..851f31fe78 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -12,9 +12,29 @@ Upgrading a provider from `v3.3.0` to `v4.0.0` will require state migrations, se ### Consumer +***Note that consumer chains can upgrade directly from `v3.1.0` to `v4.0.0`.*** + Upgrading a consumer from `v3.2.0` to `v4.0.0` will not require state migration, however, upgrading directly from `v3.1.0` to `v4.0.0` will require state migrations, see https://github.com/cosmos/interchain-security/blob/release/v4.0.x/x/ccv/consumer/keeper/migrations.go#L22. -Note that consumer chains can upgrade directly from `v3.1.0` to `v4.0.0`. +In addition, the following migration needs to be added to the upgrade handler of the consumer chain: +```golang +func migrateICSOutstandingDowntime(ctx sdk.Context, keepers *upgrades.UpgradeKeepers) error { + ctx.Logger().Info("Migrating ICS oustanding downtime...") + + downtimes := keepers.ConsumerKeeper.GetAllOutstandingDowntimes(ctx) + for _, od := range downtimes { + consAddr, err := sdk.ConsAddressFromBech32(od.ValidatorConsensusAddress) + if err != nil { + return err + } + keepers.ConsumerKeeper.DeleteOutstandingDowntime(ctx, consAddr) + } + + ctx.Logger().Info("Finished ICS oustanding downtime") + + return nil +} +``` ## [v3.3.x](https://github.com/cosmos/interchain-security/tree/release/v3.2.x) diff --git a/app/consumer-democracy/app.go b/app/consumer-democracy/app.go index e740c89406..e90d35760e 100644 --- a/app/consumer-democracy/app.go +++ b/app/consumer-democracy/app.go @@ -103,7 +103,7 @@ import ( "github.com/cometbft/cometbft/libs/log" tmos "github.com/cometbft/cometbft/libs/os" - appparams "github.com/cosmos/interchain-security/v4/app/params" + appencoding "github.com/cosmos/interchain-security/v4/app/encoding" testutil "github.com/cosmos/interchain-security/v4/testutil/integration" consumer "github.com/cosmos/interchain-security/v4/x/ccv/consumer" consumerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" @@ -116,7 +116,7 @@ import ( const ( AppName = "interchain-security-cd" upgradeName = "sovereign-changeover" // arbitrary name, define your own appropriately named upgrade - AccountAddressPrefix = "cosmos" + AccountAddressPrefix = "consumer" ) var ( @@ -1005,8 +1005,8 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino // should be used only in tests or when creating a new app instance (NewApp*()). // App user shouldn't create new codecs - use the app.AppCodec instead. // [DEPRECATED] -func MakeTestEncodingConfig() appparams.EncodingConfig { - encodingConfig := appparams.MakeTestEncodingConfig() +func MakeTestEncodingConfig() appencoding.EncodingConfig { + encodingConfig := appencoding.MakeTestEncodingConfig() std.RegisterLegacyAminoCodec(encodingConfig.Amino) std.RegisterInterfaces(encodingConfig.InterfaceRegistry) ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) @@ -1014,8 +1014,8 @@ func MakeTestEncodingConfig() appparams.EncodingConfig { return encodingConfig } -func makeEncodingConfig() appparams.EncodingConfig { - encodingConfig := appparams.MakeTestEncodingConfig() +func makeEncodingConfig() appencoding.EncodingConfig { + encodingConfig := appencoding.MakeTestEncodingConfig() std.RegisterLegacyAminoCodec(encodingConfig.Amino) std.RegisterInterfaces(encodingConfig.InterfaceRegistry) ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) diff --git a/app/consumer/ante/disabled_modules_ante_test.go b/app/consumer/ante/disabled_modules_ante_test.go index 2b12bed63a..7fa95f37c6 100644 --- a/app/consumer/ante/disabled_modules_ante_test.go +++ b/app/consumer/ante/disabled_modules_ante_test.go @@ -13,11 +13,11 @@ import ( slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" "github.com/cosmos/interchain-security/v4/app/consumer/ante" - "github.com/cosmos/interchain-security/v4/app/params" + appencoding "github.com/cosmos/interchain-security/v4/app/encoding" ) func TestDisabledModulesDecorator(t *testing.T) { - txCfg := params.MakeTestEncodingConfig().TxConfig + txCfg := appencoding.MakeTestEncodingConfig().TxConfig authzMsgExecSlashing := authz.NewMsgExec(sdk.AccAddress{}, []sdk.Msg{&slashingtypes.MsgUnjail{}}) authzMsgExecEvidence := authz.NewMsgExec(sdk.AccAddress{}, []sdk.Msg{&evidencetypes.MsgSubmitEvidence{}}) nestedAuthzMsgExecSlashing := authz.NewMsgExec(sdk.AccAddress{}, []sdk.Msg{&authzMsgExecSlashing}) diff --git a/app/consumer/ante/msg_filter_ante_test.go b/app/consumer/ante/msg_filter_ante_test.go index 47538dad1a..bfc1bb0a50 100644 --- a/app/consumer/ante/msg_filter_ante_test.go +++ b/app/consumer/ante/msg_filter_ante_test.go @@ -10,7 +10,7 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/interchain-security/v4/app/consumer/ante" - "github.com/cosmos/interchain-security/v4/app/params" + appencoding "github.com/cosmos/interchain-security/v4/app/encoding" ) type consumerKeeper struct { @@ -28,7 +28,7 @@ func noOpAnteDecorator() sdk.AnteHandler { } func TestMsgFilterDecorator(t *testing.T) { - txCfg := params.MakeTestEncodingConfig().TxConfig + txCfg := appencoding.MakeTestEncodingConfig().TxConfig testCases := []struct { name string diff --git a/app/consumer/app.go b/app/consumer/app.go index 220be5ed80..9853145117 100644 --- a/app/consumer/app.go +++ b/app/consumer/app.go @@ -87,7 +87,7 @@ import ( "github.com/cometbft/cometbft/libs/log" tmos "github.com/cometbft/cometbft/libs/os" - appparams "github.com/cosmos/interchain-security/v4/app/params" + appencoding "github.com/cosmos/interchain-security/v4/app/encoding" testutil "github.com/cosmos/interchain-security/v4/testutil/integration" ibcconsumer "github.com/cosmos/interchain-security/v4/x/ccv/consumer" ibcconsumerkeeper "github.com/cosmos/interchain-security/v4/x/ccv/consumer/keeper" @@ -97,7 +97,7 @@ import ( const ( AppName = "interchain-security-c" upgradeName = "ics-v1-to-v2" - AccountAddressPrefix = "cosmos" + AccountAddressPrefix = "consumer" ) var ( @@ -830,8 +830,8 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino // return encodingConfig // } -func MakeTestEncodingConfig() appparams.EncodingConfig { - encodingConfig := appparams.MakeTestEncodingConfig() +func MakeTestEncodingConfig() appencoding.EncodingConfig { + encodingConfig := appencoding.MakeTestEncodingConfig() std.RegisterLegacyAminoCodec(encodingConfig.Amino) std.RegisterInterfaces(encodingConfig.InterfaceRegistry) ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) @@ -839,8 +839,8 @@ func MakeTestEncodingConfig() appparams.EncodingConfig { return encodingConfig } -func makeEncodingConfig() appparams.EncodingConfig { - encodingConfig := appparams.MakeTestEncodingConfig() +func makeEncodingConfig() appencoding.EncodingConfig { + encodingConfig := appencoding.MakeTestEncodingConfig() std.RegisterLegacyAminoCodec(encodingConfig.Amino) std.RegisterInterfaces(encodingConfig.InterfaceRegistry) ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) diff --git a/app/params/proto.go b/app/encoding/encoding.go similarity index 61% rename from app/params/proto.go rename to app/encoding/encoding.go index d11fe8d06c..6897e53634 100644 --- a/app/params/proto.go +++ b/app/encoding/encoding.go @@ -1,11 +1,21 @@ -package params +package encoding import ( + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/x/auth/tx" ) +// EncodingConfig specifies the concrete encoding types to use for a given app. +// This is provided for compatibility between protobuf and amino implementations. +type EncodingConfig struct { + InterfaceRegistry types.InterfaceRegistry + Codec codec.Codec + TxConfig client.TxConfig + Amino *codec.LegacyAmino +} + // MakeTestEncodingConfig creates an EncodingConfig for an amino based test configuration. func MakeTestEncodingConfig() EncodingConfig { amino := codec.NewLegacyAmino() diff --git a/app/params/config.go b/app/params/config.go index e4f7308498..c4e3cb7e3c 100644 --- a/app/params/config.go +++ b/app/params/config.go @@ -4,32 +4,27 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -var ( - Bech32Prefix = "cosmos" - - // Bech32PrefixAccAddr defines the Bech32 prefix of an account's address - Bech32PrefixAccAddr = Bech32Prefix - // Bech32PrefixAccPub defines the Bech32 prefix of an account's public key - Bech32PrefixAccPub = Bech32Prefix + sdk.PrefixPublic - // Bech32PrefixValAddr defines the Bech32 prefix of a validator's operator address - Bech32PrefixValAddr = Bech32Prefix + sdk.PrefixValidator + sdk.PrefixOperator - // Bech32PrefixValPub defines the Bech32 prefix of a validator's operator public key - Bech32PrefixValPub = Bech32Prefix + sdk.PrefixValidator + sdk.PrefixOperator + sdk.PrefixPublic - // Bech32PrefixConsAddr defines the Bech32 prefix of a consensus node address - Bech32PrefixConsAddr = Bech32Prefix + sdk.PrefixValidator + sdk.PrefixConsensus - // Bech32PrefixConsPub defines the Bech32 prefix of a consensus node public key - Bech32PrefixConsPub = Bech32Prefix + sdk.PrefixValidator + sdk.PrefixConsensus + sdk.PrefixPublic -) - // SetAddressPrefixes builds the Config with Bech32 addressPrefix and publKeyPrefix for accounts, validators, and consensus nodes and verifies that addreeses have correct format. // Not sealed yet -func SetAddressPrefixes() { +func SetAddressPrefixes(bech32Prefix string) { cfg := sdk.GetConfig() - cfg.SetBech32PrefixForAccount(Bech32PrefixAccAddr, Bech32PrefixAccPub) - cfg.SetBech32PrefixForValidator(Bech32PrefixValAddr, Bech32PrefixValPub) - cfg.SetBech32PrefixForConsensusNode(Bech32PrefixConsAddr, Bech32PrefixConsPub) -} -func init() { - SetAddressPrefixes() + // bech32PrefixAccAddr defines the Bech32 prefix of an account's address + bech32PrefixAccAddr := bech32Prefix + // bech32PrefixAccPub defines the Bech32 prefix of an account's public key + bech32PrefixAccPub := bech32Prefix + sdk.PrefixPublic + // bech32PrefixValAddr defines the Bech32 prefix of a validator's operator address + bech32PrefixValAddr := bech32Prefix + sdk.PrefixValidator + sdk.PrefixOperator + // bech32PrefixValPub defines the Bech32 prefix of a validator's operator public key + bech32PrefixValPub := bech32Prefix + sdk.PrefixValidator + sdk.PrefixOperator + sdk.PrefixPublic + // bech32PrefixConsAddr defines the Bech32 prefix of a consensus node address + bech32PrefixConsAddr := bech32Prefix + sdk.PrefixValidator + sdk.PrefixConsensus + // bech32PrefixConsPub defines the Bech32 prefix of a consensus node public key + bech32PrefixConsPub := bech32Prefix + sdk.PrefixValidator + sdk.PrefixConsensus + sdk.PrefixPublic + + cfg.SetBech32PrefixForAccount(bech32PrefixAccAddr, bech32PrefixAccPub) + cfg.SetBech32PrefixForValidator(bech32PrefixValAddr, bech32PrefixValPub) + cfg.SetBech32PrefixForConsensusNode(bech32PrefixConsAddr, bech32PrefixConsPub) + + cfg.Seal() } diff --git a/app/params/doc.go b/app/params/doc.go deleted file mode 100644 index 49b5f6d1e7..0000000000 --- a/app/params/doc.go +++ /dev/null @@ -1,19 +0,0 @@ -/* -Package params defines the simulation parameters in the gaia. - -It contains the default weights used for each transaction used on the module's -simulation. These weights define the chance for a transaction to be simulated at -any given operation. - -You can replace the default values for the weights by providing a params.json -file with the weights defined for each of the transaction operations: - - { - "op_weight_msg_send": 60, - "op_weight_msg_delegate": 100, - } - -In the example above, the `MsgSend` has 60% chance to be simulated, while the -`MsgDelegate` will always be simulated. -*/ -package params diff --git a/app/params/encoding.go b/app/params/encoding.go deleted file mode 100644 index 8ff9ea04b3..0000000000 --- a/app/params/encoding.go +++ /dev/null @@ -1,16 +0,0 @@ -package params - -import ( - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/codec/types" -) - -// EncodingConfig specifies the concrete encoding types to use for a given app. -// This is provided for compatibility between protobuf and amino implementations. -type EncodingConfig struct { - InterfaceRegistry types.InterfaceRegistry - Codec codec.Codec - TxConfig client.TxConfig - Amino *codec.LegacyAmino -} diff --git a/app/params/params.go b/app/params/params.go deleted file mode 100644 index b6aa5fb55e..0000000000 --- a/app/params/params.go +++ /dev/null @@ -1,7 +0,0 @@ -package params - -// Simulation parameter constants -const ( - StakePerAccount = "stake_per_account" - InitiallyBondedValidators = "initially_bonded_validators" -) diff --git a/app/params/weights.go b/app/params/weights.go deleted file mode 100644 index 4e5452c9b2..0000000000 --- a/app/params/weights.go +++ /dev/null @@ -1,42 +0,0 @@ -package params - -// Default simulation operation weights for messages and gov proposals -const ( - DefaultWeightMsgSend int = 100 - DefaultWeightMsgMultiSend int = 10 - DefaultWeightMsgSetWithdrawAddress int = 50 - DefaultWeightMsgWithdrawDelegationReward int = 50 - DefaultWeightMsgWithdrawValidatorCommission int = 50 - DefaultWeightMsgFundCommunityPool int = 50 - DefaultWeightMsgDeposit int = 100 - DefaultWeightMsgVote int = 67 - DefaultWeightMsgUnjail int = 100 - DefaultWeightMsgCreateValidator int = 100 - DefaultWeightMsgEditValidator int = 5 - DefaultWeightMsgDelegate int = 100 - DefaultWeightMsgUndelegate int = 100 - DefaultWeightMsgBeginRedelegate int = 100 - - DefaultWeightCommunitySpendProposal int = 5 - DefaultWeightTextProposal int = 5 - DefaultWeightParamChangeProposal int = 5 - - DefaultWeightMsgStoreCode int = 50 - DefaultWeightMsgInstantiateContract int = 100 - DefaultWeightMsgExecuteContract int = 100 - DefaultWeightMsgUpdateAdmin int = 25 - DefaultWeightMsgClearAdmin int = 10 - DefaultWeightMsgMigrateContract int = 50 - - DefaultWeightStoreCodeProposal int = 5 - DefaultWeightInstantiateContractProposal int = 5 - DefaultWeightUpdateAdminProposal int = 5 - DefaultWeightExecuteContractProposal int = 5 - DefaultWeightClearAdminProposal int = 5 - DefaultWeightMigrateContractProposal int = 5 - DefaultWeightSudoContractProposal int = 5 - DefaultWeightPinCodesProposal int = 5 - DefaultWeightUnpinCodesProposal int = 5 - DefaultWeightUpdateInstantiateConfigProposal int = 5 - DefaultWeightStoreAndInstantiateContractProposal int = 5 -) diff --git a/app/provider/app.go b/app/provider/app.go index c1f3c4d6ff..7527756d45 100644 --- a/app/provider/app.go +++ b/app/provider/app.go @@ -100,7 +100,7 @@ import ( "github.com/cometbft/cometbft/libs/log" tmos "github.com/cometbft/cometbft/libs/os" - appparams "github.com/cosmos/interchain-security/v4/app/params" + appencoding "github.com/cosmos/interchain-security/v4/app/encoding" testutil "github.com/cosmos/interchain-security/v4/testutil/integration" ibcprovider "github.com/cosmos/interchain-security/v4/x/ccv/provider" ibcproviderclient "github.com/cosmos/interchain-security/v4/x/ccv/provider/client" @@ -930,8 +930,8 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino // return encodingConfig // } -func MakeTestEncodingConfig() appparams.EncodingConfig { - encodingConfig := appparams.MakeTestEncodingConfig() +func MakeTestEncodingConfig() appencoding.EncodingConfig { + encodingConfig := appencoding.MakeTestEncodingConfig() std.RegisterLegacyAminoCodec(encodingConfig.Amino) std.RegisterInterfaces(encodingConfig.InterfaceRegistry) ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) @@ -939,8 +939,8 @@ func MakeTestEncodingConfig() appparams.EncodingConfig { return encodingConfig } -func makeEncodingConfig() appparams.EncodingConfig { - encodingConfig := appparams.MakeTestEncodingConfig() +func makeEncodingConfig() appencoding.EncodingConfig { + encodingConfig := appencoding.MakeTestEncodingConfig() std.RegisterLegacyAminoCodec(encodingConfig.Amino) std.RegisterInterfaces(encodingConfig.InterfaceRegistry) ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) diff --git a/app/sovereign/app.go b/app/sovereign/app.go index 55967df923..4017ca9d4f 100644 --- a/app/sovereign/app.go +++ b/app/sovereign/app.go @@ -106,14 +106,14 @@ import ( "github.com/cometbft/cometbft/libs/log" tmos "github.com/cometbft/cometbft/libs/os" - appparams "github.com/cosmos/interchain-security/v4/app/params" + appencoding "github.com/cosmos/interchain-security/v4/app/encoding" testutil "github.com/cosmos/interchain-security/v4/testutil/integration" ) const ( AppName = "interchain-security-s" upgradeName = "v07-Theta" // arbitrary name, define your own appropriately named upgrade - AccountAddressPrefix = "cosmos" + AccountAddressPrefix = "consumer" ) var ( @@ -864,8 +864,8 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino // return encodingConfig // } -func MakeTestEncodingConfig() appparams.EncodingConfig { - encodingConfig := appparams.MakeTestEncodingConfig() +func MakeTestEncodingConfig() appencoding.EncodingConfig { + encodingConfig := appencoding.MakeTestEncodingConfig() std.RegisterLegacyAminoCodec(encodingConfig.Amino) std.RegisterInterfaces(encodingConfig.InterfaceRegistry) ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) @@ -873,8 +873,8 @@ func MakeTestEncodingConfig() appparams.EncodingConfig { return encodingConfig } -func makeEncodingConfig() appparams.EncodingConfig { - encodingConfig := appparams.MakeTestEncodingConfig() +func makeEncodingConfig() appencoding.EncodingConfig { + encodingConfig := appencoding.MakeTestEncodingConfig() std.RegisterLegacyAminoCodec(encodingConfig.Amino) std.RegisterInterfaces(encodingConfig.InterfaceRegistry) ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) diff --git a/cmd/interchain-security-cd/cmd/root.go b/cmd/interchain-security-cd/cmd/root.go index 64e7b76d3d..215b45317a 100644 --- a/cmd/interchain-security-cd/cmd/root.go +++ b/cmd/interchain-security-cd/cmd/root.go @@ -32,7 +32,7 @@ import ( "github.com/cometbft/cometbft/libs/log" consumer "github.com/cosmos/interchain-security/v4/app/consumer" - "github.com/cosmos/interchain-security/v4/app/params" + appencoding "github.com/cosmos/interchain-security/v4/app/encoding" ) // NewRootCmd creates a new root command for simd. It is called once in the @@ -40,7 +40,7 @@ import ( func NewRootCmd() *cobra.Command { // we "pre"-instantiate the application for getting the injected/configured encoding configuration tempApp := consumer.New(log.NewNopLogger(), dbm.NewMemDB(), nil, true, simtestutil.NewAppOptionsWithFlagHome(consumer.DefaultNodeHome)) - encodingConfig := params.EncodingConfig{ + encodingConfig := appencoding.EncodingConfig{ InterfaceRegistry: tempApp.InterfaceRegistry(), Codec: tempApp.AppCodec(), TxConfig: tempApp.TxConfig(), @@ -186,7 +186,7 @@ lru_size = 0` return customAppTemplate, customAppConfig } -func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { +func initRootCmd(rootCmd *cobra.Command, encodingConfig appencoding.EncodingConfig) { cfg := sdk.GetConfig() cfg.Seal() @@ -276,7 +276,7 @@ func addModuleInitFlags(startCmd *cobra.Command) { } // genesisCommand builds genesis-related `simd genesis` command. Users may provide application specific commands as a parameter -func genesisCommand(encodingConfig params.EncodingConfig, cmds ...*cobra.Command) *cobra.Command { +func genesisCommand(encodingConfig appencoding.EncodingConfig, cmds ...*cobra.Command) *cobra.Command { cmd := genutilcli.GenesisCoreCommand(encodingConfig.TxConfig, consumer.ModuleBasics, consumer.DefaultNodeHome) for _, sub_cmd := range cmds { diff --git a/cmd/interchain-security-cd/main.go b/cmd/interchain-security-cd/main.go index 3ecd26f899..a64a2a8645 100644 --- a/cmd/interchain-security-cd/main.go +++ b/cmd/interchain-security-cd/main.go @@ -7,12 +7,13 @@ import ( svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" app "github.com/cosmos/interchain-security/v4/app/consumer" + appparams "github.com/cosmos/interchain-security/v4/app/params" "github.com/cosmos/interchain-security/v4/cmd/interchain-security-cd/cmd" ) func main() { + appparams.SetAddressPrefixes("consumer") rootCmd := cmd.NewRootCmd() - if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { switch e := err.(type) { case server.ErrorCode: diff --git a/cmd/interchain-security-cdd/cmd/root.go b/cmd/interchain-security-cdd/cmd/root.go index b69bd57636..6b2e6cc726 100644 --- a/cmd/interchain-security-cdd/cmd/root.go +++ b/cmd/interchain-security-cdd/cmd/root.go @@ -32,7 +32,7 @@ import ( "github.com/cometbft/cometbft/libs/log" cdd "github.com/cosmos/interchain-security/v4/app/consumer-democracy" - "github.com/cosmos/interchain-security/v4/app/params" + appencoding "github.com/cosmos/interchain-security/v4/app/encoding" ) // NewRootCmd creates a new root command for simd. It is called once in the @@ -40,7 +40,7 @@ import ( func NewRootCmd() *cobra.Command { // we "pre"-instantiate the application for getting the injected/configured encoding configuration tempApp := cdd.New(log.NewNopLogger(), dbm.NewMemDB(), nil, true, simtestutil.NewAppOptionsWithFlagHome(cdd.DefaultNodeHome)) - encodingConfig := params.EncodingConfig{ + encodingConfig := appencoding.EncodingConfig{ InterfaceRegistry: tempApp.InterfaceRegistry(), Codec: tempApp.AppCodec(), TxConfig: tempApp.TxConfig(), @@ -186,7 +186,7 @@ lru_size = 0` return customAppTemplate, customAppConfig } -func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { +func initRootCmd(rootCmd *cobra.Command, encodingConfig appencoding.EncodingConfig) { cfg := sdk.GetConfig() cfg.Seal() @@ -276,7 +276,7 @@ func addModuleInitFlags(startCmd *cobra.Command) { } // genesisCommand builds genesis-related `simd genesis` command. Users may provide application specific commands as a parameter -func genesisCommand(encodingConfig params.EncodingConfig, cmds ...*cobra.Command) *cobra.Command { +func genesisCommand(encodingConfig appencoding.EncodingConfig, cmds ...*cobra.Command) *cobra.Command { cmd := genutilcli.GenesisCoreCommand(encodingConfig.TxConfig, cdd.ModuleBasics, cdd.DefaultNodeHome) for _, sub_cmd := range cmds { diff --git a/cmd/interchain-security-cdd/main.go b/cmd/interchain-security-cdd/main.go index 430ab60591..9b6aacd759 100644 --- a/cmd/interchain-security-cdd/main.go +++ b/cmd/interchain-security-cdd/main.go @@ -7,12 +7,13 @@ import ( svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" app "github.com/cosmos/interchain-security/v4/app/consumer-democracy" + appparams "github.com/cosmos/interchain-security/v4/app/params" "github.com/cosmos/interchain-security/v4/cmd/interchain-security-cdd/cmd" ) func main() { + appparams.SetAddressPrefixes("consumer") rootCmd := cmd.NewRootCmd() - if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { switch e := err.(type) { case server.ErrorCode: diff --git a/cmd/interchain-security-pd/cmd/root.go b/cmd/interchain-security-pd/cmd/root.go index 1f752d758b..8a8f5fec32 100644 --- a/cmd/interchain-security-pd/cmd/root.go +++ b/cmd/interchain-security-pd/cmd/root.go @@ -31,7 +31,7 @@ import ( tmcfg "github.com/cometbft/cometbft/config" "github.com/cometbft/cometbft/libs/log" - "github.com/cosmos/interchain-security/v4/app/params" + appencoding "github.com/cosmos/interchain-security/v4/app/encoding" providerApp "github.com/cosmos/interchain-security/v4/app/provider" ) @@ -40,7 +40,7 @@ import ( func NewRootCmd() *cobra.Command { // we "pre"-instantiate the application for getting the injected/configured encoding configuration tempApp := providerApp.New(log.NewNopLogger(), dbm.NewMemDB(), nil, true, simtestutil.NewAppOptionsWithFlagHome(providerApp.DefaultNodeHome)) - encodingConfig := params.EncodingConfig{ + encodingConfig := appencoding.EncodingConfig{ InterfaceRegistry: tempApp.InterfaceRegistry(), Codec: tempApp.AppCodec(), TxConfig: tempApp.TxConfig(), @@ -186,7 +186,7 @@ lru_size = 0` return customAppTemplate, customAppConfig } -func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { +func initRootCmd(rootCmd *cobra.Command, encodingConfig appencoding.EncodingConfig) { cfg := sdk.GetConfig() cfg.Seal() @@ -276,7 +276,7 @@ func addModuleInitFlags(startCmd *cobra.Command) { } // genesisCommand builds genesis-related `simd genesis` command. Users may provide application specific commands as a parameter -func genesisCommand(encodingConfig params.EncodingConfig, cmds ...*cobra.Command) *cobra.Command { +func genesisCommand(encodingConfig appencoding.EncodingConfig, cmds ...*cobra.Command) *cobra.Command { cmd := genutilcli.GenesisCoreCommand(encodingConfig.TxConfig, providerApp.ModuleBasics, providerApp.DefaultNodeHome) for _, sub_cmd := range cmds { cmd.AddCommand(sub_cmd) diff --git a/cmd/interchain-security-pd/main.go b/cmd/interchain-security-pd/main.go index 6091c60156..7788f06bff 100644 --- a/cmd/interchain-security-pd/main.go +++ b/cmd/interchain-security-pd/main.go @@ -6,13 +6,14 @@ import ( "github.com/cosmos/cosmos-sdk/server" svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" + appparams "github.com/cosmos/interchain-security/v4/app/params" app "github.com/cosmos/interchain-security/v4/app/provider" "github.com/cosmos/interchain-security/v4/cmd/interchain-security-pd/cmd" ) func main() { + appparams.SetAddressPrefixes("cosmos") rootCmd := cmd.NewRootCmd() - if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { switch e := err.(type) { case server.ErrorCode: diff --git a/cmd/interchain-security-sd/cmd/root.go b/cmd/interchain-security-sd/cmd/root.go index 0862e92836..28520ef1a4 100644 --- a/cmd/interchain-security-sd/cmd/root.go +++ b/cmd/interchain-security-sd/cmd/root.go @@ -31,7 +31,7 @@ import ( tmcfg "github.com/cometbft/cometbft/config" "github.com/cometbft/cometbft/libs/log" - "github.com/cosmos/interchain-security/v4/app/params" + appencoding "github.com/cosmos/interchain-security/v4/app/encoding" sovereignApp "github.com/cosmos/interchain-security/v4/app/sovereign" ) @@ -40,7 +40,7 @@ import ( func NewRootCmd() *cobra.Command { // we "pre"-instantiate the application for getting the injected/configured encoding configuration tempApp := sovereignApp.New(log.NewNopLogger(), dbm.NewMemDB(), nil, true, simtestutil.NewAppOptionsWithFlagHome(sovereignApp.DefaultNodeHome)) - encodingConfig := params.EncodingConfig{ + encodingConfig := appencoding.EncodingConfig{ InterfaceRegistry: tempApp.InterfaceRegistry(), Codec: tempApp.AppCodec(), TxConfig: tempApp.TxConfig(), @@ -186,7 +186,7 @@ lru_size = 0` return customAppTemplate, customAppConfig } -func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { +func initRootCmd(rootCmd *cobra.Command, encodingConfig appencoding.EncodingConfig) { cfg := sdk.GetConfig() cfg.Seal() @@ -276,7 +276,7 @@ func addModuleInitFlags(startCmd *cobra.Command) { } // genesisCommand builds genesis-related `simd genesis` command. Users may provide application specific commands as a parameter -func genesisCommand(encodingConfig params.EncodingConfig, cmds ...*cobra.Command) *cobra.Command { +func genesisCommand(encodingConfig appencoding.EncodingConfig, cmds ...*cobra.Command) *cobra.Command { cmd := genutilcli.GenesisCoreCommand(encodingConfig.TxConfig, sovereignApp.ModuleBasics, sovereignApp.DefaultNodeHome) for _, sub_cmd := range cmds { cmd.AddCommand(sub_cmd) diff --git a/cmd/interchain-security-sd/main.go b/cmd/interchain-security-sd/main.go index 239b08022b..2265afad90 100644 --- a/cmd/interchain-security-sd/main.go +++ b/cmd/interchain-security-sd/main.go @@ -6,13 +6,14 @@ import ( "github.com/cosmos/cosmos-sdk/server" svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" + appparams "github.com/cosmos/interchain-security/v4/app/params" app "github.com/cosmos/interchain-security/v4/app/sovereign" "github.com/cosmos/interchain-security/v4/cmd/interchain-security-sd/cmd" ) func main() { + appparams.SetAddressPrefixes("consumer") rootCmd := cmd.NewRootCmd() - if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil { switch e := err.(type) { case server.ErrorCode: diff --git a/tests/e2e/actions.go b/tests/e2e/actions.go index e98fd611e3..84c3020b91 100644 --- a/tests/e2e/actions.go +++ b/tests/e2e/actions.go @@ -33,13 +33,33 @@ func (tr TestConfig) sendTokens( action SendTokensAction, verbose bool, ) { + fromValCfg := tr.validatorConfigs[action.From] + toValCfg := tr.validatorConfigs[action.To] + fromAddress := fromValCfg.DelAddress + toAddress := toValCfg.DelAddress + if action.Chain != ChainID("provi") { + // use binary with Bech32Prefix set to ConsumerAccountPrefix + if fromValCfg.UseConsumerKey { + fromAddress = fromValCfg.ConsumerDelAddress + } else { + // use the same address as on the provider but with different prefix + fromAddress = fromValCfg.DelAddressOnConsumer + } + if toValCfg.UseConsumerKey { + toAddress = toValCfg.ConsumerDelAddress + } else { + // use the same address as on the provider but with different prefix + toAddress = toValCfg.DelAddressOnConsumer + } + } + binaryName := tr.chainConfigs[action.Chain].BinaryName //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, binaryName, "tx", "bank", "send", - tr.validatorConfigs[action.From].DelAddress, - tr.validatorConfigs[action.To].DelAddress, + fromAddress, + toAddress, fmt.Sprint(action.Amount)+`stake`, `--chain-id`, string(tr.chainConfigs[action.Chain].ChainId), @@ -653,7 +673,7 @@ type AddChainToRelayerAction struct { const hermesChainConfigTemplate = ` [[chains]] -account_prefix = "cosmos" +account_prefix = "%s" clock_drift = "5s" gas_multiplier = 1.1 grpc_addr = "%s" @@ -687,7 +707,7 @@ const gorelayerChainConfigTemplate = ` "key": "default", "chain-id": "%s", "rpc-addr": "%s", - "account-prefix": "cosmos", + "account-prefix": "%s", "keyring-backend": "test", "gas-adjustment": 1.2, "gas-prices": "0.00stake", @@ -720,6 +740,7 @@ func (tr TestConfig) addChainToGorelayer( chainConfig := fmt.Sprintf(gorelayerChainConfigTemplate, ChainId, rpcAddr, + tr.chainConfigs[action.Chain].AccountPrefix, ) //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. @@ -759,6 +780,7 @@ func (tr TestConfig) addChainToHermes( wsAddr := "ws://" + queryNodeIP + ":26658/websocket" chainConfig := fmt.Sprintf(hermesChainConfigTemplate, + tr.chainConfigs[action.Chain].AccountPrefix, grpcAddr, ChainId, keyName, @@ -1311,15 +1333,22 @@ func (tr TestConfig) delegateTokens( verbose bool, ) { toValCfg := tr.validatorConfigs[action.To] - delegateAddr := toValCfg.ValoperAddress - if action.Chain != ChainID("provi") && toValCfg.UseConsumerKey { - delegateAddr = toValCfg.ConsumerValoperAddress + validatorAddress := toValCfg.ValoperAddress + if action.Chain != ChainID("provi") { + // use binary with Bech32Prefix set to ConsumerAccountPrefix + if toValCfg.UseConsumerKey { + validatorAddress = toValCfg.ConsumerValoperAddress + } else { + // use the same address as on the provider but with different prefix + validatorAddress = toValCfg.ValoperAddressOnConsumer + } } + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[action.Chain].BinaryName, "tx", "staking", "delegate", - delegateAddr, + validatorAddress, fmt.Sprint(action.Amount)+`stake`, `--from`, `validator`+fmt.Sprint(action.From), @@ -1354,16 +1383,23 @@ func (tr TestConfig) unbondTokens( action UnbondTokensAction, verbose bool, ) { - unbondFrom := tr.validatorConfigs[action.UnbondFrom].ValoperAddress - if tr.validatorConfigs[action.UnbondFrom].UseConsumerKey { - unbondFrom = tr.validatorConfigs[action.UnbondFrom].ConsumerValoperAddress + unbondFromValCfg := tr.validatorConfigs[action.UnbondFrom] + validatorAddress := unbondFromValCfg.ValoperAddress + if action.Chain != ChainID("provi") { + // use binary with Bech32Prefix set to ConsumerAccountPrefix + if unbondFromValCfg.UseConsumerKey { + validatorAddress = unbondFromValCfg.ConsumerValoperAddress + } else { + // use the same address as on the provider but with different prefix + validatorAddress = unbondFromValCfg.ValoperAddressOnConsumer + } } //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[action.Chain].BinaryName, "tx", "staking", "unbond", - unbondFrom, + validatorAddress, fmt.Sprint(action.Amount)+`stake`, `--from`, `validator`+fmt.Sprint(action.Sender), @@ -1399,17 +1435,32 @@ func (tr TestConfig) cancelUnbondTokens( action CancelUnbondTokensAction, verbose bool, ) { - validator := tr.validatorConfigs[action.Validator].ValoperAddress - if tr.validatorConfigs[action.Validator].UseConsumerKey { - validator = tr.validatorConfigs[action.Validator].ConsumerValoperAddress + valCfg := tr.validatorConfigs[action.Validator] + delCfg := tr.validatorConfigs[action.Delegator] + validatorAddress := valCfg.ValoperAddress + delegatorAddress := delCfg.DelAddress + if action.Chain != ChainID("provi") { + // use binary with Bech32Prefix set to ConsumerAccountPrefix + if valCfg.UseConsumerKey { + validatorAddress = valCfg.ConsumerValoperAddress + } else { + // use the same address as on the provider but with different prefix + validatorAddress = valCfg.ValoperAddressOnConsumer + } + if delCfg.UseConsumerKey { + delegatorAddress = delCfg.ConsumerDelAddress + } else { + // use the same address as on the provider but with different prefix + delegatorAddress = delCfg.DelAddressOnConsumer + } } // get creation-height from state //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[action.Chain].BinaryName, "q", "staking", "unbonding-delegation", - tr.validatorConfigs[action.Delegator].DelAddress, - validator, + delegatorAddress, + validatorAddress, `--home`, tr.getValidatorHome(action.Chain, action.Delegator), `--node`, tr.getValidatorNode(action.Chain, action.Delegator), `-o`, `json`, @@ -1430,7 +1481,7 @@ func (tr TestConfig) cancelUnbondTokens( //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd = exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[action.Chain].BinaryName, "tx", "staking", "cancel-unbond", - validator, + validatorAddress, fmt.Sprint(action.Amount)+`stake`, fmt.Sprint(creationHeight), `--from`, `validator`+fmt.Sprint(action.Delegator), @@ -1467,16 +1518,24 @@ type RedelegateTokensAction struct { func (tr TestConfig) redelegateTokens(action RedelegateTokensAction, verbose bool) { srcCfg := tr.validatorConfigs[action.Src] dstCfg := tr.validatorConfigs[action.Dst] - redelegateSrc := srcCfg.ValoperAddress - if action.Chain != ChainID("provi") && srcCfg.UseConsumerKey { - redelegateSrc = srcCfg.ConsumerValoperAddress - } - redelegateDst := dstCfg.ValoperAddress - if action.Chain != ChainID("provi") && dstCfg.UseConsumerKey { - redelegateDst = dstCfg.ConsumerValoperAddress + if action.Chain != ChainID("provi") { + // use binary with Bech32Prefix set to ConsumerAccountPrefix + if srcCfg.UseConsumerKey { + redelegateSrc = srcCfg.ConsumerValoperAddress + } else { + // use the same address as on the provider but with different prefix + redelegateSrc = srcCfg.ValoperAddressOnConsumer + } + if dstCfg.UseConsumerKey { + redelegateDst = dstCfg.ConsumerValoperAddress + } else { + // use the same address as on the provider but with different prefix + redelegateDst = dstCfg.ValoperAddressOnConsumer + } } + //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, diff --git a/tests/e2e/config.go b/tests/e2e/config.go index 311ee67c89..c2079af0c3 100644 --- a/tests/e2e/config.go +++ b/tests/e2e/config.go @@ -6,6 +6,11 @@ import ( "time" ) +var ( + ProviderAccountPrefix = "cosmos" + ConsumerAccountPrefix = "consumer" +) + // TODO: Determine if user defined type (wrapping a primitive string) is desired in long run type ( ChainID string @@ -15,10 +20,27 @@ type ( // Attributes that are unique to a validator. Allows us to map (part of) // the set of strings defined above to a set of viable validators type ValidatorConfig struct { - Mnemonic string - DelAddress string - ValoperAddress string - ValconsAddress string + // Seed phrase to generate a secp256k1 key used by the validator on the provider + Mnemonic string + // Validator account address on provider marshaled to string using Bech32 + // with Bech32Prefix = ProviderAccountPrefix + DelAddress string + // Validator account address on provider marshaled to string using Bech32 + // with Bech32Prefix = ConsumerAccountPrefix + DelAddressOnConsumer string + // Validator operator address on provider marshaled to string using Bech32 + // with Bech32Prefix = ProviderAccountPrefix + ValoperAddress string + // Validator operator address on provider marshaled to string using Bech32 + // with Bech32Prefix = ConsumerAccountPrefix + ValoperAddressOnConsumer string + // Validator consensus address on provider marshaled to string using Bech32 + // with Bech32Prefix = ProviderAccountPrefix. It matches the PrivValidatorKey below. + ValconsAddress string + // Validator consensus address on provider marshaled to string using Bech32 + // with Bech32Prefix = ConsumerAccountPrefix. + ValconsAddressOnConsumer string + // Key used for consensus on provider PrivValidatorKey string NodeKey string // Must be an integer greater than 0 and less than 253 @@ -26,11 +48,29 @@ type ValidatorConfig struct { // consumer chain key assignment data // keys are used on a new node - ConsumerMnemonic string - ConsumerDelAddress string - ConsumerValoperAddress string - ConsumerValconsAddress string - ConsumerValPubKey string + + // Seed phrase to generate a secp256k1 key used by the validator on the consumer + ConsumerMnemonic string + // Validator account address on consumer marshaled to string using Bech32 + // with Bech32Prefix = ConsumerAccountPrefix + ConsumerDelAddress string + // Validator account address on consumer marshaled to string using Bech32 + // with Bech32Prefix = ProviderAccountPrefix + ConsumerDelAddressOnProvider string + // Validator operator address on consumer marshaled to string using Bech32 + // with Bech32Prefix = ConsumerAccountPrefix + ConsumerValoperAddress string + // Validator operator address on consumer marshaled to string using Bech32 + // with Bech32Prefix = ProviderAccountPrefix + ConsumerValoperAddressOnProvider string + // Validator consensus address on consumer marshaled to string using Bech32 + // with Bech32Prefix = ConsumerAccountPrefix. It matches the PrivValidatorKey below. + ConsumerValconsAddress string + // Validator consensus address on consumer marshaled to string using Bech32 + // with Bech32Prefix = ProviderAccountPrefix. + ConsumerValconsAddressOnProvider string + ConsumerValPubKey string + // Key used for consensus on consumer ConsumerPrivValidatorKey string ConsumerNodeKey string UseConsumerKey bool // if true the validator node will start with consumer key @@ -40,6 +80,8 @@ type ValidatorConfig struct { // the set of strings defined above to a set of viable chains type ChainConfig struct { ChainId ChainID + // The account prefix configured on the chain. For example, on the Hub, this is "cosmos" + AccountPrefix string // Must be unique per chain IpPrefix string VotingWaitTime uint @@ -92,61 +134,79 @@ func (tr *TestConfig) Initialize() { func getDefaultValidators() map[ValidatorID]ValidatorConfig { return 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", + 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", + DelAddressOnConsumer: "consumer19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddtz33vu", + ValoperAddress: "cosmosvaloper19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddtrgtng", + ValoperAddressOnConsumer: "consumervaloper19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddy6jwzg", + ValconsAddress: "cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq", + ValconsAddressOnConsumer: "consumervalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xpvpagq", + 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: false, + 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: "consumer1eeeggku6dzk3mv7wph3zq035rhtd890sh9rl32", + ConsumerDelAddressOnProvider: "cosmos1eeeggku6dzk3mv7wph3zq035rhtd890sjswszd", + ConsumerValoperAddress: "consumervaloper1eeeggku6dzk3mv7wph3zq035rhtd890scaqql7", + ConsumerValoperAddressOnProvider: "cosmosvaloper1eeeggku6dzk3mv7wph3zq035rhtd890shy69w7", + ConsumerValconsAddress: "consumervalcons1muys5jyqk4xd27e208nym85kn0t4zjcfk9q5ce", + ConsumerValconsAddressOnProvider: "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: false, }, 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", + 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", + DelAddressOnConsumer: "consumer1dkas8mu4kyhl5jrh4nzvm65qz588hy9qahzgv6", + ValoperAddress: "cosmosvaloper1dkas8mu4kyhl5jrh4nzvm65qz588hy9qakmjnw", + ValoperAddressOnConsumer: "consumervaloper1dkas8mu4kyhl5jrh4nzvm65qz588hy9qj0phzw", + ValconsAddress: "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39", + ValconsAddressOnConsumer: "consumervalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klhuqtq9", + 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, + 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: "consumer1q90l6j6lzzgt460ehjj56azknlt5yrd44y2uke", + ConsumerDelAddressOnProvider: "cosmos1q90l6j6lzzgt460ehjj56azknlt5yrd4s38n97", + ConsumerValoperAddress: "consumervaloper1q90l6j6lzzgt460ehjj56azknlt5yrd46ufrcd", + ConsumerValoperAddressOnProvider: "cosmosvaloper1q90l6j6lzzgt460ehjj56azknlt5yrd449nxfd", + ConsumerValconsAddress: "consumervalcons1uuec3cjxajv5te08p220usrjhkfhg9wyref26m", + ConsumerValconsAddressOnProvider: "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, }, ValidatorID("carol"): { - Mnemonic: "sight similar better jar bitter laptop solve fashion father jelly scissors chest uniform play unhappy convince silly clump another conduct behave reunion marble animal", - DelAddress: "cosmos19hz4m226ztankqramvt4a7t0shejv4dc79gp9u", - ValoperAddress: "cosmosvaloper19hz4m226ztankqramvt4a7t0shejv4dcm3u5f0", - ValconsAddress: "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6", - PrivValidatorKey: `{"address":"C888306A908A217B9A943D1DAD8790044D0947A4","pub_key":{"type":"tendermint/PubKeyEd25519","value":"IHo4QEikWZfIKmM0X+N+BjKttz8HOzGs2npyjiba3Xk="},"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"z08bmSB91uFVpVmR3t2ewd/bDjZ/AzwQpe5rKjWiPG0gejhASKRZl8gqYzRf434GMq23Pwc7MazaenKOJtrdeQ=="}}`, - NodeKey: `{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"WLTcHEjbwB24Wp3z5oBSYTvtGQonz/7IQabOFw85BN0UkkyY5HDf38o8oHlFxVI26f+DFVeICuLbe9aXKGnUeg=="}}`, - IpSuffix: "6", + Mnemonic: "sight similar better jar bitter laptop solve fashion father jelly scissors chest uniform play unhappy convince silly clump another conduct behave reunion marble animal", + DelAddress: "cosmos19hz4m226ztankqramvt4a7t0shejv4dc79gp9u", + DelAddressOnConsumer: "consumer19hz4m226ztankqramvt4a7t0shejv4dcms9wkm", + ValoperAddress: "cosmosvaloper19hz4m226ztankqramvt4a7t0shejv4dcm3u5f0", + ValoperAddressOnConsumer: "consumervaloper19hz4m226ztankqramvt4a7t0shejv4dc5gx3c0", + ValconsAddress: "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6", + ValconsAddressOnConsumer: "consumervalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayds0ea6", + PrivValidatorKey: `{"address":"C888306A908A217B9A943D1DAD8790044D0947A4","pub_key":{"type":"tendermint/PubKeyEd25519","value":"IHo4QEikWZfIKmM0X+N+BjKttz8HOzGs2npyjiba3Xk="},"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"z08bmSB91uFVpVmR3t2ewd/bDjZ/AzwQpe5rKjWiPG0gejhASKRZl8gqYzRf434GMq23Pwc7MazaenKOJtrdeQ=="}}`, + NodeKey: `{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"WLTcHEjbwB24Wp3z5oBSYTvtGQonz/7IQabOFw85BN0UkkyY5HDf38o8oHlFxVI26f+DFVeICuLbe9aXKGnUeg=="}}`, + IpSuffix: "6", // consumer chain assigned key - ConsumerMnemonic: "clip choose cake west range gun slam cry village receive juice galaxy lend ritual range provide ritual can since verify breeze vacant play dragon", - ConsumerDelAddress: "cosmos1sx6j9g2rh324a342a5f0rnx7me34r9nwgf0mc7", - ConsumerValoperAddress: "cosmosvaloper1sx6j9g2rh324a342a5f0rnx7me34r9nwdamw5d", - ConsumerValconsAddress: "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk", - ConsumerValPubKey: `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is="}`, - ConsumerPrivValidatorKey: `{"address":"B41C3A40142963AA5B12DDD1C4E5890C0B3926B1","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is="},"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"3YaBAZLA+sl/E73lLfbFbG0u6DYm33ayr/0UpCt/vFBSLkZ/X6a1ZR0fy7fGWbN0ogP4Xc8rSx9dnvcZnqrqKw=="}}`, - ConsumerNodeKey: `{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"rxBzFedtD3pqgfJQblbxGusKOr47oBfr8ba0Iz14gobtDRZQZlSZ/UGP4pSHkVf+4vtkrkO1vRHBYJobuiP+7A=="}}`, - UseConsumerKey: true, + ConsumerMnemonic: "clip choose cake west range gun slam cry village receive juice galaxy lend ritual range provide ritual can since verify breeze vacant play dragon", + ConsumerDelAddress: "consumer1sx6j9g2rh324a342a5f0rnx7me34r9nwduz5te", + ConsumerDelAddressOnProvider: "cosmos1sx6j9g2rh324a342a5f0rnx7me34r9nwgf0mc7", + ConsumerValoperAddress: "consumervaloper1sx6j9g2rh324a342a5f0rnx7me34r9nwzypt9d", + ConsumerValoperAddressOnProvider: "cosmosvaloper1sx6j9g2rh324a342a5f0rnx7me34r9nwdamw5d", + ConsumerValconsAddress: "consumervalcons1kswr5sq599365kcjmhgufevfps9njf43kv9tuk", + ConsumerValconsAddressOnProvider: "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk", + ConsumerValPubKey: `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is="}`, + ConsumerPrivValidatorKey: `{"address":"B41C3A40142963AA5B12DDD1C4E5890C0B3926B1","pub_key":{"type":"tendermint/PubKeyEd25519","value":"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is="},"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"3YaBAZLA+sl/E73lLfbFbG0u6DYm33ayr/0UpCt/vFBSLkZ/X6a1ZR0fy7fGWbN0ogP4Xc8rSx9dnvcZnqrqKw=="}}`, + ConsumerNodeKey: `{"priv_key":{"type":"tendermint/PrivKeyEd25519","value":"rxBzFedtD3pqgfJQblbxGusKOr47oBfr8ba0Iz14gobtDRZQZlSZ/UGP4pSHkVf+4vtkrkO1vRHBYJobuiP+7A=="}}`, + UseConsumerKey: true, }, } } @@ -164,6 +224,7 @@ func SlashThrottleTestConfig() TestConfig { chainConfigs: map[ChainID]ChainConfig{ ChainID("provi"): { ChainId: ChainID("provi"), + AccountPrefix: ProviderAccountPrefix, BinaryName: "interchain-security-pd", IpPrefix: "7.7.7", VotingWaitTime: 20, @@ -179,6 +240,7 @@ func SlashThrottleTestConfig() TestConfig { }, ChainID("consu"): { ChainId: ChainID("consu"), + AccountPrefix: ConsumerAccountPrefix, BinaryName: "interchain-security-cd", IpPrefix: "7.7.8", VotingWaitTime: 20, @@ -210,6 +272,7 @@ func DefaultTestConfig() TestConfig { chainConfigs: map[ChainID]ChainConfig{ ChainID("provi"): { ChainId: ChainID("provi"), + AccountPrefix: ProviderAccountPrefix, BinaryName: "interchain-security-pd", IpPrefix: "7.7.7", VotingWaitTime: 20, @@ -225,6 +288,7 @@ func DefaultTestConfig() TestConfig { }, ChainID("consu"): { ChainId: ChainID("consu"), + AccountPrefix: ConsumerAccountPrefix, BinaryName: "interchain-security-cd", IpPrefix: "7.7.8", VotingWaitTime: 20, @@ -268,6 +332,7 @@ func DemocracyTestConfig(allowReward bool) TestConfig { chainConfigs: map[ChainID]ChainConfig{ ChainID("provi"): { ChainId: ChainID("provi"), + AccountPrefix: ProviderAccountPrefix, BinaryName: "interchain-security-pd", IpPrefix: "7.7.7", VotingWaitTime: 20, @@ -282,6 +347,7 @@ func DemocracyTestConfig(allowReward bool) TestConfig { }, ChainID("democ"): { ChainId: ChainID("democ"), + AccountPrefix: ConsumerAccountPrefix, BinaryName: "interchain-security-cdd", IpPrefix: "7.7.9", VotingWaitTime: 20, @@ -308,6 +374,7 @@ func MultiConsumerTestConfig() TestConfig { chainConfigs: map[ChainID]ChainConfig{ ChainID("provi"): { ChainId: ChainID("provi"), + AccountPrefix: ProviderAccountPrefix, BinaryName: "interchain-security-pd", IpPrefix: "7.7.7", VotingWaitTime: 20, @@ -322,6 +389,7 @@ func MultiConsumerTestConfig() TestConfig { }, ChainID("consu"): { ChainId: ChainID("consu"), + AccountPrefix: ConsumerAccountPrefix, BinaryName: "interchain-security-cd", IpPrefix: "7.7.8", VotingWaitTime: 20, @@ -333,6 +401,7 @@ func MultiConsumerTestConfig() TestConfig { }, ChainID("densu"): { ChainId: ChainID("densu"), + AccountPrefix: ConsumerAccountPrefix, BinaryName: "interchain-security-cd", IpPrefix: "7.7.9", VotingWaitTime: 20, @@ -363,6 +432,7 @@ func ChangeoverTestConfig() TestConfig { chainConfigs: map[ChainID]ChainConfig{ ChainID("provi"): { ChainId: ChainID("provi"), + AccountPrefix: ProviderAccountPrefix, BinaryName: "interchain-security-pd", IpPrefix: "7.7.7", VotingWaitTime: 20, @@ -378,6 +448,7 @@ func ChangeoverTestConfig() TestConfig { }, ChainID("sover"): { ChainId: ChainID("sover"), + AccountPrefix: ConsumerAccountPrefix, BinaryName: "interchain-security-sd", UpgradeBinary: "interchain-security-cdd", IpPrefix: "7.7.8", @@ -408,47 +479,60 @@ func ConsumerMisbehaviourTestConfig() TestConfig { }, 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", + 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", + DelAddressOnConsumer: "consumer19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddtz33vu", + ValoperAddress: "cosmosvaloper19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddtrgtng", + ValoperAddressOnConsumer: "consumervaloper19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddy6jwzg", + ValconsAddress: "cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq", + ValconsAddressOnConsumer: "consumervalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xpvpagq", + 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, + 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: "consumer1eeeggku6dzk3mv7wph3zq035rhtd890sh9rl32", + ConsumerDelAddressOnProvider: "cosmos1eeeggku6dzk3mv7wph3zq035rhtd890sjswszd", + ConsumerValoperAddress: "consumervaloper1eeeggku6dzk3mv7wph3zq035rhtd890scaqql7", + ConsumerValoperAddressOnProvider: "cosmosvaloper1eeeggku6dzk3mv7wph3zq035rhtd890shy69w7", + ConsumerValconsAddress: "consumervalcons1muys5jyqk4xd27e208nym85kn0t4zjcfk9q5ce", + ConsumerValconsAddressOnProvider: "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", + 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", + DelAddressOnConsumer: "consumer1dkas8mu4kyhl5jrh4nzvm65qz588hy9qahzgv6", + ValoperAddress: "cosmosvaloper1dkas8mu4kyhl5jrh4nzvm65qz588hy9qakmjnw", + ValoperAddressOnConsumer: "consumervaloper1dkas8mu4kyhl5jrh4nzvm65qz588hy9qj0phzw", + ValconsAddress: "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39", + ValconsAddressOnConsumer: "consumervalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klhuqtq9", + 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, + 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: "consumer1q90l6j6lzzgt460ehjj56azknlt5yrd44y2uke", + ConsumerDelAddressOnProvider: "cosmos1q90l6j6lzzgt460ehjj56azknlt5yrd4s38n97", + ConsumerValoperAddress: "consumervaloper1q90l6j6lzzgt460ehjj56azknlt5yrd46ufrcd", + ConsumerValoperAddressOnProvider: "cosmosvaloper1q90l6j6lzzgt460ehjj56azknlt5yrd449nxfd", + ConsumerValconsAddress: "consumervalcons1uuec3cjxajv5te08p220usrjhkfhg9wyref26m", + ConsumerValconsAddressOnProvider: "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"), + AccountPrefix: ProviderAccountPrefix, BinaryName: "interchain-security-pd", IpPrefix: "7.7.7", VotingWaitTime: 20, @@ -464,6 +548,7 @@ func ConsumerMisbehaviourTestConfig() TestConfig { }, ChainID("consu"): { ChainId: ChainID("consu"), + AccountPrefix: ConsumerAccountPrefix, BinaryName: "interchain-security-cd", IpPrefix: "7.7.8", VotingWaitTime: 20, diff --git a/tests/e2e/main.go b/tests/e2e/main.go index 13e3fae1e7..5f3ea71e74 100644 --- a/tests/e2e/main.go +++ b/tests/e2e/main.go @@ -54,14 +54,15 @@ var ( // map the test config names to their structs to allow for easy selection of test configs, // and also to programmatically 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(), - "consumer-misbehaviour": ConsumerMisbehaviourTestConfig(), - "consumer-double-sign": DefaultTestConfig(), + "default": DefaultTestConfig(), + "changeover": ChangeoverTestConfig(), + "democracy": DemocracyTestConfig(false), + "democracy-reward": DemocracyTestConfig(true), + "slash-throttle": SlashThrottleTestConfig(), + "multiconsumer": MultiConsumerTestConfig(), + "consumer-misbehaviour": ConsumerMisbehaviourTestConfig(), + "consumer-double-sign": DefaultTestConfig(), + "consumer-double-downtime": DefaultTestConfig(), } ) @@ -128,6 +129,12 @@ var stepChoices = map[string]StepChoice{ description: "consumer double signing tests", testConfig: DefaultTestConfig(), }, + "consumer-double-downtime": { + name: "consumer-double-downtime", + steps: consumerDoubleDowntimeSteps, + description: "jail a validator for two (different) downtime infractions on consumer", + testConfig: DefaultTestConfig(), + }, } func executeTests(tests []testStepsWithConfig) (err error) { @@ -232,6 +239,7 @@ func getTestCases(selectedPredefinedTests, selectedTestFiles TestSet) (tests []t "changeover", "happy-path", "democracy-reward", "democracy", "slash-throttle", "consumer-double-sign", "consumer-misbehaviour", + "consumer-double-downtime", } if includeMultiConsumer != nil && *includeMultiConsumer { selectedPredefinedTests = append(selectedPredefinedTests, "multiconsumer") diff --git a/tests/e2e/state.go b/tests/e2e/state.go index 6578aad03a..0b2c2d1835 100644 --- a/tests/e2e/state.go +++ b/tests/e2e/state.go @@ -316,9 +316,16 @@ func (tr TestConfig) getRewards(chain ChainID, modelState Rewards) Rewards { } func (tr TestConfig) getReward(chain ChainID, validator ValidatorID, blockHeight uint, isNativeDenom bool) float64 { - delAddresss := tr.validatorConfigs[validator].DelAddress - if chain != ChainID("provi") && tr.validatorConfigs[validator].UseConsumerKey { - delAddresss = tr.validatorConfigs[validator].ConsumerDelAddress + valCfg := tr.validatorConfigs[validator] + delAddresss := valCfg.DelAddress + if chain != ChainID("provi") { + // use binary with Bech32Prefix set to ConsumerAccountPrefix + if valCfg.UseConsumerKey { + delAddresss = valCfg.ConsumerDelAddress + } else { + // use the same address as on the provider but with different prefix + delAddresss = valCfg.DelAddressOnConsumer + } } //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. @@ -345,9 +352,16 @@ func (tr TestConfig) getReward(chain ChainID, validator ValidatorID, blockHeight func (tr TestConfig) getBalance(chain ChainID, validator ValidatorID) uint { //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. - valDelAddress := tr.validatorConfigs[validator].DelAddress - if chain != ChainID("provi") && tr.validatorConfigs[validator].UseConsumerKey { - valDelAddress = tr.validatorConfigs[validator].ConsumerDelAddress + valCfg := tr.validatorConfigs[validator] + valDelAddress := valCfg.DelAddress + if chain != ChainID("provi") { + // use binary with Bech32Prefix set to ConsumerAccountPrefix + if valCfg.UseConsumerKey { + valDelAddress = valCfg.ConsumerDelAddress + } else { + // use the same address as on the provider but with different prefix + valDelAddress = valCfg.DelAddressOnConsumer + } } //#nosec G204 -- Bypass linter warning for spawning subprocess with cmd arguments. @@ -485,6 +499,7 @@ type ValPubKey struct { Value string `yaml:"value"` } +// TODO (mpoke) Return powers for multiple validators func (tr TestConfig) getValPower(chain ChainID, validator ValidatorID) uint { if *verbose { log.Println("getting validator power for chain: ", chain, " validator: ", validator) @@ -519,16 +534,25 @@ func (tr TestConfig) getValPower(chain ChainID, validator ValidatorID) uint { } for _, val := range valset.Validators { - if val.Address == tr.validatorConfigs[validator].ValconsAddress || - val.Address == tr.validatorConfigs[validator].ConsumerValconsAddress { - - votingPower, err := strconv.Atoi(val.VotingPower) - if err != nil { - log.Fatalf("strconv.Atoi returned an error while converting validator voting power: %v, voting power string: %s, validator set: %s", err, val.VotingPower, pretty.Sprint(valset)) + if chain == ChainID("provi") { + // use binary with Bech32Prefix set to ProviderAccountPrefix + if val.Address != tr.validatorConfigs[validator].ValconsAddress { + continue } + } else { + // use binary with Bech32Prefix set to ConsumerAccountPrefix + if val.Address != tr.validatorConfigs[validator].ValconsAddressOnConsumer && + val.Address != tr.validatorConfigs[validator].ConsumerValconsAddress { + continue + } + } - return uint(votingPower) + votingPower, err := strconv.Atoi(val.VotingPower) + if err != nil { + log.Fatalf("strconv.Atoi returned an error while converting validator voting power: %v, voting power string: %s, validator set: %s", err, val.VotingPower, pretty.Sprint(valset)) } + + return uint(votingPower) } // Validator not in set, its validator power is zero. @@ -536,11 +560,22 @@ func (tr TestConfig) getValPower(chain ChainID, validator ValidatorID) uint { } func (tr TestConfig) getValStakedTokens(chain ChainID, validator ValidatorID) uint { + valoperAddress := tr.validatorConfigs[validator].ValoperAddress + if chain != ChainID("provi") { + // use binary with Bech32Prefix set to ConsumerAccountPrefix + if tr.validatorConfigs[validator].UseConsumerKey { + valoperAddress = tr.validatorConfigs[validator].ConsumerValoperAddress + } else { + // use the same address as on the provider but with different prefix + valoperAddress = tr.validatorConfigs[validator].ValoperAddressOnConsumer + } + } + //#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", "staking", "validator", - tr.validatorConfigs[validator].ValoperAddress, + valoperAddress, `--node`, tr.getQueryNode(chain), `-o`, `json`, @@ -641,7 +676,7 @@ func (tr TestConfig) getProviderAddressFromConsumer(consumerChain ChainID, valid cmd := exec.Command("docker", "exec", tr.containerConfig.InstanceName, tr.chainConfigs[ChainID("provi")].BinaryName, "query", "provider", "validator-provider-key", - string(consumerChain), tr.validatorConfigs[validator].ConsumerValconsAddress, + string(consumerChain), tr.validatorConfigs[validator].ConsumerValconsAddressOnProvider, `--node`, tr.getQueryNode(ChainID("provi")), `-o`, `json`, ) diff --git a/tests/e2e/steps.go b/tests/e2e/steps.go index 783d976a3a..1626df0de2 100644 --- a/tests/e2e/steps.go +++ b/tests/e2e/steps.go @@ -114,3 +114,11 @@ var consumerDoubleSignSteps = concatSteps( // make a consumer validator double sign and get jailed stepsCauseDoubleSignOnConsumer("consu", "provi"), ) + +var consumerDoubleDowntimeSteps = concatSteps( + stepsStartChains([]string{"consu"}, false), + stepsDelegate("consu"), + stepsUnbond("consu"), + stepsRedelegateShort("consu"), + stepsDoubleDowntime("consu"), +) diff --git a/tests/e2e/steps_consumer_misbehaviour.go b/tests/e2e/steps_consumer_misbehaviour.go index 4df7b9daec..3cb4ce0f1b 100644 --- a/tests/e2e/steps_consumer_misbehaviour.go +++ b/tests/e2e/steps_consumer_misbehaviour.go @@ -61,7 +61,7 @@ func stepsStartChainsWithSoftOptOut(consumerName string) []Step { Action: AssignConsumerPubKeyAction{ Chain: ChainID(consumerName), Validator: ValidatorID("alice"), - ConsumerPubkey: `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"ujY14AgopV907IYgPAk/5x8c9267S4fQf89nyeCPTes="}`, + ConsumerPubkey: getDefaultValidators()[ValidatorID("alice")].ConsumerValPubKey, // consumer chain has not started // we don't need to reconfigure the node // since it will start with consumer key @@ -70,10 +70,10 @@ func stepsStartChainsWithSoftOptOut(consumerName string) []Step { State: State{ ChainID(consumerName): ChainState{ AssignedKeys: &map[ValidatorID]string{ - ValidatorID("alice"): "cosmosvalcons1muys5jyqk4xd27e208nym85kn0t4zjcfeu63fe", + ValidatorID("alice"): getDefaultValidators()[ValidatorID("alice")].ConsumerValconsAddressOnProvider, }, ProviderKeys: &map[ValidatorID]string{ - ValidatorID("alice"): "cosmosvalcons1qmq08eruchr5sf5s3rwz7djpr5a25f7xw4mceq", + ValidatorID("alice"): getDefaultValidators()[ValidatorID("alice")].ValconsAddress, }, }, }, diff --git a/tests/e2e/steps_downtime.go b/tests/e2e/steps_downtime.go index f63d0a31c9..a8506bf518 100644 --- a/tests/e2e/steps_downtime.go +++ b/tests/e2e/steps_downtime.go @@ -211,6 +211,204 @@ func stepsDowntime(consumerName string) []Step { } } +// stepsDowstepsDoubleDowntime time tests that a validator can get jailed twice +// on a consumer. +// These are the steps: +// - a validator is down on a consumer +// - the validator gets jailed on the provider (when the SlashPacket is received) +// - the validator gets removed from the consumer (when the VSCPacket is received) +// - the validator gets unjailed on the provider +// - the validator is added to the consumer (when the VSCPacket is received) +// - the validator is down again on the consumer +// - the validator gets jailed on the provider (when the SlashPacket is received) +// - the validator gets removed from the consumer (when the VSCPacket is received) +func stepsDoubleDowntime(consumerName string) []Step { + return []Step{ + { + Action: DowntimeSlashAction{ + Chain: ChainID(consumerName), + Validator: ValidatorID("bob"), + }, + State: State{ + // validator should be slashed on consumer, powers not affected on either chain yet + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 509, + ValidatorID("bob"): 500, + ValidatorID("carol"): 501, + }, + }, + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 509, + ValidatorID("bob"): 500, + ValidatorID("carol"): 501, + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID(consumerName), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 509, + // Downtime jailing and corresponding voting power change are processed by provider + ValidatorID("bob"): 0, + ValidatorID("carol"): 501, + }, + }, + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 509, + // Bob's stake may or may not be slashed at this point depending on comet vs cometmock + // See https://github.com/cosmos/interchain-security/issues/1304 + ValidatorID("carol"): 501, + }, + }, + }, + }, + // A block is incremented each action, hence why VSC is committed on provider, + // and can now be relayed as packet to consumer + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID(consumerName), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 509, + // VSC now seen on consumer + ValidatorID("bob"): 0, + ValidatorID("carol"): 501, + }, + }, + }, + }, + { + Action: UnjailValidatorAction{ + Provider: ChainID("provi"), + Validator: ValidatorID("bob"), + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 509, + // bob's stake should not be slashed + // since the slash was initiated from consumer + ValidatorID("bob"): 500, + ValidatorID("carol"): 501, + }, + }, + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 509, + ValidatorID("bob"): 0, + ValidatorID("carol"): 501, + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID(consumerName), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 509, + // bob's stake should not be slashed + // since the slash was initiated from consumer + ValidatorID("bob"): 500, + ValidatorID("carol"): 501, + }, + }, + }, + }, + // Try to jail bob again on the consumer + { + Action: DowntimeSlashAction{ + Chain: ChainID(consumerName), + Validator: ValidatorID("bob"), + }, + State: State{ + // validator should be slashed on consumer, powers not affected on either chain yet + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 509, + ValidatorID("bob"): 500, + ValidatorID("carol"): 501, + }, + }, + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 509, + ValidatorID("bob"): 500, + ValidatorID("carol"): 501, + }, + }, + }, + }, + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID(consumerName), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID("provi"): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 509, + // Downtime jailing and corresponding voting power change are processed by provider + ValidatorID("bob"): 0, + ValidatorID("carol"): 501, + }, + }, + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 509, + // Bob's stake may or may not be slashed at this point depending on comet vs cometmock + // See https://github.com/cosmos/interchain-security/issues/1304 + ValidatorID("carol"): 501, + }, + }, + }, + }, + // A block is incremented each action, hence why VSC is committed on provider, + // and can now be relayed as packet to consumer + { + Action: RelayPacketsAction{ + ChainA: ChainID("provi"), + ChainB: ChainID(consumerName), + Port: "provider", + Channel: 0, + }, + State: State{ + ChainID(consumerName): ChainState{ + ValPowers: &map[ValidatorID]uint{ + ValidatorID("alice"): 509, + // VSC now seen on consumer + ValidatorID("bob"): 0, + ValidatorID("carol"): 501, + }, + }, + }, + }, + } +} + // stepsDowntimeWithOptOut returns steps validating that alice can incur downtime // and not be slashed/jailed, since her voting power is less than 5% of the total. // diff --git a/tests/e2e/steps_start_chains.go b/tests/e2e/steps_start_chains.go index b1fdb65df5..08732e3f37 100644 --- a/tests/e2e/steps_start_chains.go +++ b/tests/e2e/steps_start_chains.go @@ -64,7 +64,7 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint Action: AssignConsumerPubKeyAction{ Chain: ChainID(consumerName), Validator: ValidatorID("carol"), - ConsumerPubkey: `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is="}`, + ConsumerPubkey: getDefaultValidators()[ValidatorID("carol")].ConsumerValPubKey, // consumer chain has not started // we don't need to reconfigure the node // since it will start with consumer key @@ -73,10 +73,10 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint State: State{ ChainID(consumerName): ChainState{ AssignedKeys: &map[ValidatorID]string{ - ValidatorID("carol"): "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk", + ValidatorID("carol"): getDefaultValidators()[ValidatorID("carol")].ConsumerValconsAddressOnProvider, }, ProviderKeys: &map[ValidatorID]string{ - ValidatorID("carol"): "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6", + ValidatorID("carol"): getDefaultValidators()[ValidatorID("carol")].ValconsAddress, }, }, }, @@ -86,7 +86,7 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint Action: AssignConsumerPubKeyAction{ Chain: ChainID(consumerName), Validator: ValidatorID("carol"), - ConsumerPubkey: `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is="}`, + ConsumerPubkey: getDefaultValidators()[ValidatorID("carol")].ConsumerValPubKey, ReconfigureNode: false, ExpectError: true, ExpectedError: "a validator has assigned the consumer key already: consumer key is already in use by a validator", @@ -99,7 +99,7 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint Chain: ChainID(consumerName), Validator: ValidatorID("bob"), // same pub key as carol - ConsumerPubkey: `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"Ui5Gf1+mtWUdH8u3xlmzdKID+F3PK0sfXZ73GZ6q6is="}`, + ConsumerPubkey: getDefaultValidators()[ValidatorID("carol")].ConsumerValPubKey, ReconfigureNode: false, ExpectError: true, ExpectedError: "a validator has assigned the consumer key already: consumer key is already in use by a validator", @@ -107,11 +107,11 @@ func stepsStartConsumerChain(consumerName string, proposalIndex, chainIndex uint State: State{ ChainID(consumerName): ChainState{ AssignedKeys: &map[ValidatorID]string{ - ValidatorID("carol"): "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk", + ValidatorID("carol"): getDefaultValidators()[ValidatorID("carol")].ConsumerValconsAddressOnProvider, ValidatorID("bob"): "", }, ProviderKeys: &map[ValidatorID]string{ - ValidatorID("carol"): "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6", + ValidatorID("carol"): getDefaultValidators()[ValidatorID("carol")].ValconsAddress, }, }, }, @@ -235,7 +235,7 @@ func stepsAssignConsumerKeyOnStartedChain(consumerName, validator string) []Step Validator: ValidatorID("bob"), // reconfigure the node -> validator was using provider key // until this point -> key matches config.consumerValPubKey for "bob" - ConsumerPubkey: `{"@type":"/cosmos.crypto.ed25519.PubKey","key":"QlG+iYe6AyYpvY1z9RNJKCVlH14Q/qSz4EjGdGCru3o="}`, + ConsumerPubkey: getDefaultValidators()[ValidatorID("bob")].ConsumerValPubKey, ReconfigureNode: true, }, State: State{ @@ -257,12 +257,12 @@ func stepsAssignConsumerKeyOnStartedChain(consumerName, validator string) []Step ValidatorID("carol"): 500, }, AssignedKeys: &map[ValidatorID]string{ - ValidatorID("bob"): "cosmosvalcons1uuec3cjxajv5te08p220usrjhkfhg9wyvqn0tm", - ValidatorID("carol"): "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk", + ValidatorID("bob"): getDefaultValidators()[ValidatorID("bob")].ConsumerValconsAddressOnProvider, + ValidatorID("carol"): getDefaultValidators()[ValidatorID("carol")].ConsumerValconsAddressOnProvider, }, ProviderKeys: &map[ValidatorID]string{ - ValidatorID("bob"): "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39", - ValidatorID("carol"): "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6", + ValidatorID("bob"): getDefaultValidators()[ValidatorID("bob")].ValconsAddress, + ValidatorID("carol"): getDefaultValidators()[ValidatorID("carol")].ValconsAddress, }, }, }, @@ -293,12 +293,12 @@ func stepsAssignConsumerKeyOnStartedChain(consumerName, validator string) []Step ValidatorID("carol"): 500, }, AssignedKeys: &map[ValidatorID]string{ - ValidatorID("bob"): "cosmosvalcons1uuec3cjxajv5te08p220usrjhkfhg9wyvqn0tm", - ValidatorID("carol"): "cosmosvalcons1kswr5sq599365kcjmhgufevfps9njf43e4lwdk", + ValidatorID("bob"): getDefaultValidators()[ValidatorID("bob")].ConsumerValconsAddressOnProvider, + ValidatorID("carol"): getDefaultValidators()[ValidatorID("carol")].ConsumerValconsAddressOnProvider, }, ProviderKeys: &map[ValidatorID]string{ - ValidatorID("bob"): "cosmosvalcons1nx7n5uh0ztxsynn4sje6eyq2ud6rc6klc96w39", - ValidatorID("carol"): "cosmosvalcons1ezyrq65s3gshhx5585w6mpusq3xsj3ayzf4uv6", + ValidatorID("bob"): getDefaultValidators()[ValidatorID("bob")].ValconsAddress, + ValidatorID("carol"): getDefaultValidators()[ValidatorID("carol")].ValconsAddress, }, }, }, diff --git a/tests/e2e/testnet-scripts/fork-consumer.sh b/tests/e2e/testnet-scripts/fork-consumer.sh index 7c12438b71..db8199d192 100644 --- a/tests/e2e/testnet-scripts/fork-consumer.sh +++ b/tests/e2e/testnet-scripts/fork-consumer.sh @@ -53,7 +53,7 @@ enabled = true [[chains]] id = "consu" ccv_consumer_chain = true -account_prefix = "cosmos" +account_prefix = "consumer" clock_drift = "5s" gas_multiplier = 1.1 grpc_addr = "tcp://$CONS_CHAIN_PREFIX.252:9091" diff --git a/tests/e2e/testnet-scripts/sovereign-genesis.json b/tests/e2e/testnet-scripts/sovereign-genesis.json index c3ae9da36c..ba95b2fbce 100644 --- a/tests/e2e/testnet-scripts/sovereign-genesis.json +++ b/tests/e2e/testnet-scripts/sovereign-genesis.json @@ -35,7 +35,7 @@ "accounts": [ { "@type": "/cosmos.auth.v1beta1.BaseAccount", - "address": "cosmos19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddwhu7lm", + "address": "consumer19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddtz33vu", "pub_key": null, "account_number": "0", "sequence": "0" @@ -52,7 +52,7 @@ }, "balances": [ { - "address": "cosmos19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddwhu7lm", + "address": "consumer19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddtz33vu", "coins": [ { "denom": "stake", @@ -125,8 +125,8 @@ "max_change_rate": "0.010000000000000000" }, "min_self_delegation": "1", - "delegator_address": "cosmos19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddwhu7lm", - "validator_address": "cosmosvaloper19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddtrgtng", + "delegator_address": "consumer19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddtz33vu", + "validator_address": "consumervaloper19pe9pg5dv9k5fzgzmsrgnw9rl9asf7ddy6jwzg", "pubkey": { "@type": "/cosmos.crypto.ed25519.PubKey", "key": "RrclQz9bIhkIy/gfL485g3PYMeiIku4qeo495787X10=" @@ -166,7 +166,7 @@ "tip": null }, "signatures": [ - "c7aD9dWzb85fn+Aq0ijMdhyJNJSOsOcFLvJt8ctvdxAAbwdrzKPVFbq9IYf1qCwKmfmQUrlFy40qiuQeXaZ8pg==" + "AZROMEeaBL9cDOWQJYYdAG3KDl+w37SK0XP88ecS+WwQQLj8rXuEKNDl1PXpZR0AFIJ8coSwhFEtbpV44j6uVQ==" ] } ] diff --git a/x/ccv/consumer/keeper/keeper.go b/x/ccv/consumer/keeper/keeper.go index a43a773862..b8751344b8 100644 --- a/x/ccv/consumer/keeper/keeper.go +++ b/x/ccv/consumer/keeper/keeper.go @@ -501,13 +501,9 @@ func (k Keeper) SetOutstandingDowntime(ctx sdk.Context, address sdk.ConsAddress) } // DeleteOutstandingDowntime deletes the outstanding downtime flag for the given validator consensus address -func (k Keeper) DeleteOutstandingDowntime(ctx sdk.Context, consAddress string) { - consAddr, err := sdk.ConsAddressFromBech32(consAddress) - if err != nil { - return // TODO: this should panic with appropriate tests to validate the panic won't happen in normal cases. - } +func (k Keeper) DeleteOutstandingDowntime(ctx sdk.Context, address sdk.ConsAddress) { store := ctx.KVStore(k.storeKey) - store.Delete(types.OutstandingDowntimeKey(consAddr)) + store.Delete(types.OutstandingDowntimeKey(address)) } // GetAllOutstandingDowntimes gets an array of the validator addresses of outstanding downtime flags diff --git a/x/ccv/consumer/keeper/relay.go b/x/ccv/consumer/keeper/relay.go index 0de4b0c35f..2d4e16510a 100644 --- a/x/ccv/consumer/keeper/relay.go +++ b/x/ccv/consumer/keeper/relay.go @@ -82,8 +82,19 @@ func (k Keeper) OnRecvVSCPacket(ctx sdk.Context, packet channeltypes.Packet, new // remove outstanding slashing flags of the validators // for which the slashing was acknowledged by the provider chain - for _, addr := range newChanges.GetSlashAcks() { - k.DeleteOutstandingDowntime(ctx, addr) + for _, ack := range newChanges.GetSlashAcks() { + // get consensus address from bech32 address + consAddr, err := ccv.GetConsAddrFromBech32(ack) + if err != nil { + // Do not return an error as it would lead to the consumer being + // removed by the provider + k.Logger(ctx).Error("invalid consensus address in VSCPacket.SlashAcks", + "vscID", newChanges.ValsetUpdateId, + "SlashAck", ack, + "error", err) + continue + } + k.DeleteOutstandingDowntime(ctx, consAddr) } k.Logger(ctx).Info("finished receiving/handling VSCPacket", diff --git a/x/ccv/consumer/keeper/relay_test.go b/x/ccv/consumer/keeper/relay_test.go index 7c30c3e4f0..46a805a85a 100644 --- a/x/ccv/consumer/keeper/relay_test.go +++ b/x/ccv/consumer/keeper/relay_test.go @@ -123,8 +123,8 @@ func TestOnRecvVSCPacket(t *testing.T) { }}, }, { - "failure on packet with invalid slash acks", - true, + "success on packet with invalid slash acks", + false, channeltypes.NewPacket(pd3.GetBytes(), 4, types.ProviderPortID, providerCCVChannelID, types.ConsumerPortID, consumerCCVChannelID, clienttypes.NewHeight(1, 0), 0), types.ValidatorSetChangePacketData{ValidatorUpdates: []abci.ValidatorUpdate{ diff --git a/x/ccv/consumer/keeper/validators.go b/x/ccv/consumer/keeper/validators.go index 31e803bad4..24a1c5a57c 100644 --- a/x/ccv/consumer/keeper/validators.go +++ b/x/ccv/consumer/keeper/validators.go @@ -59,6 +59,10 @@ func (k Keeper) ApplyCCValidatorChanges(ctx sdk.Context, changes []abci.Validato // AfterValidatorBonded is called by the Slashing module and should not return an error. panic(err) } + // Sanity check: making sure the outstanding downtime flag is not + // set for this new validator. This is especially useful to deal with + // https://github.com/cosmos/interchain-security/issues/1569. + k.DeleteOutstandingDowntime(ctx, consAddr) } else { // edge case: we received an update for 0 power // but the validator is already deleted. Do not forward diff --git a/x/ccv/types/utils.go b/x/ccv/types/utils.go index f6e7ffc3aa..ae85240256 100644 --- a/x/ccv/types/utils.go +++ b/x/ccv/types/utils.go @@ -1,8 +1,10 @@ package types import ( + "errors" "reflect" "sort" + "strings" "time" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" @@ -13,6 +15,7 @@ import ( cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/bech32" abci "github.com/cometbft/cometbft/abci/types" tmprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" @@ -106,3 +109,17 @@ func PanicIfZeroOrNil(x interface{}, nameForPanicMsg string) { panic("zero or nil value for " + nameForPanicMsg) } } + +// GetConsAddrFromBech32 returns a ConsAddress from a Bech32 with an arbitrary prefix +func GetConsAddrFromBech32(bech32str string) (sdk.ConsAddress, error) { + bech32Addr := strings.TrimSpace(bech32str) + if len(bech32Addr) == 0 { + return nil, errors.New("couldn't parse empty input") + } + // remove bech32 prefix + _, addr, err := bech32.DecodeAndConvert(bech32Addr) + if err != nil { + return nil, errors.New("couldn't find valid bech32") + } + return sdk.ConsAddress(addr), nil +} diff --git a/x/ccv/types/wire.go b/x/ccv/types/wire.go index c7cbe9e126..9c22522b74 100644 --- a/x/ccv/types/wire.go +++ b/x/ccv/types/wire.go @@ -30,13 +30,6 @@ func (vsc ValidatorSetChangePacketData) Validate() error { if vsc.ValsetUpdateId == 0 { return errorsmod.Wrap(ErrInvalidPacketData, "valset update id cannot be equal to zero") } - // Validate the slash acks - must be consensus addresses - for _, ack := range vsc.SlashAcks { - _, err := sdk.ConsAddressFromBech32(ack) - if err != nil { - return err - } - } return nil } diff --git a/x/ccv/types/wire_test.go b/x/ccv/types/wire_test.go index e8ba966c8c..ab6692912e 100644 --- a/x/ccv/types/wire_test.go +++ b/x/ccv/types/wire_test.go @@ -17,93 +17,40 @@ import ( ) func TestPacketDataValidateBasic(t *testing.T) { - pk1, err := cryptocodec.ToTmProtoPublicKey(ed25519.GenPrivKey().PubKey()) - require.NoError(t, err) - pk2, err := cryptocodec.ToTmProtoPublicKey(ed25519.GenPrivKey().PubKey()) + pk, err := cryptocodec.ToTmProtoPublicKey(ed25519.GenPrivKey().PubKey()) require.NoError(t, err) - cId := crypto.NewCryptoIdentityFromIntSeed(4732894342) - validSlashAck := cId.SDKValConsAddress().String() - tooLongSlashAck := string(make([]byte, 1024)) - cases := []struct { name string expError bool packetData types.ValidatorSetChangePacketData }{ { - "invalid: nil packet data", + "invalid: zero ValsetUpdateId", true, - types.NewValidatorSetChangePacketData(nil, 1, nil), + types.NewValidatorSetChangePacketData([]abci.ValidatorUpdate{}, 0, nil), }, { - "valid: empty packet data", - false, - types.NewValidatorSetChangePacketData([]abci.ValidatorUpdate{}, 2, nil), - }, - { - "invalid: slash ack not consensus address", + "invalid: nil ValidatorUpdates", true, - types.NewValidatorSetChangePacketData( - []abci.ValidatorUpdate{ - { - PubKey: pk1, - Power: 30, - }, - }, - 3, - []string{ - "some_string", - }, - ), + types.NewValidatorSetChangePacketData(nil, 1, nil), }, { - "valid: packet data with valid slash ack", + "valid: empty ValidatorUpdates", false, - types.NewValidatorSetChangePacketData( - []abci.ValidatorUpdate{ - { - PubKey: pk2, - Power: 20, - }, - }, - 4, - []string{ - validSlashAck, - }, - ), - }, - { - "invalid: slash ack is too long", - true, - types.NewValidatorSetChangePacketData( - []abci.ValidatorUpdate{ - { - PubKey: pk2, - Power: 20, - }, - }, - 5, - []string{ - tooLongSlashAck, - }, - ), + types.NewValidatorSetChangePacketData([]abci.ValidatorUpdate{}, 2, nil), }, { - "valid: packet data with nil slash ack", + "valid: one validator update", false, types.NewValidatorSetChangePacketData( []abci.ValidatorUpdate{ { - PubKey: pk1, + PubKey: pk, Power: 30, }, - { - PubKey: pk2, - Power: 20, - }, }, - 6, + 3, nil, ), },