Skip to content

Commit

Permalink
feat: add migrateMultisigVesting
Browse files Browse the repository at this point in the history
  • Loading branch information
hoank101 committed Feb 6, 2024
1 parent e664b69 commit 0c4534e
Show file tree
Hide file tree
Showing 7 changed files with 467 additions and 36 deletions.
2 changes: 2 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,8 @@ func (app *MigalooApp) setupUpgradeHandlers() {
app.ConsensusParamsKeeper,
app.ICAControllerKeeper,
app.AccountKeeper,
*app.StakingKeeper,
app.BankKeeper,
),
)

Expand Down
209 changes: 199 additions & 10 deletions app/test_helpers.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
package app

import (
"cosmossdk.io/math"

Check failure on line 4 in app/test_helpers.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gofumpt`-ed (gofumpt)
"encoding/json"
"fmt"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
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"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
"testing"
"time"

Expand All @@ -10,8 +21,9 @@ import (
dbm "github.com/cometbft/cometbft-db"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/libs/log"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
tdmtypes "github.com/cometbft/cometbft/proto/tendermint/types"
tmtypes "github.com/cometbft/cometbft/types"

"github.com/cosmos/cosmos-sdk/baseapp"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
Expand All @@ -36,23 +48,26 @@ const (
type KeeperTestHelper struct {
suite.Suite

App *MigalooApp
Ctx sdk.Context // ctx is deliver ctx
CheckCtx sdk.Context
QueryHelper *baseapp.QueryServiceTestHelper
TestAccs []sdk.AccAddress
App *MigalooApp
Ctx sdk.Context // ctx is deliver ctx
CheckCtx sdk.Context
QueryHelper *baseapp.QueryServiceTestHelper
TestAccs []sdk.AccAddress
StakingHelper *stakinghelper.Helper
}

func (s *KeeperTestHelper) Setup(_ *testing.T, chainID string) {

Check warning on line 59 in app/test_helpers.go

View workflow job for this annotation

GitHub Actions / lint

unused-parameter: parameter 'chainID' seems to be unused, consider removing or renaming it as _ (revive)
s.App = SetupApp(s.T())
s.Ctx = s.App.BaseApp.NewContext(false, tmproto.Header{Height: 1, ChainID: chainID, Time: time.Now().UTC()})
s.CheckCtx = s.App.BaseApp.NewContext(true, tmproto.Header{Height: 1, ChainID: chainID, Time: time.Now().UTC()})
t := s.T()
s.App = SetupApp(t)
s.Ctx = s.App.BaseApp.NewContext(false, tdmtypes.Header{Height: 1, ChainID: "test-1", Time: time.Now().UTC()})
s.QueryHelper = &baseapp.QueryServiceTestHelper{
GRPCQueryRouter: s.App.GRPCQueryRouter(),
Ctx: s.Ctx,
}
s.TestAccs = CreateRandomAccounts(3)

s.TestAccs = s.RandomAccountAddresses(3)
s.StakingHelper = stakinghelper.NewHelper(s.Suite.T(), s.Ctx, s.App.StakingKeeper)
s.StakingHelper.Denom = "uwhale"
}

// DefaultConsensusParams defines the default Tendermint consensus params used
Expand Down Expand Up @@ -253,3 +268,177 @@ type EmptyBaseAppOptions struct{}
func (ao EmptyBaseAppOptions) Get(_ string) interface{} {
return nil
}

// CreateTestContext creates a test context.
func (s *KeeperTestHelper) Commit() {
oldHeight := s.Ctx.BlockHeight()
oldHeader := s.Ctx.BlockHeader()
s.App.Commit()
newHeader := tdmtypes.Header{Height: oldHeight + 1, ChainID: "testing", Time: oldHeader.Time.Add(time.Second)}
s.App.BeginBlock(abci.RequestBeginBlock{Header: newHeader})
s.Ctx = s.App.NewContext(false, newHeader)
}

// FundModuleAcc funds target modules with specified amount.
func (s *KeeperTestHelper) FundModuleAcc(moduleName string, amounts sdk.Coins) {
err := banktestutil.FundModuleAccount(s.App.BankKeeper, s.Ctx, moduleName, amounts)
s.Require().NoError(err)
}

func (s *KeeperTestHelper) MintCoins(coins sdk.Coins) {
err := s.App.BankKeeper.MintCoins(s.Ctx, minttypes.ModuleName, coins)
s.Require().NoError(err)
}

// SetupValidator sets up a validator and returns the ValAddress.
func (s *KeeperTestHelper) SetupValidator(bondStatus stakingtypes.BondStatus) sdk.ValAddress {
valPriv := secp256k1.GenPrivKey()
valPub := valPriv.PubKey()
valAddr := sdk.ValAddress(valPub.Address())
bondDenom := s.App.StakingKeeper.GetParams(s.Ctx).BondDenom
selfBond := sdk.NewCoins(sdk.Coin{Amount: sdk.NewInt(100), Denom: bondDenom})

s.FundAcc(sdk.AccAddress(valAddr), selfBond)

msg := s.StakingHelper.CreateValidatorMsg(valAddr, valPub, selfBond[0].Amount)
res, err := s.StakingHelper.CreateValidatorWithMsg(s.Ctx, msg)
s.Require().NoError(err)
s.Require().NotNil(res)

val, found := s.App.StakingKeeper.GetValidator(s.Ctx, valAddr)
s.Require().True(found)

val = val.UpdateStatus(bondStatus)
s.App.StakingKeeper.SetValidator(s.Ctx, val)

consAddr, err := val.GetConsAddr()
s.Suite.Require().NoError(err)

signingInfo := slashingtypes.NewValidatorSigningInfo(
consAddr,
s.Ctx.BlockHeight(),
0,
time.Unix(0, 0),
false,
0,
)
s.App.SlashingKeeper.SetValidatorSigningInfo(s.Ctx, consAddr, signingInfo)

return valAddr
}

// BeginNewBlock starts a new block.
func (s *KeeperTestHelper) BeginNewBlock() {
var valAddr []byte

validators := s.App.StakingKeeper.GetAllValidators(s.Ctx)
if len(validators) >= 1 {
valAddrFancy, err := validators[0].GetConsAddr()
s.Require().NoError(err)
valAddr = valAddrFancy.Bytes()
} else {
valAddrFancy := s.SetupValidator(stakingtypes.Bonded)
validator, _ := s.App.StakingKeeper.GetValidator(s.Ctx, valAddrFancy)
valAddr2, _ := validator.GetConsAddr()
valAddr = valAddr2.Bytes()
}

s.BeginNewBlockWithProposer(valAddr)
}

// BeginNewBlockWithProposer begins a new block with a proposer.
func (s *KeeperTestHelper) BeginNewBlockWithProposer(proposer sdk.ValAddress) {
validator, found := s.App.StakingKeeper.GetValidator(s.Ctx, proposer)
s.Assert().True(found)

valConsAddr, err := validator.GetConsAddr()
s.Require().NoError(err)

valAddr := valConsAddr.Bytes()

newBlockTime := s.Ctx.BlockTime().Add(5 * time.Second)

header := tdmtypes.Header{Height: s.Ctx.BlockHeight() + 1, Time: newBlockTime}
newCtx := s.Ctx.WithBlockTime(newBlockTime).WithBlockHeight(s.Ctx.BlockHeight() + 1)
s.Ctx = newCtx
lastCommitInfo := abci.CommitInfo{
Votes: []abci.VoteInfo{{
Validator: abci.Validator{Address: valAddr, Power: 1000},
SignedLastBlock: true,
}},
Round: 0,
}
reqBeginBlock := abci.RequestBeginBlock{Header: header, LastCommitInfo: lastCommitInfo}

fmt.Println("beginning block ", s.Ctx.BlockHeight())
s.App.BeginBlocker(s.Ctx, reqBeginBlock)
}

// EndBlock ends the block.
func (s *KeeperTestHelper) EndBlock() {
reqEndBlock := abci.RequestEndBlock{Height: s.Ctx.BlockHeight()}
s.App.EndBlocker(s.Ctx, reqEndBlock)
}

// AllocateRewardsToValidator allocates reward tokens to a distribution module then allocates rewards to the validator address.
func (s *KeeperTestHelper) AllocateRewardsToValidator(valAddr sdk.ValAddress, rewardAmt math.Int) {
validator, found := s.App.StakingKeeper.GetValidator(s.Ctx, valAddr)
s.Require().True(found)

// allocate reward tokens to distribution module
coins := sdk.Coins{sdk.NewCoin(config.BaseDenom, rewardAmt)}
err := banktestutil.FundModuleAccount(s.App.BankKeeper, s.Ctx, distrtypes.ModuleName, coins)
s.Require().NoError(err)

// allocate rewards to validator
s.Ctx = s.Ctx.WithBlockHeight(s.Ctx.BlockHeight() + 1)
decTokens := sdk.DecCoins{{Denom: config.BaseDenom, Amount: sdk.NewDec(20000)}}
s.App.DistrKeeper.AllocateTokensToValidator(s.Ctx, validator, decTokens)
}

// BuildTx builds a transaction.
func (s *KeeperTestHelper) BuildTx(
txBuilder client.TxBuilder,
msgs []sdk.Msg,
sigV2 signing.SignatureV2,
memo string, txFee sdk.Coins,
gasLimit uint64,
) authsigning.Tx {
err := txBuilder.SetMsgs(msgs[0])
s.Require().NoError(err)

err = txBuilder.SetSignatures(sigV2)
s.Require().NoError(err)

txBuilder.SetMemo(memo)
txBuilder.SetFeeAmount(txFee)
txBuilder.SetGasLimit(gasLimit)

return txBuilder.GetTx()
}

func (s *KeeperTestHelper) ConfirmUpgradeSucceeded(upgradeName string, upgradeHeight int64) {
s.Ctx = s.Ctx.WithBlockHeight(upgradeHeight - 1)
plan := upgradetypes.Plan{Name: upgradeName, Height: upgradeHeight}
err := s.App.UpgradeKeeper.ScheduleUpgrade(s.Ctx, plan)
s.Require().NoError(err)
_, exists := s.App.UpgradeKeeper.GetUpgradePlan(s.Ctx)
s.Require().True(exists)

s.Ctx = s.Ctx.WithBlockHeight(upgradeHeight)
s.Require().NotPanics(func() {
beginBlockRequest := abci.RequestBeginBlock{}
s.App.BeginBlocker(s.Ctx, beginBlockRequest)
})
}

// CreateRandomAccounts is a function return a list of randomly generated AccAddresses
func CreateRandomAccounts(numAccts int) []sdk.AccAddress {
testAddrs := make([]sdk.AccAddress, numAccts)
for i := 0; i < numAccts; i++ {
pk := ed25519.GenPrivKey().PubKey()
testAddrs[i] = sdk.AccAddress(pk.Address())
}

return testAddrs
}
6 changes: 5 additions & 1 deletion app/upgrades/v4_1_0/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ package v4

// UpgradeName defines the on-chain upgrade name for the Migaloo v3.0.2 upgrade.
// this upgrade includes the fix for pfm
const UpgradeName = "v4.1.0"
const (
UpgradeName = "v4.1.0"
NotionalMultisigVestingAccount = "migaloo1alga5e8vr6ccr9yrg0kgxevpt5xgmgrvqgujs6"
NewNotionalMultisigVestingAccount = "migaloo1tx6f2hetpd9uhveja26kr074496hzk2zzqhsh0"
)
35 changes: 35 additions & 0 deletions app/upgrades/v4_1_0/mainnet_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package v4

import (
"encoding/json"

Check failure on line 4 in app/upgrades/v4_1_0/mainnet_account.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gofumpt`-ed (gofumpt)
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
bankKeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"

"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"
)

