Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat!: migrate to allocate previously allocated rewards, and distribute unaccounted denoms #3361

Merged
merged 12 commits into from
Oct 4, 2024
94 changes: 93 additions & 1 deletion app/upgrades/v21/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,40 @@ package v21

import (
"context"
"fmt"

providerkeeper "github.com/cosmos/interchain-security/v6/x/ccv/provider/keeper"
providertypes "github.com/cosmos/interchain-security/v6/x/ccv/provider/types"

errorsmod "cosmossdk.io/errors"
"cosmossdk.io/math"
upgradetypes "cosmossdk.io/x/upgrade/types"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"

"github.com/cosmos/gaia/v21/app/keepers"
)

// Neutron and Stride denoms that were not whitelisted but the consumer rewards pool contains amounts of those denoms.
// Price in $ for each denom corresponds to an approximation fo the current amount stored in the consumer rewards pool
// as of 27.09.2024. Only denoms with amounts more than $10 are included.
const (
NeutronUusdc = "ibc/4E0D0854C0F846150FA8389D75EA5B5129B17703D7F4992D0356B4FE7C013D42" // ~$40
NeutronUtia = "ibc/7054742D02E4F28B7DB5B44D97A496CF5AD16C2AE6948028A5FD57DCE7C5E271" // ~$300

StrideStutia = "ibc/17DABEBAC71C388DA064A3D54FB7E68BAF0687965EC39DEADA1FB78C0F1447E6" // ~$18,000
StrideStadym = "ibc/3F0A41ECB6FAF27E315583DBF39B5B69A7149D23959A0E4B319F7EF5C618DCD7" // ~$800
StrideStaISLM = "ibc/61A6F21D6AFF9835F66056461F1CAE24AA3323820259856B485FE7C063CA4FA6" // ~$1650
StrideStuband = "ibc/E9401AC885592AC2023E0FB9BA7C8BC66D346CEE04CED8E9F545F3C25290708A" // ~$300
StrideStadydx = "ibc/EEFD952A6DE346F2649039E99A16430B05FFEDF628A4DE99F34BB4B5F6A9346E" // ~$21,000
StrideStusaga = "ibc/F918765AC289257B35DECC52BD92EBCDBA3C139658BD6F2670D70A6E10B97F58" // ~$300
)

