From 84f7ebe075c78aca05c0080b0f14db15ae33df10 Mon Sep 17 00:00:00 2001 From: Reece Williams <31943163+Reecepbcups@users.noreply.github.com> Date: Tue, 16 Jan 2024 16:23:53 -0600 Subject: [PATCH] chore(upgrade): Migrate Core-1 Multisig to Charter Council (#936) * init * finally get delegation to work, hacky though by force setting ugh * idfk negative coin amount * fix staking util * prop16Core1Multisig & move unvested funds * cleanup * use ctx.GetBlockTime() for determinism * lintor * use `juno-1` height for go test * cleanup * remove stale comment * move func * remove mintUnvestedToCharter * fix test * Test Redelgations & Pre-Upgrade Undelegations * Lint --------- Co-authored-by: Joel Smith --- .gitignore | 2 +- app/apptesting/test_suite.go | 21 +++-- app/upgrades/v19/constants.go | 5 ++ app/upgrades/v19/mainnet_account.go | 44 ++++++++++ app/upgrades/v19/upgrade_test.go | 45 +++++++++- app/upgrades/v19/upgrades.go | 132 ++++++++++++++++++++++++++++ 6 files changed, 237 insertions(+), 12 deletions(-) create mode 100644 app/upgrades/v19/mainnet_account.go diff --git a/.gitignore b/.gitignore index e5e151ed2..d67943a7f 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,7 @@ tmp-swagger-gen heighliner* -**/data/wasm/* +**/data/**/* # emacs editor config \#*\# diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index 3c635664c..1ab204aaa 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -31,6 +31,7 @@ import ( distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakinghelper "github.com/cosmos/cosmos-sdk/x/staking/testutil" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" @@ -45,6 +46,8 @@ type KeeperTestHelper struct { Ctx sdk.Context QueryHelper *baseapp.QueryServiceTestHelper TestAccs []sdk.AccAddress + + StakingHelper *stakinghelper.Helper } var ( @@ -56,12 +59,15 @@ var ( func (s *KeeperTestHelper) Setup() { t := s.T() s.App = app.Setup(t) - s.Ctx = s.App.BaseApp.NewContext(false, tmtypes.Header{Height: 1, ChainID: "testing", Time: time.Now().UTC()}) + s.Ctx = s.App.BaseApp.NewContext(false, tmtypes.Header{Height: 1, ChainID: "juno-1", Time: time.Now().UTC()}) s.QueryHelper = &baseapp.QueryServiceTestHelper{ GRPCQueryRouter: s.App.GRPCQueryRouter(), Ctx: s.Ctx, } s.TestAccs = CreateRandomAccounts(3) + + s.StakingHelper = stakinghelper.NewHelper(s.Suite.T(), s.Ctx, s.App.AppKeepers.StakingKeeper) + s.StakingHelper.Denom = "ujuno" } func (s *KeeperTestHelper) SetupTestForInitGenesis() { @@ -118,21 +124,18 @@ func (s *KeeperTestHelper) MintCoins(coins sdk.Coins) { // SetupValidator sets up a validator and returns the ValAddress. func (s *KeeperTestHelper) SetupValidator(bondStatus stakingtypes.BondStatus) sdk.ValAddress { - valPub := secp256k1.GenPrivKey().PubKey() + valPriv := secp256k1.GenPrivKey() + valPub := valPriv.PubKey() valAddr := sdk.ValAddress(valPub.Address()) bondDenom := s.App.AppKeepers.StakingKeeper.GetParams(s.Ctx).BondDenom selfBond := sdk.NewCoins(sdk.Coin{Amount: sdk.NewInt(100), Denom: bondDenom}) s.FundAcc(sdk.AccAddress(valAddr), selfBond) - // stakingHandler := staking.NewHandler(s.App.AppKeepers.StakingKeeper) - stakingCoin := sdk.NewCoin(appparams.BondDenom, selfBond[0].Amount) - ZeroCommission := stakingtypes.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()) - _, err := stakingtypes.NewMsgCreateValidator(valAddr, valPub, stakingCoin, stakingtypes.Description{}, ZeroCommission, sdk.OneInt()) + msg := s.StakingHelper.CreateValidatorMsg(valAddr, valPub, selfBond[0].Amount) + res, err := s.StakingHelper.CreateValidatorWithMsg(s.Ctx, msg) s.Require().NoError(err) - // res, err := stakingHandler(s.Ctx, msg) - // s.Require().NoError(err) - // s.Require().NotNil(res) + s.Require().NotNil(res) val, found := s.App.AppKeepers.StakingKeeper.GetValidator(s.Ctx, valAddr) s.Require().True(found) diff --git a/app/upgrades/v19/constants.go b/app/upgrades/v19/constants.go index 18d61982c..a2b18b060 100644 --- a/app/upgrades/v19/constants.go +++ b/app/upgrades/v19/constants.go @@ -8,6 +8,11 @@ import ( "github.com/CosmosContracts/juno/v19/app/upgrades" ) +const ( + Core1MultisigVestingAccount = "juno190g5j8aszqhvtg7cprmev8xcxs6csra7xnk3n3" + CharterCouncil = "juno1nmezpepv3lx45mndyctz2lzqxa6d9xzd2xumkxf7a6r4nxt0y95qypm6c0" +) + // UpgradeName defines the on-chain upgrade name for the upgrade. const UpgradeName = "v19" diff --git a/app/upgrades/v19/mainnet_account.go b/app/upgrades/v19/mainnet_account.go new file mode 100644 index 000000000..d337e4166 --- /dev/null +++ b/app/upgrades/v19/mainnet_account.go @@ -0,0 +1,44 @@ +package v19 + +import ( + "encoding/json" + + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" + banktestutil "github.com/cosmos/cosmos-sdk/x/bank/testutil" + + "github.com/CosmosContracts/juno/v19/app/keepers" +) + +const ( + // based off some mintscan data, this is JUST for testing. (ujuno) + AvaliableCoins = 2176229301554 + DelegatedCoins = 6803271425657 + StakingRewardCoins = 909613203388 +) + +// junod q auth account juno190g5j8aszqhvtg7cprmev8xcxs6csra7xnk3n3 --output=json +// returns the account and remaining unvested +func CreateMainnetVestingAccount(ctx sdk.Context, k keepers.AppKeepers) (*vestingtypes.PeriodicVestingAccount, math.Int) { + // manually convert the account_number, sequence, start_time, end_time to a non string + // regex: "length":"([0-9]+)" -> "length":$1 + + str := `{"@type":"/cosmos.vesting.v1beta1.PeriodicVestingAccount","base_vesting_account":{"base_account":{"address":"juno190g5j8aszqhvtg7cprmev8xcxs6csra7xnk3n3","pub_key":{"@type":"/cosmos.crypto.multisig.LegacyAminoPubKey","threshold":3,"public_keys":[{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A+hZFIZ3i+5jD83trhShTmD/bAAXpIyb6tHJDJtiOAn6"},{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"ApcEus7fRKwSRNNs4nlOy62fFH9Ep7lg9DQRsnx9Ht0H"},{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A1SgSrlikj83agLUJPYDuWTjPkw4rPzkWgMMy/5RxANy"},{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A5fjV581bOBJSuHpBkY7ve3uZJFAv4JI14+K+RiHgr30"},{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"Akr1IlYcH7p08W8pdYNkmAEvDRoPOXdOefg56cm3paKm"}]},"account_number":46159,"sequence":33},"original_vesting":[{"denom":"ujuno","amount":"12457737000000"}],"delegated_free":[{"denom":"ujuno","amount":"398745473523"}],"delegated_vesting":[{"denom":"ujuno","amount":"6404764327386"}],"end_time":2006348400},"start_time":1633100400,"vesting_periods":[{"length":0,"amount":[{"denom":"ujuno","amount":"2373341000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"294128000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"294128000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"294128000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"294128000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"294128000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"294128000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"294128000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"294128000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"294128000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"294128000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"294128000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"294128000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"147064000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"147064000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"147064000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"147064000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"147064000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"147064000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"147064000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"147064000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"147064000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"147064000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"147064000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"147064000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"73952000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"73952000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"73952000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"73952000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"73952000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"73952000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"73952000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"73952000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"73952000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"73952000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"73952000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"73952000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"66388000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"66388000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"66388000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"66388000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"66388000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"66388000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"66388000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"66388000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"66388000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"66388000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"66388000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"66388000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"58825000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"58825000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"58825000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"58825000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"58825000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"58825000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"58825000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"58825000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"58825000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"58825000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"58825000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"58825000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"51262000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"51262000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"51262000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"51262000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"51262000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"51262000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"51262000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"51262000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"51262000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"51262000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"51262000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"51262000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"43867000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"43867000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"43867000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"43867000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"43867000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"43867000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"43867000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"43867000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"43867000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"43867000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"43867000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"43867000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"36556000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"36556000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"36556000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"36556000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"36556000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"36556000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"36556000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"36556000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"36556000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"36556000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"36556000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"36556000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"29245000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"29245000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"29245000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"29245000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"29245000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"29245000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"29245000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"29245000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"29245000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"29245000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"29245000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"29245000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"21934000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"21934000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"21934000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"21934000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"21934000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"21934000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"21934000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"21934000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"21934000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"21934000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"21934000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"21934000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"14623000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"14623000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"14623000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"14623000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"14623000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"14623000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"14623000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"14623000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"14623000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"14623000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"14623000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"14623000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"2522000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"2522000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"2522000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"2522000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"2522000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"2522000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"2522000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"2522000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"2522000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"2522000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"2522000000"}]},{"length":2592000,"amount":[{"denom":"ujuno","amount":"2526000000"}]}]}` + + var acc vestingtypes.PeriodicVestingAccount + if err := json.Unmarshal([]byte(str), &acc); err != nil { + panic(err) + } + + unvested := SumPeriodVestingAccountsUnvestedTokensAmount(ctx, &acc) + + err := banktestutil.FundAccount(k.BankKeeper, ctx, acc.BaseAccount.GetAddress(), sdk.NewCoins(sdk.NewCoin("ujuno", math.NewInt(AvaliableCoins+DelegatedCoins+StakingRewardCoins)))) + if err != nil { + panic(err) + } + + k.AccountKeeper.SetAccount(ctx, &acc) + return &acc, unvested +} diff --git a/app/upgrades/v19/upgrade_test.go b/app/upgrades/v19/upgrade_test.go index 07e3ac969..9a678e3ed 100644 --- a/app/upgrades/v19/upgrade_test.go +++ b/app/upgrades/v19/upgrade_test.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" + vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/CosmosContracts/juno/v19/app/apptesting" @@ -30,13 +31,53 @@ func TestKeeperTestSuite(t *testing.T) { // Ensures the test does not error out. func (s *UpgradeTestSuite) TestUpgrade() { s.Setup() - preUpgradeChecks(s) + // == CREATE MOCK CORE-1 ACCOUNT == + c1m, unvested := v19.CreateMainnetVestingAccount(s.Ctx, s.App.AppKeepers) + c1mAddr := c1m.GetAddress() + fmt.Printf("c1mAddr unvested: %+v\n", unvested) + + core1Prebal := s.App.AppKeepers.BankKeeper.GetAllBalances(s.Ctx, c1mAddr) + fmt.Printf("Core1 bal: %s\n", core1Prebal) + + // create many validators to confirm the unbonding code works + newVal1 := s.SetupValidator(stakingtypes.Bonded) + newVal2 := s.SetupValidator(stakingtypes.Bonded) + newVal3 := s.SetupValidator(stakingtypes.Bonded) + + // Delegate tokens of the core1 multisig account + s.StakingHelper.Delegate(c1mAddr, newVal1, sdk.NewInt(1)) + s.StakingHelper.Delegate(c1mAddr, newVal2, sdk.NewInt(2)) + s.StakingHelper.Delegate(c1mAddr, newVal3, sdk.NewInt(3)) + + // Undelegate part of the tokens from val2 (test instant unbonding on undelegation started before upgrade) + s.StakingHelper.Undelegate(c1mAddr, newVal3, sdk.NewInt(1), true) + + // Redelegate part of the tokens from val2 -> val3 (test instant unbonding on redelegations started before upgrade) + _, err := s.App.AppKeepers.StakingKeeper.BeginRedelegation(s.Ctx, c1mAddr, newVal2, newVal3, sdk.NewDec(1)) + s.Require().NoError(err) + + // Confirm delegated to 3 validators + s.Require().Equal(3, len(s.App.AppKeepers.StakingKeeper.GetAllDelegatorDelegations(s.Ctx, c1mAddr))) + + // == UPGRADE == upgradeHeight := int64(5) s.ConfirmUpgradeSucceeded(v19.UpgradeName, upgradeHeight) - postUpgradeChecks(s) + + // == POST VERIFICATION == + updatedAcc := s.App.AppKeepers.AccountKeeper.GetAccount(s.Ctx, c1mAddr) + _, ok := updatedAcc.(*vestingtypes.PeriodicVestingAccount) + s.Require().False(ok) + + s.Require().Equal(0, len(s.App.AppKeepers.BankKeeper.GetAllBalances(s.Ctx, c1mAddr))) + s.Require().Equal(0, len(s.App.AppKeepers.StakingKeeper.GetAllDelegatorDelegations(s.Ctx, c1mAddr))) + s.Require().Equal(0, len(s.App.AppKeepers.StakingKeeper.GetRedelegations(s.Ctx, c1mAddr, 65535))) + + charterBal := s.App.AppKeepers.BankKeeper.GetAllBalances(s.Ctx, sdk.MustAccAddressFromBech32(v19.CharterCouncil)) + fmt.Printf("Council Post Upgrade Balance: %s\n", charterBal) + s.Require().True(charterBal.AmountOf("ujuno").GTE(core1Prebal.AmountOf("ujuno"))) } func preUpgradeChecks(s *UpgradeTestSuite) { diff --git a/app/upgrades/v19/upgrades.go b/app/upgrades/v19/upgrades.go index f9f1567bd..6efa1d698 100644 --- a/app/upgrades/v19/upgrades.go +++ b/app/upgrades/v19/upgrades.go @@ -2,11 +2,15 @@ package v19 import ( "fmt" + "time" wasmlctypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" decorators "github.com/CosmosContracts/juno/v19/app/decorators" @@ -45,6 +49,10 @@ func CreateV19UpgradeHandler( } } + if ctx.ChainID() == "juno-1" { + migrateCore1MultisigVesting(ctx, k) + } + // https://github.com/cosmos/ibc-go/blob/main/docs/docs/03-light-clients/04-wasm/03-integration.md params := k.IBCKeeper.ClientKeeper.GetParams(ctx) params.AllowedClients = append(params.AllowedClients, wasmlctypes.Wasm) @@ -53,3 +61,127 @@ func CreateV19UpgradeHandler( return versionMap, err } } + +// migrateCore1Vesting moves the funds and delegations from the PeriodicVestingAccount -> the new Council (contract address). +// - Get the Core-1 multisig vesting account +// - Instantly finish all redelegations, then unbond all tokens. +// - Send all tokens to the new council (including the previously held balance) +// - Sum all future vesting periods, then mint and send those tokens to the new council. +func migrateCore1MultisigVesting(ctx sdk.Context, k *keepers.AppKeepers) { + Core1Addr := sdk.MustAccAddressFromBech32(Core1MultisigVestingAccount) + CouncilAddr := sdk.MustAccAddressFromBech32(CharterCouncil) + + core1Acc := k.AccountKeeper.GetAccount(ctx, Core1Addr) + + vestingAcc, ok := core1Acc.(*vestingtypes.PeriodicVestingAccount) + if !ok { + panic(fmt.Errorf("core1Acc.(*vestingtypes.PeriodicVestingAccount): %+v", core1Acc)) + } + + // SEND TO THE CHARTER + prop16Core1Multisig(ctx, k, Core1Addr, CouncilAddr) + + // REMOVE VESTING FROM THE CORE1 MULTISIG (set it to the base account, no vesting terms) + k.AccountKeeper.SetAccount(ctx, vestingAcc.BaseAccount) +} + +func prop16Core1Multisig(ctx sdk.Context, k *keepers.AppKeepers, Core1Addr, CouncilAddr sdk.AccAddress) { // nolint:gocritic + redelegated, err := completeAllRedelegations(ctx, ctx.BlockTime(), k, Core1Addr) + if err != nil { + panic(err) + } + + unbonded, err := unbondAllAndFinish(ctx, ctx.BlockTime(), k, Core1Addr) + if err != nil { + panic(err) + } + + fmt.Printf("Core1Addr Instant Redelegations: %s\n", redelegated) + fmt.Printf("Core1Addr Instant Unbonding: %s\n", unbonded) + + // now send these to the council + err = k.BankKeeper.SendCoins(ctx, Core1Addr, CouncilAddr, sdk.NewCoins(k.BankKeeper.GetBalance(ctx, Core1Addr, "ujuno"))) + if err != nil { + panic(err) + } +} + +func SumPeriodVestingAccountsUnvestedTokensAmount(ctx sdk.Context, acc *vestingtypes.PeriodicVestingAccount) (unvested math.Int) { + now := ctx.BlockTime() + startTime := time.Unix(acc.StartTime, 0) + + unvested = math.ZeroInt() + for _, period := range acc.VestingPeriods { + durration := time.Duration(period.Length) * time.Minute + if startTime.Add(durration).After(now) { + unvested = unvested.Add(period.Amount[0].Amount) + } + + startTime = startTime.Add(time.Duration(period.Length)) + } + + return unvested +} + +// From Prop16 +func completeAllRedelegations(ctx sdk.Context, now time.Time, keepers *keepers.AppKeepers, accAddr sdk.AccAddress) (math.Int, error) { + redelegatedAmt := math.ZeroInt() + + for _, activeRedelegation := range keepers.StakingKeeper.GetRedelegations(ctx, accAddr, 65535) { + redelegationSrc, _ := sdk.ValAddressFromBech32(activeRedelegation.ValidatorSrcAddress) + redelegationDst, _ := sdk.ValAddressFromBech32(activeRedelegation.ValidatorDstAddress) + + // set all entry completionTime to now so we can complete re-delegation + for i := range activeRedelegation.Entries { + activeRedelegation.Entries[i].CompletionTime = now + redelegatedAmt = redelegatedAmt.Add(math.Int(activeRedelegation.Entries[i].SharesDst)) + } + + keepers.StakingKeeper.SetRedelegation(ctx, activeRedelegation) + _, err := keepers.StakingKeeper.CompleteRedelegation(ctx, accAddr, redelegationSrc, redelegationDst) + if err != nil { + return redelegatedAmt, err + } + } + + return redelegatedAmt, nil +} + +// From Prop16 +func unbondAllAndFinish(ctx sdk.Context, now time.Time, keepers *keepers.AppKeepers, accAddr sdk.AccAddress) (math.Int, error) { + unbondedAmt := math.ZeroInt() + + // Unbond all delegations from the account + for _, delegation := range keepers.StakingKeeper.GetAllDelegatorDelegations(ctx, accAddr) { + validatorValAddr := delegation.GetValidatorAddr() + _, found := keepers.StakingKeeper.GetValidator(ctx, validatorValAddr) + if !found { + continue + } + + _, err := keepers.StakingKeeper.Undelegate(ctx, accAddr, validatorValAddr, delegation.GetShares()) + if err != nil { + return math.ZeroInt(), err + } + } + + // Take all unbonding and complete them. + for _, unbondingDelegation := range keepers.StakingKeeper.GetAllUnbondingDelegations(ctx, accAddr) { + validatorStringAddr := unbondingDelegation.ValidatorAddress + validatorValAddr, _ := sdk.ValAddressFromBech32(validatorStringAddr) + + // Complete unbonding delegation + for i := range unbondingDelegation.Entries { + unbondingDelegation.Entries[i].CompletionTime = now + unbondedAmt = unbondedAmt.Add(unbondingDelegation.Entries[i].Balance) + } + + keepers.StakingKeeper.SetUnbondingDelegation(ctx, unbondingDelegation) + _, err := keepers.StakingKeeper.CompleteUnbonding(ctx, accAddr, validatorValAddr) + if err != nil { + return math.ZeroInt(), err + } + } + + return unbondedAmt, nil +}