func CreateMainnetVestingAccount(ctx sdk.Context,
bankKeeper bankKeeper.Keeper,
accountKeeper authkeeper.AccountKeeper) (*vestingtypes.ContinuousVestingAccount, math.Int) {

Check failure on line 17 in app/upgrades/v4_1_0/mainnet_account.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gofumpt`-ed (gofumpt)
str := `{"@type":"/cosmos.vesting.v1beta1.ContinuousVestingAccount","base_vesting_account":{"base_account":{"address":"migaloo1alga5e8vr6ccr9yrg0kgxevpt5xgmgrvqgujs6","pub_key":{"@type":"/cosmos.crypto.multisig.LegacyAminoPubKey","threshold":4,"public_keys":[{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AlnzK22KrkylnvTCvZZc8eZnydtQuzCWLjJJSMFUvVHf"},{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"Aiw2Ftg+fnoHDU7M3b0VMRsI0qurXlerW0ahtfzSDZA4"},{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AvEHv+MVYRVau8FbBcJyG0ql85Tbbn7yhSA0VGmAY4ku"},{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"Az5VHWqi3zMJu1rLGcu2EgNXLLN+al4Dy/lj6UZTzTCl"},{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"Ai4GlSH3uG+joMnAFbQC3jQeHl9FPvVTlRmwIFt7d7TI"},{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"A2kAzH2bZr530jmFq/bRFrT2q8SRqdnfIebba+YIBqI1"}]},"account_number":46,"sequence":27},"original_vesting":[{"denom":"uwhale","amount":"22165200000000"}],"delegated_free":[{"denom":"uwhale","amount":"443382497453"}],"delegated_vesting":[{"denom":"uwhale","amount":"22129422502547"}],"end_time":1770994800},"start_time":1676300400}`

var acc vestingtypes.ContinuousVestingAccount
if err := json.Unmarshal([]byte(str), &acc); err != nil {
panic(err)
}

vesting := GetVestingCoin(ctx, &acc)

err := banktestutil.FundAccount(bankKeeper, ctx, acc.BaseAccount.GetAddress(),
acc.GetOriginalVesting())
if err != nil {
panic(err)
}

accountKeeper.SetAccount(ctx, &acc)
return &acc, vesting
}
Loading

0 comments on commit 0c4534e

Please sign in to comment.