// CreateUpgradeHandler returns an upgrade handler for Gaia v21.
func CreateUpgradeHandler(
mm *module.Manager,
configurator module.Configurator,
Expand All @@ -23,7 +47,15 @@ func CreateUpgradeHandler(

vm, err := mm.RunMigrations(ctx, configurator, vm)
if err != nil {
return vm, err
return vm, errorsmod.Wrapf(err, "running module migrations")
}

ctx.Logger().Info("allocating rewards of Neutron and Stride unaccounted denoms")
err = AllocateNeutronAndStrideUnaccountedDenoms(ctx, keepers.ProviderKeeper, keepers.BankKeeper, keepers.AccountKeeper)
if err != nil {
// migration can only work on cosmoshub-4
// all testchains except for mainnet export fork will fail this
ctx.Logger().Error("Error allocating rewards of Neutron and Stride unaccounted denoms:", "message", err.Error())
}

err = InitializeConstitutionCollection(ctx, *keepers.GovKeeper)
Expand All @@ -36,6 +68,66 @@ func CreateUpgradeHandler(
}
}

// AllocateRewards allocates all the `denoms` that reside in the `address` and are meant for the chain with `consumerID`
func AllocateRewards(ctx sdk.Context, providerKeeper providerkeeper.Keeper, bankKeeper bankkeeper.Keeper, address sdk.AccAddress, consumerID string, denoms []string) error {
for _, denom := range denoms {
coinRewards := bankKeeper.GetBalance(ctx, address, denom)
decCoinRewards := sdk.DecCoins{sdk.DecCoin{Denom: coinRewards.Denom, Amount: math.LegacyNewDecFromInt(coinRewards.Amount)}}
consumerRewardsAllocation := providertypes.ConsumerRewardsAllocation{Rewards: decCoinRewards}

err := providerKeeper.SetConsumerRewardsAllocationByDenom(ctx, consumerID, denom, consumerRewardsAllocation)
if err != nil {
return err
}
}
return nil
}

// HasexpectedChainIDSanityCheck returns true if the chain with the provided `consumerID` is of a chain with the `expectedChainID`
func HasExpectedChainIDSanityCheck(ctx sdk.Context, providerKeeper providerkeeper.Keeper, consumerID string, expectedChainID string) bool {
actualChainID, err := providerKeeper.GetConsumerChainId(ctx, consumerID)
if err != nil {
return false
}
if expectedChainID != actualChainID {
return false
}
return true
Comment on lines +92 to +95
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, in the future we can make this simply

return expectedChainID == actualChainID

}

// AllocateNeutronAndStrideUnaccountedDenoms allocates previously unaccounted denoms to the Stride and Neutron consumer chains
func AllocateNeutronAndStrideUnaccountedDenoms(ctx sdk.Context, providerKeeper providerkeeper.Keeper, bankKeeper bankkeeper.Keeper, accountKeeper authkeeper.AccountKeeper) error {
consumerRewardsPoolAddress := accountKeeper.GetModuleAccount(ctx, providertypes.ConsumerRewardsPool).GetAddress()

const NeutronconsumerID = "0"
const NeutronChainID = "neutron-1"

if !HasExpectedChainIDSanityCheck(ctx, providerKeeper, NeutronconsumerID, NeutronChainID) {
return fmt.Errorf("failed sanity check: consumer id (%s) does not correspond to chain id (%s)", NeutronconsumerID, NeutronChainID)
}

neutronUnaccountedDenoms := []string{NeutronUusdc, NeutronUtia}
err := AllocateRewards(ctx, providerKeeper, bankKeeper, consumerRewardsPoolAddress, NeutronconsumerID, neutronUnaccountedDenoms)
if err != nil {
return fmt.Errorf("cannot allocate rewards for consumer id (%s): %w", NeutronconsumerID, err)
}

const StrideconsumerID = "1"
const StrideChainID = "stride-1"

if !HasExpectedChainIDSanityCheck(ctx, providerKeeper, StrideconsumerID, StrideChainID) {
return fmt.Errorf("failed sanity check: consumer id (%s) does not correspond to chain id (%s)", StrideconsumerID, StrideChainID)
}

strideUnaccountedDenoms := []string{StrideStutia, StrideStadym, StrideStaISLM, StrideStuband, StrideStadydx, StrideStusaga}
err = AllocateRewards(ctx, providerKeeper, bankKeeper, consumerRewardsPoolAddress, StrideconsumerID, strideUnaccountedDenoms)
if err != nil {
return fmt.Errorf("cannot allocate rewards for consumer id (%s): %w", StrideconsumerID, err)
}

return nil
}

// setting the default constitution for the chain
// this is in line with cosmos-sdk v5 gov migration: https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/x/gov/migrations/v5/store.go#L57
func InitializeConstitutionCollection(ctx sdk.Context, govKeeper govkeeper.Keeper) error {
Expand Down
18 changes: 18 additions & 0 deletions app/upgrades/v21/upgrades_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,24 @@ import (
v21 "github.com/cosmos/gaia/v21/app/upgrades/v21"
)

func TestHasExpectedChainIDSanityCheck(t *testing.T) {
gaiaApp := helpers.Setup(t)
ctx := gaiaApp.NewUncachedContext(true, tmproto.Header{})

pk := gaiaApp.ProviderKeeper

// no such consumer chain
consumerID := "0"
require.False(t, v21.HasExpectedChainIDSanityCheck(ctx, pk, consumerID, "chain-1"))

// consumer chain does not have `chain-1` id
pk.SetConsumerChainId(ctx, consumerID, "chain-2")
require.False(t, v21.HasExpectedChainIDSanityCheck(ctx, pk, consumerID, "chain-1"))

pk.SetConsumerChainId(ctx, consumerID, "chain-1")
require.True(t, v21.HasExpectedChainIDSanityCheck(ctx, pk, consumerID, "chain-1"))
}

func TestInitializeConstitutionCollection(t *testing.T) {
gaiaApp := helpers.Setup(t)
ctx := gaiaApp.NewUncachedContext(true, tmproto.Header{})
Expand Down
5 changes: 3 additions & 2 deletions cmd/gaiad/cmd/testnet_set_local_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ import (
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
"github.com/cosmos/cosmos-sdk/server"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
gaia "github.com/cosmos/gaia/v21/app"
"github.com/spf13/cast"
"github.com/spf13/cobra"

gaia "github.com/cosmos/gaia/v21/app"

"cosmossdk.io/log"
"github.com/cometbft/cometbft/crypto"
tmd25519 "github.com/cometbft/cometbft/crypto/ed25519"
Expand Down Expand Up @@ -269,7 +270,7 @@ func updateApplicationState(app *gaia.GaiaApp, args valArgs) error {
// PROVIDER
app.ProviderKeeper.DeleteLastProviderConsensusValSet(appCtx)

// GOVERNANCE
// GOVERNANCE
shortVotingPeriod := time.Second * 20
expeditedVotingPeriod := time.Second * 10
params, err := app.GovKeeper.Params.Get(appCtx)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ require (
github.com/cosmos/ibc-apps/modules/rate-limiting/v8 v8.0.0
github.com/cosmos/ibc-go/modules/capability v1.0.1
github.com/cosmos/ibc-go/v8 v8.5.1
github.com/cosmos/interchain-security/v6 v6.1.0
github.com/cosmos/interchain-security/v6 v6.2.0-rc0
github.com/google/gofuzz v1.2.0
github.com/gorilla/mux v1.8.1
github.com/ory/dockertest/v3 v3.11.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,8 @@ github.com/cosmos/ibc-go/v8 v8.5.1 h1:3JleEMKBjRKa3FeTKt4fjg22za/qygLBo7mDkoYTNB
github.com/cosmos/ibc-go/v8 v8.5.1/go.mod h1:P5hkAvq0Qbg0h18uLxDVA9q1kOJ0l36htMsskiNwXbo=
github.com/cosmos/ics23/go v0.11.0 h1:jk5skjT0TqX5e5QJbEnwXIS2yI2vnmLOgpQPeM5RtnU=
github.com/cosmos/ics23/go v0.11.0/go.mod h1:A8OjxPE67hHST4Icw94hOxxFEJMBG031xIGF/JHNIY0=
github.com/cosmos/interchain-security/v6 v6.1.0 h1:ycTpT+If90nSEvRVu86ThPJxNtcmnOMjJmFC9ptd/yo=
github.com/cosmos/interchain-security/v6 v6.1.0/go.mod h1:+5zIZEzkL4yNHB/UWXCu75t6GeEgEmWHbz5OnBWiL0o=
github.com/cosmos/interchain-security/v6 v6.2.0-rc0 h1:RjGfEDSnOlsgXG4g5FSr5PBUE4V5N1wfCH09vLqrMDE=
github.com/cosmos/interchain-security/v6 v6.2.0-rc0/go.mod h1:8Ke3cbEBBMImBkWPfF1bxPFg5ZqYOxZPjpnh0ItxQMQ=
github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo=
github.com/cosmos/keyring v1.2.0/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA=
github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM=
Expand Down
1 change: 0 additions & 1 deletion tests/interchain/cosmwasm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ func (s *CosmWasmSuite) TestCantInstantiateWithoutProp() {
}

func (s *CosmWasmSuite) TestCreateNewContract() {

_, contractAddr := s.storeInstantiateProposal(initState)

count := s.getContractCount(contractAddr)
Expand Down
2 changes: 1 addition & 1 deletion tests/interchain/permissionless_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,8 @@ func (s *PermissionlessConsumersSuite) TestChangePowerShaping() {
s.Require().NoError(err)
s.Require().Equal(consumer.ValidatorWallets[i].ValConsAddress, valCons)
}

}

func (s *PermissionlessConsumersSuite) TestConsumerCommissionRate() {
s.UpgradeChain()
cfg := s.consumerCfg
Expand Down
Loading