From 4180101ab08e4d507f13d2398c5a3ed9d2fbbf22 Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Mon, 2 Jan 2023 12:52:45 +0400 Subject: [PATCH] Release/v1.1.0 (#272) * ics-escrow module account added * fixed user withdraw test cases * improved fix * removed codecov secret * fixes zero intent scenario (#267) * docker gh-action and pr-template (#268) * add tg-271 test script * emit error on receipt of Acknowledgement_error * remove pre v1.0.0 upgrade handlers * remove burn permissions from pr and mint module accounts * add more verbose errors to failed tx responses * x/mint poolincentives should go to airdrop module account * remove BurnCoins from x/pr expectedkeepers as this was only required during development * add rr softcap * add upgrade handler for chain restart at height 115000; removes cosmoshub-4 registered zone, closes ICA channels, defers epochs until 4/1 Co-authored-by: Ajaz Ahmed Ansari --- .github/workflows/buildtest.yaml | 1 - CHANGELOG.md | 25 +- app/app.go | 33 +- app/upgrades.go | 350 +-------------- scripts/tg271/TG-271-onboarding.sh | 416 ++++++++++++++++++ scripts/tg271/docker-compose.yml | 87 ++++ scripts/tg271/hermes.toml | 68 +++ scripts/tg271/wallets.sh | 19 + scripts/vars.sh | 63 +-- x/interchainstaking/keeper/abci.go | 6 + x/interchainstaking/keeper/hooks.go | 11 +- .../keeper/ibc_packet_handlers.go | 33 +- .../keeper/ibc_packet_handlers_test.go | 10 +- x/interchainstaking/keeper/intent.go | 16 +- x/interchainstaking/keeper/intent_test.go | 30 ++ x/interchainstaking/keeper/keeper.go | 40 +- x/interchainstaking/keeper/keeper_test.go | 3 +- x/interchainstaking/keeper/msg_server.go | 2 +- x/interchainstaking/keeper/msg_server_test.go | 1 - .../keeper/v1_1_upgrade_handler.go | 83 ++++ .../keeper/v1_1_upgrade_handler_test.go | 99 +++++ x/interchainstaking/types/keys.go | 3 +- x/mint/keeper/keeper.go | 9 +- .../types/expected_keepers.go | 2 - 24 files changed, 958 insertions(+), 452 deletions(-) create mode 100755 scripts/tg271/TG-271-onboarding.sh create mode 100644 scripts/tg271/docker-compose.yml create mode 100644 scripts/tg271/hermes.toml create mode 100644 scripts/tg271/wallets.sh create mode 100644 x/interchainstaking/keeper/v1_1_upgrade_handler.go create mode 100644 x/interchainstaking/keeper/v1_1_upgrade_handler_test.go diff --git a/.github/workflows/buildtest.yaml b/.github/workflows/buildtest.yaml index 9fc07bd22..5caff3fce 100644 --- a/.github/workflows/buildtest.yaml +++ b/.github/workflows/buildtest.yaml @@ -80,7 +80,6 @@ jobs: - name: Upload coverage reports to Codecov with GitHub Action uses: codecov/codecov-action@v3 with: - token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos files: ./coverage_nogen.txt flags: unittests fail_ci_if_error: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f5593849..d3a7c524b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,21 @@ # Changelog ## Released -### v0.10.1 -- Fix signal intents pass-by-value bug -- Refactor MsgSignalIntent to fix amino (un)marshal issue -- Fix off-by-one error in epoch end client update -- Bump Cosmos-SDK to v0.46.4 -- Bump Tendermint to v0.34.23 -- Bump ibc-go to v5.1.0 -- Bump Wasmd +### v1.1.0 + +- Add escrow account to fix unbonding bug +- Filter zero intents +- Remove burn permissions from mint and participation reward accounts +- Remove pre-v1.0.0 upgrade handlers +- Improve error responses for failed redelegation/withdrawal callbacks +- Direct poolincentives to airdrop module account +- Replace redemption rate hard cap with soft cap +- Add chain restart migration to remove cosmoshub-4, close ICA channels and burn minted qAtoms + +### v1.0.0 + +- First production release +- Bump ibc-go to v5.1.0 +- Bump tendermint to v0.34.24 +- Bump cosmos-sdk to v0.46.7 diff --git a/app/app.go b/app/app.go index e3d5e3ec1..00d967985 100644 --- a/app/app.go +++ b/app/app.go @@ -206,23 +206,22 @@ var ( // module account permissions maccPerms = map[string][]string{ - authtypes.FeeCollectorName: nil, - distrtypes.ModuleName: nil, - // TODO: Remove Burner from mint - for dev/test only; - minttypes.ModuleName: {authtypes.Minter, authtypes.Burner}, - stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, - stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, - govtypes.ModuleName: {authtypes.Burner}, - ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, - icatypes.ModuleName: nil, - claimsmanagertypes.ModuleName: nil, - interchainstakingtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, - interchainquerytypes.ModuleName: nil, - // TODO: Remove Burner from participationrewards - for dev/test only; - participationrewardstypes.ModuleName: {authtypes.Burner}, - airdroptypes.ModuleName: nil, - wasm.ModuleName: {authtypes.Burner}, - tokenfactorytypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + authtypes.FeeCollectorName: nil, + distrtypes.ModuleName: nil, + minttypes.ModuleName: {authtypes.Minter}, + stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, + stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, + govtypes.ModuleName: {authtypes.Burner}, + ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + icatypes.ModuleName: nil, + claimsmanagertypes.ModuleName: nil, + interchainstakingtypes.ModuleName: {authtypes.Minter}, + interchainstakingtypes.EscrowModuleAccount: {authtypes.Burner}, + interchainquerytypes.ModuleName: nil, + participationrewardstypes.ModuleName: nil, + airdroptypes.ModuleName: nil, + wasm.ModuleName: {authtypes.Burner}, + tokenfactorytypes.ModuleName: {authtypes.Minter, authtypes.Burner}, } // module accounts that are allowed to receive tokens diff --git a/app/upgrades.go b/app/upgrades.go index e92f44095..a78638fbe 100644 --- a/app/upgrades.go +++ b/app/upgrades.go @@ -2,44 +2,21 @@ package app import ( "fmt" - "time" storetypes "github.com/cosmos/cosmos-sdk/store/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" - claimsmanagertypes "github.com/ingenuity-build/quicksilver/x/claimsmanager/types" - icstypes "github.com/ingenuity-build/quicksilver/x/interchainstaking/types" ) // upgrade name consts: vMMmmppUpgradeName (M=Major, m=minor, p=patch) const ( - v001000UpgradeName = "v0.10.0" - v001001UpgradeName = "v0.10.1" - v001002UpgradeName = "v0.10.2" - v001003UpgradeName = "v0.10.3" - v001004UpgradeName = "v0.10.4" - v001005UpgradeName = "v0.10.5" - v001006UpgradeName = "v0.10.6" - v001007UpgradeName = "v0.10.7" - v001008UpgradeName = "v0.10.8" - - InnuendoChainID = "innuendo-3" - Innuendo2ChainID = "innuendo-4" - DevnetChainID = "quicktest-1" + ProductionChainID = "quicksilver-1" + InnuendoChainID = "innuendo-3" + Innuendo2ChainID = "innuendo-4" + DevnetChainID = "quicktest-1" ) func setUpgradeHandlers(app *Quicksilver) { - app.UpgradeKeeper.SetUpgradeHandler(v001000UpgradeName, getv001000Upgrade(app)) - app.UpgradeKeeper.SetUpgradeHandler(v001001UpgradeName, getv001001Upgrade(app)) - app.UpgradeKeeper.SetUpgradeHandler(v001002UpgradeName, getv001002Upgrade(app)) - app.UpgradeKeeper.SetUpgradeHandler(v001003UpgradeName, getv001003Upgrade(app)) - app.UpgradeKeeper.SetUpgradeHandler(v001004UpgradeName, getv001004Upgrade(app)) - app.UpgradeKeeper.SetUpgradeHandler(v001005UpgradeName, getv001005Upgrade(app)) - app.UpgradeKeeper.SetUpgradeHandler(v001006UpgradeName, getv001006Upgrade(app)) - app.UpgradeKeeper.SetUpgradeHandler(v001007UpgradeName, getv001007Upgrade(app)) - app.UpgradeKeeper.SetUpgradeHandler(v001008UpgradeName, getv001008Upgrade(app)) + // app.UpgradeKeeper.SetUpgradeHandler(v001000UpgradeName, getv001000Upgrade(app)) // When a planned update height is reached, the old binary will panic // writing on disk the height and name of the update that triggered it @@ -55,12 +32,12 @@ func setUpgradeHandlers(app *Quicksilver) { var storeUpgrades *storetypes.StoreUpgrades - switch upgradeInfo.Name { - case v001000UpgradeName: + switch upgradeInfo.Name { //nolint:gocritic + // case v001000UpgradeName: - storeUpgrades = &storetypes.StoreUpgrades{ - Added: []string{claimsmanagertypes.ModuleName}, - } + // storeUpgrades = &storetypes.StoreUpgrades{ + // Added: []string{claimsmanagertypes.ModuleName}, + // } default: // no-op } @@ -69,310 +46,3 @@ func setUpgradeHandlers(app *Quicksilver) { app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, storeUpgrades)) } } - -func getv001000Upgrade(app *Quicksilver) upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.0; no state transitions to apply.") - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - } -} - -func getv001001Upgrade(app *Quicksilver) upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.1; no state transitions to apply.") - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - } -} - -func getv001002Upgrade(app *Quicksilver) upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - switch ctx.ChainID() { - case "quicktest-1": // devnet - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.2; reinstating queries for quickosmo-1.") - - // deposit - zone, _ := app.InterchainstakingKeeper.GetZone(ctx, "quickosmo-1") - balanceQuery := banktypes.QueryAllBalancesRequest{Address: zone.DepositAddress.Address} - bz, _ := app.InterchainstakingKeeper.GetCodec().Marshal(&balanceQuery) - - app.InterchainstakingKeeper.ICQKeeper.MakeRequest( - ctx, - zone.ConnectionId, - zone.ChainId, - "cosmos.bank.v1beta1.Query/AllBalances", - bz, - sdk.NewInt(int64(app.InterchainstakingKeeper.GetParam(ctx, icstypes.KeyDepositInterval))), - icstypes.ModuleName, - "allbalances", - 0, - ) - - app.UpgradeKeeper.Logger(ctx).Info("state transitions complete.") - - case InnuendoChainID: - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.2; removing osmo-test-4 zone.") - app.InterchainstakingKeeper.DeleteZone(ctx, "osmo-test-4") - default: - // also do nothing - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.2; nothing to do.") - } - - app.InterchainQueryKeeper.Logger(ctx).Info("removing legacy perfbalance queries.") - - for _, query := range app.InterchainQueryKeeper.AllQueries(ctx) { - if query.CallbackId == "perfbalance" && query.Period.Equal(sdk.NewInt(-1)) { - app.InterchainQueryKeeper.DeleteQuery(ctx, query.Id) - app.InterchainQueryKeeper.Logger(ctx).Info("removed query", "id", query.Id, "chain", query.ChainId) - } - } - - app.InterchainQueryKeeper.Logger(ctx).Info("emitting v2 periodic perfbalance queries.") - - for _, zone := range app.InterchainstakingKeeper.AllZones(ctx) { - zone := zone - if err := app.InterchainstakingKeeper.EmitPerformanceBalanceQuery(ctx, &zone); err != nil { - panic(err) - } - } - - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - } -} - -func getv001003Upgrade(app *Quicksilver) upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - switch ctx.ChainID() { - case InnuendoChainID: - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.3; removing defunct zones.") - app.InterchainstakingKeeper.DeleteZone(ctx, "bitcanna-dev-5") - app.InterchainstakingKeeper.DeleteZone(ctx, "fauxgaia-1") - app.InterchainstakingKeeper.DeleteZone(ctx, "uni-5") - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.3; removing queries for defunct zones.") - for _, query := range app.InterchainQueryKeeper.AllQueries(ctx) { - if query.ChainId == "bitcanna-dev-5" || query.ChainId == "fauxgaia-1" || query.ChainId == "uni-5" { - app.InterchainQueryKeeper.DeleteQuery(ctx, query.Id) - app.InterchainQueryKeeper.Logger(ctx).Info("removed query", "id", query.Id, "chain", query.ChainId) - } - } - - default: - // also do nothing - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.3; nothing to do.") - } - - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - } -} - -func getv001004Upgrade(app *Quicksilver) upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - switch ctx.ChainID() { - case InnuendoChainID: - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.4; removing withdrawal records for previously removed zones.") - app.InterchainstakingKeeper.IteratePrefixedWithdrawalRecords(ctx, []byte("fauxgaia-1"), func(_ int64, record icstypes.WithdrawalRecord) bool { - app.InterchainstakingKeeper.DeleteWithdrawalRecord(ctx, "fauxgaia-1", record.Txhash, record.Status) - return false - }) - - app.InterchainstakingKeeper.IteratePrefixedWithdrawalRecords(ctx, []byte("bitcanna-dev-5"), func(_ int64, record icstypes.WithdrawalRecord) bool { - app.InterchainstakingKeeper.DeleteWithdrawalRecord(ctx, "bitcanna-dev-5", record.Txhash, record.Status) - return false - }) - - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.4; removing unbonding records for previously removed zones.") - app.InterchainstakingKeeper.IteratePrefixedUnbondingRecords(ctx, []byte("fauxgaia-1"), func(_ int64, record icstypes.UnbondingRecord) bool { - app.InterchainstakingKeeper.DeleteUnbondingRecord(ctx, "fauxgaia-1", record.Validator, record.EpochNumber) - return false - }) - - app.InterchainstakingKeeper.IteratePrefixedUnbondingRecords(ctx, []byte("bitcanna-dev-5"), func(_ int64, record icstypes.UnbondingRecord) bool { - app.InterchainstakingKeeper.DeleteUnbondingRecord(ctx, "bitcanna-dev-5", record.Validator, record.EpochNumber) - return false - }) - - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.4; removing delegation records for previously removed zones.") - fgZone, _ := app.InterchainstakingKeeper.GetZone(ctx, "fauxgaia-1") - app.InterchainstakingKeeper.IterateAllDelegations(ctx, &fgZone, func(record icstypes.Delegation) (stop bool) { - if err := app.InterchainstakingKeeper.RemoveDelegation(ctx, &fgZone, record); err != nil { - panic(err) - } - return false - }) - - bcZone, _ := app.InterchainstakingKeeper.GetZone(ctx, "bitcanna-dev-5") - app.InterchainstakingKeeper.IterateAllDelegations(ctx, &bcZone, func(record icstypes.Delegation) (stop bool) { - if err := app.InterchainstakingKeeper.RemoveDelegation(ctx, &bcZone, record); err != nil { - panic(err) - } - return false - }) - - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.4; tidy up withdrawal records pertaining to withdrawal for jailed validators bug.") - app.InterchainstakingKeeper.IterateWithdrawalRecords(ctx, func(_ int64, record icstypes.WithdrawalRecord) bool { - if record.Status == 3 && record.CompletionTime.String() == "0001-01-01T00:00:00Z" { - app.InterchainstakingKeeper.DeleteWithdrawalRecord(ctx, record.ChainId, record.Txhash, record.Status) - // unbonding never happened here. credit burn_amount back to delegator. - if err := app.BankKeeper.SendCoinsFromModuleToAccount(ctx, icstypes.ModuleName, sdk.MustAccAddressFromBech32(record.Delegator), sdk.NewCoins(record.BurnAmount)); err != nil { - panic(err) - } - } - - if record.Status == 4 && record.CompletionTime.Before(ctx.BlockTime()) { - app.InterchainstakingKeeper.DeleteWithdrawalRecord(ctx, record.ChainId, record.Txhash, record.Status) - // unbonding completed, burn qAtoms to restore balance. - } - return false - }) - - // this is hacky as shit, but we know the surplus balance is 1100000 uatom - if err := app.BankKeeper.BurnCoins(ctx, icstypes.ModuleName, sdk.NewCoins(sdk.NewCoin("uqatom", sdk.NewInt(1100000)))); err != nil { - panic(err) - } - - app.InterchainstakingKeeper.IterateZones(ctx, func(index int64, zoneInfo icstypes.Zone) (stop bool) { - app.UpgradeKeeper.Logger(ctx).Info("re-asserting redemption rate after upgrade.") - app.InterchainstakingKeeper.UpdateRedemptionRateNoBounds(ctx, zoneInfo) - return false - }) - - default: - // also do nothing - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.4; nothing to do.") - } - - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - } -} - -func getv001005Upgrade(app *Quicksilver) upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - switch ctx.ChainID() { - case DevnetChainID: - app.InterchainstakingKeeper.IterateWithdrawalRecords(ctx, func(_ int64, record icstypes.WithdrawalRecord) bool { - if record.Status == 3 && record.CompletionTime.Equal(time.Time{}) { - app.InterchainstakingKeeper.DeleteWithdrawalRecord(ctx, record.ChainId, record.Txhash, record.Status) - // unbonding never happened here. credit burn_amount back to delegator. - fmt.Println("something happened!") - if err := app.BankKeeper.SendCoinsFromModuleToAccount(ctx, icstypes.ModuleName, sdk.MustAccAddressFromBech32(record.Delegator), sdk.NewCoins(record.BurnAmount)); err != nil { - fmt.Println("error", err) // don't actually fail here. - } - } - return false - }) - icsModule := app.AccountKeeper.GetModuleAddress(icstypes.ModuleName) - icsModuleBalances := app.BankKeeper.GetAllBalances(ctx, icsModule) - fmt.Println("icsmodule", icsModule.String(), icsModuleBalances) - app.InterchainstakingKeeper.IterateZones(ctx, func(index int64, zoneInfo icstypes.Zone) (stop bool) { - app.UpgradeKeeper.Logger(ctx).Info("re-asserting redemption rate after upgrade.") - app.InterchainstakingKeeper.UpdateRedemptionRateNoBounds(ctx, zoneInfo) - return false - }) - - case InnuendoChainID: - app.InterchainstakingKeeper.IterateWithdrawalRecords(ctx, func(_ int64, record icstypes.WithdrawalRecord) bool { - if record.Status == 3 && record.CompletionTime.Equal(time.Time{}) { - app.InterchainstakingKeeper.DeleteWithdrawalRecord(ctx, record.ChainId, record.Txhash, record.Status) - // unbonding never happened here. credit burn_amount back to delegator. - if err := app.BankKeeper.SendCoinsFromModuleToAccount(ctx, icstypes.ModuleName, sdk.MustAccAddressFromBech32(record.Delegator), sdk.NewCoins(record.BurnAmount)); err != nil { - fmt.Println("tried to return tokens but encountered an error", err) // don't actually fail here. - } - } - return false - }) - icsModule := app.AccountKeeper.GetModuleAddress(icstypes.ModuleName) - icsModuleBalances := app.BankKeeper.GetAllBalances(ctx, icsModule) - fmt.Println("icsmodule", icsModule.String(), icsModuleBalances) - app.InterchainstakingKeeper.IterateZones(ctx, func(index int64, zoneInfo icstypes.Zone) (stop bool) { - app.InterchainstakingKeeper.UpdateRedemptionRateNoBounds(ctx, zoneInfo) - return false - }) - default: - // no-op - } - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.5; initialising new params.") - app.InterchainstakingKeeper.MigrateParams(ctx) - app.ParticipationRewardsKeeper.MigrateParams(ctx) - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.5; complete.") - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - } -} - -func getv001006Upgrade(app *Quicksilver) upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - switch ctx.ChainID() { - case Innuendo2ChainID: - for _, record := range []icstypes.RedelegationRecord{ - {ChainId: "theta-testnet-001", EpochNumber: 4, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper10v6wvdenee8r9l6wlsphcgur2ltl8ztkfrvj9a", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 4, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper10w45kv74rqsz6sjr0u9mqp7wvhjd3gg53xc22c", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 4, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper13n6wqhq8la352je00nwq847ktp47pgknseu6kk", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 4, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper15aptdqmm7ddgtcrjvc5hs988rlrkze406p56m2", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 4, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper15h3wjtzzjw9ua8yfvytke3u9pgt8hz6wh7hys5", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 4, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper15tye9nj3cj9va0jfvm5sk6dv8h5zfqegg9eukc", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 4, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper178h4s6at5v9cd8m9n7ew3hg7k9eh0s6wptxpcn", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 4, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper17hskshytlrepzhas628uk00jvvppg7yfj3wpqz", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 4, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper183aycgtstp67r6s4vd7ts2npp2ckk4xah7rxj6", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 4, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper19j9apwhdqvjhvjuptpa7llmny77skx0k0y0whk", Amount: 1}, - } { - app.InterchainstakingKeeper.SetRedelegationRecord(ctx, record) - app.InterchainstakingKeeper.Logger(ctx).Info("Readding redelegation", "src", record.Source, "dst", record.Destination, "amount", record.Amount) - } - default: - // no-op - } - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.6; complete.") - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - } -} - -func getv001007Upgrade(app *Quicksilver) upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.7; no state transitions to apply.") - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - } -} - -func getv001008Upgrade(app *Quicksilver) upgradetypes.UpgradeHandler { - return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { - switch ctx.ChainID() { - case Innuendo2ChainID: - for _, record := range []icstypes.RedelegationRecord{ - {ChainId: "theta-testnet-001", EpochNumber: 5, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper10v6wvdenee8r9l6wlsphcgur2ltl8ztkfrvj9a", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 5, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper10w45kv74rqsz6sjr0u9mqp7wvhjd3gg53xc22c", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 5, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper13n6wqhq8la352je00nwq847ktp47pgknseu6kk", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 5, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper15aptdqmm7ddgtcrjvc5hs988rlrkze406p56m2", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 5, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper15h3wjtzzjw9ua8yfvytke3u9pgt8hz6wh7hys5", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 5, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper15tye9nj3cj9va0jfvm5sk6dv8h5zfqegg9eukc", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 5, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper178h4s6at5v9cd8m9n7ew3hg7k9eh0s6wptxpcn", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 5, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper17hskshytlrepzhas628uk00jvvppg7yfj3wpqz", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 5, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper183aycgtstp67r6s4vd7ts2npp2ckk4xah7rxj6", Amount: 1}, - {ChainId: "theta-testnet-001", EpochNumber: 5, Source: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Destination: "cosmosvaloper19j9apwhdqvjhvjuptpa7llmny77skx0k0y0whk", Amount: 1}, - - {ChainId: "theta-testnet-001", EpochNumber: 6, Source: "cosmosvaloper1zcjcj7una47tpjyl7gtmxr4x0z3q0wtt9e2mmx", Destination: "cosmosvaloper1tflk30mq5vgqjdly92kkhhq3raev2hnz6eete3", Amount: 3}, - {ChainId: "theta-testnet-001", EpochNumber: 6, Source: "cosmosvaloper1zcjcj7una47tpjyl7gtmxr4x0z3q0wtt9e2mmx", Destination: "cosmosvaloper1s3y5zjppw6ymh0h6snmnj52730weqjqph4c8n9", Amount: 1}, - - {ChainId: "uni-5", EpochNumber: 5, Source: "junovaloper1w9fllydnchng7e3mug9a6xq3dz6vmgls2mh52l", Destination: "junovaloper192p0qmgz6rsda5fdnrvd63cgyzk6y93xcn8vzu", Amount: 2}, - {ChainId: "uni-5", EpochNumber: 5, Source: "junovaloper1w9fllydnchng7e3mug9a6xq3dz6vmgls2mh52l", Destination: "junovaloper1dma7pr7fmn9fsn6n0700qxwjcm52y8rwnqh6pm", Amount: 2}, - {ChainId: "uni-5", EpochNumber: 5, Source: "junovaloper1w9fllydnchng7e3mug9a6xq3dz6vmgls2mh52l", Destination: "junovaloper1gfaavqqg79tgcmgws6ys7yvchtc3fl42zjw43l", Amount: 2}, - {ChainId: "uni-5", EpochNumber: 5, Source: "junovaloper1w9fllydnchng7e3mug9a6xq3dz6vmgls2mh52l", Destination: "junovaloper1h686kh9ajxcdcd8ss4lgenh3awyms7sl2630qu", Amount: 2}, - {ChainId: "uni-5", EpochNumber: 5, Source: "junovaloper1w9fllydnchng7e3mug9a6xq3dz6vmgls2mh52l", Destination: "junovaloper1v99tqhh55tdslznud58jkuk4sdg9m9y9xalg7v", Amount: 2}, - {ChainId: "uni-5", EpochNumber: 5, Source: "junovaloper1w9fllydnchng7e3mug9a6xq3dz6vmgls2mh52l", Destination: "junovaloper123aw4ml9e3r9yjswl3ul73gj58h77ul4nuvlek", Amount: 1}, - {ChainId: "uni-5", EpochNumber: 5, Source: "junovaloper1w9fllydnchng7e3mug9a6xq3dz6vmgls2mh52l", Destination: "junovaloper12e37vdgl2uc7kk3wu0d2qpkuwgyy7w874cyvnt", Amount: 1}, - {ChainId: "uni-5", EpochNumber: 5, Source: "junovaloper1w9fllydnchng7e3mug9a6xq3dz6vmgls2mh52l", Destination: "junovaloper12ze55c8sngsf460pa7qykfgrzpv44n3ay3w3cd", Amount: 1}, - {ChainId: "uni-5", EpochNumber: 5, Source: "junovaloper1w9fllydnchng7e3mug9a6xq3dz6vmgls2mh52l", Destination: "junovaloper13ewczawhaxdyr0x8ua3j45f9lej0ahdh5cegfj", Amount: 1}, - {ChainId: "uni-5", EpochNumber: 5, Source: "junovaloper1w9fllydnchng7e3mug9a6xq3dz6vmgls2mh52l", Destination: "junovaloper14ven7wknwm74wnsx0jquw8wmc0m9wrlkf8shjn", Amount: 1}, - - {ChainId: "uni-5", EpochNumber: 6, Source: "junovaloper1v99tqhh55tdslznud58jkuk4sdg9m9y9xalg7v", Destination: "junovaloper192p0qmgz6rsda5fdnrvd63cgyzk6y93xcn8vzu", Amount: 1}, - {ChainId: "uni-5", EpochNumber: 6, Source: "junovaloper1v99tqhh55tdslznud58jkuk4sdg9m9y9xalg7v", Destination: "junovaloper1dma7pr7fmn9fsn6n0700qxwjcm52y8rwnqh6pm", Amount: 1}, - {ChainId: "uni-5", EpochNumber: 6, Source: "junovaloper1v99tqhh55tdslznud58jkuk4sdg9m9y9xalg7v", Destination: "junovaloper1gfaavqqg79tgcmgws6ys7yvchtc3fl42zjw43l", Amount: 1}, - {ChainId: "uni-5", EpochNumber: 6, Source: "junovaloper1v99tqhh55tdslznud58jkuk4sdg9m9y9xalg7v", Destination: "junovaloper1h686kh9ajxcdcd8ss4lgenh3awyms7sl2630qu", Amount: 1}, - } { - app.InterchainstakingKeeper.SetRedelegationRecord(ctx, record) - app.InterchainstakingKeeper.Logger(ctx).Info("Readding redelegation", "src", record.Source, "dst", record.Destination, "amount", record.Amount) - } - default: - // no-op - } - app.UpgradeKeeper.Logger(ctx).Info("upgrade to v0.10.8; complete.") - return app.mm.RunMigrations(ctx, app.configurator, fromVM) - } -} diff --git a/scripts/tg271/TG-271-onboarding.sh b/scripts/tg271/TG-271-onboarding.sh new file mode 100755 index 000000000..dbfa9561d --- /dev/null +++ b/scripts/tg271/TG-271-onboarding.sh @@ -0,0 +1,416 @@ +#!/bin/bash + +THIS_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +SCRIPT_DIR=$( realpath -- "${THIS_DIR}/.." ) +export DC="-f ${THIS_DIR}/docker-compose.yml" +. ${SCRIPT_DIR}/vars.sh + +export CHAINID_1=gaia-1 + +docker-compose $DC down + +if [[ "$1" == "-r" ]]; then + #!/bin/bash + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +CHAINID_0=qstest-1 +CHAINID_1=gaia-1 + +docker-compose down + +echo "Removing previous data..." +rm -rf ./${CHAIN_DIR}/$CHAINID_0 &> /dev/null +rm -rf ./${CHAIN_DIR}/${CHAINID_0}a &> /dev/null +rm -rf ./${CHAIN_DIR}/${CHAINID_0}b &> /dev/null + +rm -rf ./${CHAIN_DIR}/$CHAINID_1 &> /dev/null +rm -rf ./${CHAIN_DIR}/${CHAINID_1}a &> /dev/null +rm -rf ./${CHAIN_DIR}/${CHAINID_1}b &> /dev/null + +rm -rf ./${CHAIN_DIR}/hermes &> /dev/null +rm -rf ./${CHAIN_DIR}/icq &> /dev/null +rm -rf ./${CHAIN_DIR}/icq2 &> /dev/null + +# Add directories for both chains, exit if an error occurs +#chain_0 +if ! mkdir -p ./${CHAIN_DIR}/$CHAINID_0 2>/dev/null; then + echo "Failed to create chain folder. Aborting..." + exit 1 +fi + +if ! mkdir -p ./${CHAIN_DIR}/${CHAINID_0}a 2>/dev/null; then + echo "Failed to create chain folder. Aborting..." + exit 1 +fi + +if ! mkdir -p ./${CHAIN_DIR}/${CHAINID_0}b 2>/dev/null; then + echo "Failed to create chain folder. Aborting..." + exit 1 +fi + +#chain_1 +if ! mkdir -p ./${CHAIN_DIR}/$CHAINID_1 2>/dev/null; then + echo "Failed to create chain folder. Aborting..." + exit 1 +fi + +if ! mkdir -p ./${CHAIN_DIR}/${CHAINID_1}a 2>/dev/null; then + echo "Failed to create chain folder. Aborting..." + exit 1 +fi + +if ! mkdir -p ./${CHAIN_DIR}/${CHAINID_1}b 2>/dev/null; then + echo "Failed to create chain folder. Aborting..." + exit 1 +fi + +#relayers +if ! mkdir -p ./${CHAIN_DIR}/hermes 2>/dev/null; then + echo "Failed to create hermes folder. Aborting..." + exit 1 +fi + +cp $THIS_DIR/hermes.toml ./${CHAIN_DIR}/hermes/config.toml + +if ! mkdir -p ./${CHAIN_DIR}/icq 2>/dev/null; then + echo "Failed to create icq folder. Aborting..." + exit 1 +fi + +cp ../config/icq.yaml ./${CHAIN_DIR}/icq/config.yaml + +echo "Initializing $CHAINID_0..." +$QS1_RUN init test --chain-id $CHAINID_0 +echo "Initializing ${CHAINID_0}a..." +$QS2_RUN init test --chain-id $CHAINID_0 +echo "Initializing ${CHAINID_0}b..." +$QS3_RUN init test --chain-id $CHAINID_0 + +echo "Initializing $CHAINID_1..." +$GAIA1_RUN init test --chain-id $CHAINID_1 +echo "Initializing ${CHAINID_1}a..." +$GAIA2_RUN init test --chain-id $CHAINID_1 +echo "Initializing ${CHAINID_1}b..." +$GAIA3_RUN init test --chain-id $CHAINID_1 + +echo "Adding genesis accounts..." +echo $VAL_MNEMONIC_1 | $QS1_RUN keys add val1 --recover --keyring-backend=test + +echo $VAL_MNEMONIC_2 | $GAIA1_RUN keys add val2 --recover --keyring-backend=test +echo $VAL_MNEMONIC_3 | $GAIA2_RUN keys add val3 --recover --keyring-backend=test +echo $VAL_MNEMONIC_4 | $GAIA3_RUN keys add val4 --recover --keyring-backend=test + +echo $VAL_MNEMONIC_6 | $QS2_RUN keys add val6 --recover --keyring-backend=test +echo $VAL_MNEMONIC_7 | $QS3_RUN keys add val7 --recover --keyring-backend=test + + +echo $DEMO_MNEMONIC_1 | $QS1_RUN keys add demowallet1 --recover --keyring-backend=test +echo $DEMO_MNEMONIC_2 | $QS1_RUN keys add demowallet2 --recover --keyring-backend=test + +echo $DEMO_MNEMONIC_2 | $GAIA1_RUN keys add demowallet2 --recover --keyring-backend=test +echo $DEMO_MNEMONIC_3 | $GAIA2_RUN keys add demowallet3 --recover --keyring-backend=test +echo $DEMO_MNEMONIC_4 | $GAIA3_RUN keys add demowallet4 --recover --keyring-backend=test + +echo $DEMO_MNEMONIC_6 | $QS2_RUN keys add demowallet6 --recover --keyring-backend=test +echo $DEMO_MNEMONIC_7 | $QS3_RUN keys add demowallet7 --recover --keyring-backend=test + +echo $RLY_MNEMONIC_1 | $QS1_RUN keys add rly1 --recover --keyring-backend=test +echo $RLY_MNEMONIC_2 | $GAIA1_RUN keys add rly2 --recover --keyring-backend=test + +## Set denoms +${SED} 's/stake/uqck/g' $(pwd)/${CHAIN_DIR}/${CHAINID_0}/config/genesis.json +${SED} 's/stake/uqck/g' $(pwd)/${CHAIN_DIR}/${CHAINID_0}a/config/genesis.json +${SED} 's/stake/uqck/g' $(pwd)/${CHAIN_DIR}/${CHAINID_0}b/config/genesis.json + +${SED} 's/stake/uatom/g' $(pwd)/${CHAIN_DIR}/${CHAINID_1}/config/genesis.json +${SED} 's/stake/uatom/g' $(pwd)/${CHAIN_DIR}/${CHAINID_1}a/config/genesis.json +${SED} 's/stake/uatom/g' $(pwd)/${CHAIN_DIR}/${CHAINID_1}b/config/genesis.json + +VAL_ADDRESS_1=$($QS1_RUN keys show val1 --keyring-backend test -a) +DEMO_ADDRESS_1=$($QS1_RUN keys show demowallet1 --keyring-backend test -a) +RLY_ADDRESS_1=$($QS1_RUN keys show rly1 --keyring-backend test -a) + +VAL_ADDRESS_2=$($GAIA1_RUN keys show val2 --keyring-backend test -a) +DEMO_ADDRESS_2=$($GAIA1_RUN keys show demowallet2 --keyring-backend test -a) +RLY_ADDRESS_2=$($GAIA1_RUN keys show rly2 --keyring-backend test -a) + +VAL_ADDRESS_3=$($GAIA2_RUN keys show val3 --keyring-backend test -a) +DEMO_ADDRESS_3=$($GAIA2_RUN keys show demowallet3 --keyring-backend test -a) + +VAL_ADDRESS_4=$($GAIA3_RUN keys show val4 --keyring-backend test -a) +DEMO_ADDRESS_4=$($GAIA3_RUN keys show demowallet4 --keyring-backend test -a) + +VAL_VALOPER_2=$($GAIA1_RUN keys show val2 --keyring-backend test --bech=val -a) +VAL_VALOPER_3=$($GAIA2_RUN keys show val3 --keyring-backend test --bech=val -a) +VAL_VALOPER_4=$($GAIA3_RUN keys show val4 --keyring-backend test --bech=val -a) + +VAL_ADDRESS_6=$($QS2_RUN keys show val6 --keyring-backend test -a) +DEMO_ADDRESS_6=$($QS2_RUN keys show demowallet6 --keyring-backend test -a) + +VAL_ADDRESS_7=$($QS3_RUN keys show val7 --keyring-backend test -a) +DEMO_ADDRESS_7=$($QS3_RUN keys show demowallet7 --keyring-backend test -a) + +VAL_VALOPER_6=$($QS2_RUN keys show val6 --keyring-backend test --bech=val -a) +VAL_VALOPER_7=$($QS3_RUN keys show val7 --keyring-backend test --bech=val -a) + +$QS1_RUN add-genesis-account ${VAL_ADDRESS_1} 100000000000uqck +$QS1_RUN add-genesis-account ${DEMO_ADDRESS_1} 100000000000uqck +$QS1_RUN add-genesis-account ${RLY_ADDRESS_1} 100000000000uqck + +$QS1_RUN add-genesis-account ${VAL_ADDRESS_6} 100000000000uqck +$QS1_RUN add-genesis-account ${VAL_ADDRESS_7} 100000000000uqck +$QS1_RUN add-genesis-account ${DEMO_ADDRESS_6} 100000000000uqck +$QS1_RUN add-genesis-account ${DEMO_ADDRESS_7} 100000000000uqck + +$QS2_RUN add-genesis-account ${VAL_ADDRESS_6} 100000000000uqck +$QS3_RUN add-genesis-account ${VAL_ADDRESS_7} 100000000000uqck + +$GAIA1_RUN add-genesis-account ${VAL_ADDRESS_2} 100000000000uatom +$GAIA1_RUN add-genesis-account ${VAL_ADDRESS_3} 100000000000uatom +$GAIA1_RUN add-genesis-account ${VAL_ADDRESS_4} 100000000000uatom +$GAIA1_RUN add-genesis-account ${DEMO_ADDRESS_2} 100000000000uatom +$GAIA1_RUN add-genesis-account ${DEMO_ADDRESS_3} 100000000000uatom +$GAIA1_RUN add-genesis-account ${DEMO_ADDRESS_4} 100000000000uatom +$GAIA1_RUN add-genesis-account ${RLY_ADDRESS_2} 100000000000uatom + +$GAIA2_RUN add-genesis-account ${VAL_ADDRESS_3} 100000000000uatom +$GAIA3_RUN add-genesis-account ${VAL_ADDRESS_4} 100000000000uatom + +echo "Creating and collecting gentx..." +$QS1_RUN gentx val1 7000000000uqck --chain-id $CHAINID_0 --keyring-backend test +$QS2_RUN gentx val6 7000000000uqck --chain-id $CHAINID_0 --keyring-backend test +$QS3_RUN gentx val7 7000000000uqck --chain-id $CHAINID_0 --keyring-backend test + +$GAIA1_RUN gentx val2 7000000000uatom --commission-rate 0.33 --commission-max-rate 0.5 --commission-max-change-rate 0.1 --chain-id $CHAINID_1 --keyring-backend test +$GAIA2_RUN gentx val3 6000000000uatom --commission-rate 0.23 --commission-max-rate 0.5 --commission-max-change-rate 0.1 --chain-id $CHAINID_1 --keyring-backend test +$GAIA3_RUN gentx val4 5000000000uatom --commission-rate 0.13 --commission-max-rate 0.5 --commission-max-change-rate 0.1 --chain-id $CHAINID_1 --keyring-backend test + +cp ./${CHAIN_DIR}/${CHAINID_0}a/config/gentx/*.json ./${CHAIN_DIR}/${CHAINID_0}/config/gentx/ +cp ./${CHAIN_DIR}/${CHAINID_0}b/config/gentx/*.json ./${CHAIN_DIR}/${CHAINID_0}/config/gentx/ + +$QS1_RUN collect-gentxs + +cp ./${CHAIN_DIR}/${CHAINID_1}a/config/gentx/*.json ./${CHAIN_DIR}/${CHAINID_1}/config/gentx/ +cp ./${CHAIN_DIR}/${CHAINID_1}b/config/gentx/*.json ./${CHAIN_DIR}/${CHAINID_1}/config/gentx/ + +$GAIA1_RUN collect-gentxs + +node1=$($GAIA1_RUN tendermint show-node-id)@gaia:26656 +node2=$($GAIA2_RUN tendermint show-node-id)@gaia2:26656 +node3=$($GAIA3_RUN tendermint show-node-id)@gaia3:26656 + +node5=$($QS1_RUN tendermint show-node-id)@quicksilver:26656 +node6=$($QS2_RUN tendermint show-node-id)@quicksilver2:26656 +node7=$($QS3_RUN tendermint show-node-id)@quicksilver3:26656 + +echo "Changing defaults and ports in app.toml and config.toml files..." +${SED} -e 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ${CHAIN_DIR}/${CHAINID_0}/config/config.toml +${SED} -e 's/timeout_commit = "5s"/timeout_commit = "1s"/g' ${CHAIN_DIR}/${CHAINID_0}/config/config.toml +${SED} -e 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ${CHAIN_DIR}/${CHAINID_0}/config/config.toml +${SED} -e 's/index_all_keys = false/index_all_keys = true/g' ${CHAIN_DIR}/${CHAINID_0}/config/config.toml +${SED} -e "s/persistent_peers = \"\"/persistent_peers = \"$node6,$node7\"/g" ${CHAIN_DIR}/${CHAINID_0}b/config/config.toml +${SED} -e 's/enable = false/enable = true/g' ${CHAIN_DIR}/${CHAINID_0}/config/app.toml +${SED} -e 's/swagger = false/swagger = true/g' ${CHAIN_DIR}/${CHAINID_0}/config/app.toml + +${SED} -e 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ${CHAIN_DIR}/${CHAINID_0}a/config/config.toml +${SED} -e 's/timeout_commit = "5s"/timeout_commit = "1s"/g' ${CHAIN_DIR}/${CHAINID_0}a/config/config.toml +${SED} -e 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ${CHAIN_DIR}/${CHAINID_0}a/config/config.toml +${SED} -e 's/index_all_keys = false/index_all_keys = true/g' ${CHAIN_DIR}/${CHAINID_0}a/config/config.toml +${SED} -e "s/persistent_peers = \"\"/persistent_peers = \"$node5,$node7\"/g" ${CHAIN_DIR}/${CHAINID_0}a/config/config.toml +${SED} -e 's/enable = false/enable = true/g' ${CHAIN_DIR}/${CHAINID_0}a/config/app.toml +${SED} -e 's/swagger = false/swagger = true/g' ${CHAIN_DIR}/${CHAINID_0}a/config/app.toml + +${SED} -e 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ${CHAIN_DIR}/${CHAINID_0}b/config/config.toml +${SED} -e 's/timeout_commit = "5s"/timeout_commit = "1s"/g' ${CHAIN_DIR}/${CHAINID_0}b/config/config.toml +${SED} -e 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ${CHAIN_DIR}/${CHAINID_0}b/config/config.toml +${SED} -e 's/index_all_keys = false/index_all_keys = true/g' ${CHAIN_DIR}/${CHAINID_0}b/config/config.toml +${SED} -e "s/persistent_peers = \"\"/persistent_peers = \"$node5,$node6\"/g" ${CHAIN_DIR}/${CHAINID_0}b/config/config.toml +${SED} -e 's/enable = false/enable = true/g' ${CHAIN_DIR}/${CHAINID_0}b/config/app.toml +${SED} -e 's/swagger = false/swagger = true/g' ${CHAIN_DIR}/${CHAINID_0}b/config/app.toml + +${SED} -e 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ${CHAIN_DIR}/${CHAINID_1}/config/config.toml +${SED} -e 's/timeout_commit = "5s"/timeout_commit = "1s"/g' ${CHAIN_DIR}/${CHAINID_1}/config/config.toml +${SED} -e 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ${CHAIN_DIR}/${CHAINID_1}/config/config.toml +${SED} -e 's/index_all_keys = false/index_all_keys = true/g' ${CHAIN_DIR}/${CHAINID_1}/config/config.toml +${SED} -e "s/persistent_peers = \"\"/persistent_peers = \"$node2,$node3,$node4\"/g" ${CHAIN_DIR}/${CHAINID_1}/config/config.toml +${SED} -e 's/enable = false/enable = true/g' ${CHAIN_DIR}/${CHAINID_1}/config/app.toml +${SED} -e 's/swagger = false/swagger = true/g' ${CHAIN_DIR}/${CHAINID_1}/config/app.toml + +${SED} -e 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ${CHAIN_DIR}/${CHAINID_1}a/config/config.toml +${SED} -e 's/timeout_commit = "5s"/timeout_commit = "1s"/g' ${CHAIN_DIR}/${CHAINID_1}a/config/config.toml +${SED} -e 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ${CHAIN_DIR}/${CHAINID_1}a/config/config.toml +${SED} -e 's/index_all_keys = false/index_all_keys = true/g' ${CHAIN_DIR}/${CHAINID_1}a/config/config.toml +${SED} -e "s/persistent_peers = \"\"/persistent_peers = \"$node1,$node3,$node4\"/g" ${CHAIN_DIR}/${CHAINID_1}a/config/config.toml +${SED} -e 's/enable = false/enable = true/g' ${CHAIN_DIR}/${CHAINID_1}a/config/app.toml +${SED} -e 's/swagger = false/swagger = true/g' ${CHAIN_DIR}/${CHAINID_1}a/config/app.toml + +${SED} -e 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ${CHAIN_DIR}/${CHAINID_1}b/config/config.toml +${SED} -e 's/timeout_commit = "5s"/timeout_commit = "1s"/g' ${CHAIN_DIR}/${CHAINID_1}b/config/config.toml +${SED} -e 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ${CHAIN_DIR}/${CHAINID_1}b/config/config.toml +${SED} -e 's/index_all_keys = false/index_all_keys = true/g' ${CHAIN_DIR}/${CHAINID_1}b/config/config.toml +${SED} -e "s/persistent_peers = \"\"/persistent_peers = \"$node1,$node2,$node4\"/g" ${CHAIN_DIR}/${CHAINID_1}b/config/config.toml +${SED} -e 's/enable = false/enable = true/g' ${CHAIN_DIR}/${CHAINID_1}b/config/app.toml +${SED} -e 's/swagger = false/swagger = true/g' ${CHAIN_DIR}/${CHAINID_1}b/config/app.toml + +jq '.consensus_params.block.time_iota_ms = "200"' ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json > ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json.new && mv ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json{.new,} +jq '.consensus_params.block.time_iota_ms = "200"' ./${CHAIN_DIR}/${CHAINID_1}/config/genesis.json > ./${CHAIN_DIR}/${CHAINID_1}/config/genesis.json.new && mv ./${CHAIN_DIR}/${CHAINID_1}/config/genesis.json{.new,} + +## add the message types ICA should allow +jq '.app_state.interchainaccounts.host_genesis_state.params.allow_messages = ["/cosmos.bank.v1beta1.MsgSend", "/cosmos.bank.v1beta1.MsgMultiSend", "/cosmos.staking.v1beta1.MsgDelegate", "/cosmos.staking.v1beta1.MsgRedeemTokensforShares", "/cosmos.staking.v1beta1.MsgTokenizeShares", "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", "/cosmos.distribution.v1beta1.MsgSetWithdrawAddress", "/ibc.applications.transfer.v1.MsgTransfer", "/cosmos.staking.v1beta1.MsgUndelegate"]' ./${CHAIN_DIR}/${CHAINID_1}/config/genesis.json > ./${CHAIN_DIR}/${CHAINID_1}/config/genesis.json.new && mv ./${CHAIN_DIR}/${CHAINID_1}/config/genesis.json{.new,} +jq '.app.state.mint.minter.inflation = "2.530000000000000000"' ./${CHAIN_DIR}/${CHAINID_1}/config/genesis.json > ./${CHAIN_DIR}/${CHAINID_1}/config/genesis.json.new && mv ./${CHAIN_DIR}/${CHAINID_1}/config/genesis.json{.new,} +jq '.app.state.mint.params.max_inflation = "2.530000000000000000"' ./${CHAIN_DIR}/${CHAINID_1}/config/genesis.json > ./${CHAIN_DIR}/${CHAINID_1}/config/genesis.json.new && mv ./${CHAIN_DIR}/${CHAINID_1}/config/genesis.json{.new,} +jq '.app_state.staking.params.unbonding_time = "300s"' ./${CHAIN_DIR}/${CHAINID_1}/config/genesis.json > ./${CHAIN_DIR}/${CHAINID_1}/config/genesis.json.new && mv ./${CHAIN_DIR}/${CHAINID_1}/config/genesis.json{.new,} +cp ./${CHAIN_DIR}/${CHAINID_1}{,a}/config/genesis.json +cp ./${CHAIN_DIR}/${CHAINID_1}{,b}/config/genesis.json + +## set the 'epoch' epoch to 5m interval +jq '.app_state.epochs.epochs = [{"identifier": "epoch","start_time": "0001-01-01T00:00:00Z","duration": "240s","current_epoch": "0","current_epoch_start_time": "0001-01-01T00:00:00Z","epoch_counting_started": false,"current_epoch_start_height": "0"}]' ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json > ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json.new && mv ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json{.new,} +jq '.app_state.interchainstaking.params.deposit_interval = 25' ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json > ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json.new && mv ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json{.new,} +jq '.app_state.mint.params.epoch_identifier = "epoch"' ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json > ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json.new && mv ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json{.new,} +jq '.app_state.gov.deposit_params.min_deposit = [{"denom": "uqck", "amount": "100"}]' ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json > ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json.new && mv ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json{.new,} +jq '.app_state.gov.deposit_params.max_deposit_period = "10s"' ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json > ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json.new && mv ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json{.new,} +jq '.app_state.gov.voting_params.voting_period = "10s"' ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json > ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json.new && mv ./${CHAIN_DIR}/${CHAINID_0}/config/genesis.json{.new,} + +cp ./${CHAIN_DIR}/${CHAINID_0}{,a}/config/genesis.json +cp ./${CHAIN_DIR}/${CHAINID_0}{,b}/config/genesis.json + +rm -rf ${CHAIN_DIR}/backup +mkdir ${CHAIN_DIR}/backup +cp -fr ${CHAIN_DIR}/${CHAINID_0} ${CHAIN_DIR}/backup/${CHAINID_0} +cp -fr ${CHAIN_DIR}/${CHAINID_0}a ${CHAIN_DIR}/backup/${CHAINID_0}a +cp -fr ${CHAIN_DIR}/${CHAINID_0}b ${CHAIN_DIR}/backup/${CHAINID_0}b +cp -fr ${CHAIN_DIR}/${CHAINID_1} ${CHAIN_DIR}/backup/${CHAINID_1} +cp -fr ${CHAIN_DIR}/${CHAINID_1}a ${CHAIN_DIR}/backup/${CHAINID_1}a +cp -fr ${CHAIN_DIR}/${CHAINID_1}b ${CHAIN_DIR}/backup/${CHAINID_1}b + +docker-compose down + +cat << EOF > ${THIS_DIR}/wallets.sh +VAL_ADDRESS_1=$VAL_ADDRESS_1 +DEMO_ADDRESS_1=$DEMO_ADDRESS_1 +RLY_ADDRESS_1=$RLY_ADDRESS_1 +VAL_ADDRESS_6=$VAL_ADDRESS_6 +DEMO_ADDRESS_6=$DEMO_ADDRESS_6 +VAL_ADDRESS_7=$VAL_ADDRESS_7 +DEMO_ADDRESS_7=$DEMO_ADDRESS_7 +VAL_ADDRESS_2=$VAL_ADDRESS_2 +DEMO_ADDRESS_2=$DEMO_ADDRESS_2 +RLY_ADDRESS_2=$RLY_ADDRESS_2 +VAL_ADDRESS_3=$VAL_ADDRESS_3 +DEMO_ADDRESS_3=$DEMO_ADDRESS_3 + +VAL_ADDRESS_4=$VAL_ADDRESS_4 +DEMO_ADDRESS_4=$DEMO_ADDRESS_4 + +VAL_VALOPER_2=$VAL_VALOPER_2 +VAL_VALOPER_3=$VAL_VALOPER_3 +VAL_VALOPER_4=$VAL_VALOPER_4 +EOF + +else + echo "Copying previously generated state." + rm -rf ${CHAIN_DIR}/${CHAINID_0} + rm -rf ${CHAIN_DIR}/${CHAINID_0}a + rm -rf ${CHAIN_DIR}/${CHAINID_0}b + rm -rf ${CHAIN_DIR}/${CHAINID_1} + rm -rf ${CHAIN_DIR}/${CHAINID_1}a + rm -rf ${CHAIN_DIR}/${CHAINID_1}b + rm -rf ${CHAIN_DIR}/hermes &> /dev/null + rm -rf ${CHAIN_DIR}/icq &> /dev/null + rm -rf ${CHAIN_DIR}/rly &> /dev/null + + TIME=${TIME} + jq ".genesis_time = \"$TIME\"" ./${CHAIN_DIR}/backup/${CHAINID_0}/config/genesis.json > ./${CHAIN_DIR}/backup/${CHAINID_0}/config/genesis.json.new && mv ./${CHAIN_DIR}/backup/${CHAINID_0}/config/genesis.json{.new,} + jq ".genesis_time = \"$TIME\"" ./${CHAIN_DIR}/backup/${CHAINID_0}a/config/genesis.json > ./${CHAIN_DIR}/backup/${CHAINID_0}a/config/genesis.json.new && mv ./${CHAIN_DIR}/backup/${CHAINID_0}a/config/genesis.json{.new,} + jq ".genesis_time = \"$TIME\"" ./${CHAIN_DIR}/backup/${CHAINID_0}b/config/genesis.json > ./${CHAIN_DIR}/backup/${CHAINID_0}b/config/genesis.json.new && mv ./${CHAIN_DIR}/backup/${CHAINID_0}b/config/genesis.json{.new,} + + cp -fr ${CHAIN_DIR}/backup/${CHAINID_0} ${CHAIN_DIR}/${CHAINID_0} + cp -fr ${CHAIN_DIR}/backup/${CHAINID_0}a ${CHAIN_DIR}/${CHAINID_0}a + cp -fr ${CHAIN_DIR}/backup/${CHAINID_0}b ${CHAIN_DIR}/${CHAINID_0}b + cp -fr ${CHAIN_DIR}/backup/${CHAINID_1} ${CHAIN_DIR}/${CHAINID_1} + cp -fr ${CHAIN_DIR}/backup/${CHAINID_1}a ${CHAIN_DIR}/${CHAINID_1}a + cp -fr ${CHAIN_DIR}/backup/${CHAINID_1}b ${CHAIN_DIR}/${CHAINID_1}b + mkdir ${CHAIN_DIR}/hermes ${CHAIN_DIR}/icq + cp ../config/icq.yaml ./${CHAIN_DIR}/icq/config.yaml + cp ./hermes.toml ./${CHAIN_DIR}/hermes/config.toml + cp -rf ../config/rly ./${CHAIN_DIR}/rly +fi + +source ${THIS_DIR}/wallets.sh + +############################################################################################################################# + +docker-compose $DC up --force-recreate -d quicksilver quicksilver2 quicksilver3 gaia gaia2 gaia3 +echo "Chains created" +sleep 3 +echo "Restoring keys" +echo "$RLY_MNEMONIC_1" | $HERMES_RUN keys add --mnemonic-file /dev/fd/0 --chain $CHAINID_0 +echo "$RLY_MNEMONIC_2" | $HERMES_RUN keys add --mnemonic-file /dev/fd/0 --chain $CHAINID_1 +sleep 3 +#echo "Creating IBC connection" +echo "Creating connection & transfer channel" +$HERMES_RUN create channel --a-chain $CHAINID_0 --b-chain $CHAINID_1 --a-port transfer --b-port transfer --new-client-connection --yes +#$HERMES_RUN create connection --a-chain $CHAINID_0 --b-chain $CHAINID_1 +#$HERMES_RUN create channel --port-a transfer --port-b transfer $CHAINID_0 connection-0 +echo "Tranfer channel created" +docker-compose $DC up --force-recreate -d hermes +RLY_ADDRESS_3=$($RLY_RUN keys show qstest-1 testkey) +RLY_ADDRESS_4=$($RLY_RUN keys show lstest-1 testkey) + +## TG-271 - send to delegate account before we register it! +$GAIA1_EXEC tx bank send val2 cosmos1j5u9y5gm95f4sudpupu8zv7jqlnh8wzlnn88w7upx5exj4ekr0fsmx3jup 1uatom --chain-id $CHAINID_1 -y --keyring-backend=test -b block +sleep 3 +$QS1_EXEC tx bank send val1 $RLY_ADDRESS_3 1000uqck --chain-id $CHAINID_0 -y --keyring-backend=test +$GAIA1_EXEC tx bank send val2 $RLY_ADDRESS_4 1000uatom --chain-id $CHAINID_1 -y --keyring-backend=test + +docker-compose $DC up --force-recreate -d relayer + +rm -rf ./icq/keys +echo "Launch and configure interchain query daemon" + +ICQ_ADDRESS_1=$($ICQ_RUN keys add test --chain qstest-1 | jq .address -r) +ICQ_ADDRESS_2=$($ICQ_RUN keys add test --chain lstest-1 | jq .address -r) + +sleep 3 + +$QS1_EXEC tx bank send val1 $ICQ_ADDRESS_1 1000uqck --chain-id $CHAINID_0 -y --keyring-backend=test +$GAIA1_EXEC tx bank send val2 $ICQ_ADDRESS_2 1000uatom --chain-id $CHAINID_1 -y --keyring-backend=test + +docker-compose $DC up --force-recreate -d icq + +#echo "Register $CHAINID_1 on quicksilver..." +cat $THIS_DIR/../registerzone.json | jq . -c | $QS1_EXEC tx gov submit-proposal /dev/fd/0 --from demowallet1 --chain-id $CHAINID_0 --gas 2000000 -y --keyring-backend=test +sleep 3 +$QS1_EXEC tx gov vote 1 yes --from val1 --chain-id $CHAINID_0 -y --keyring-backend=test +$QS2_EXEC tx gov vote 1 yes --from val6 --chain-id $CHAINID_0 -y --keyring-backend=test +$QS3_EXEC tx gov vote 1 yes --from val7 --chain-id $CHAINID_0 -y --keyring-backend=test +sleep 10 +docker-compose $DC restart hermes +sleep 5 + +sleep 3 +DEPOSIT_ACCOUNT=$($QS1_EXEC q interchainstaking zones --output=json | jq .zones[0].deposit_address.address -r) +while [[ "$DEPOSIT_ACCOUNT" == "null" ]]; do + sleep 2 + DEPOSIT_ACCOUNT=$($QS1_EXEC q interchainstaking zones --output=json | jq .zones[0].deposit_address.address -r) +done + +PERFORMANCE_ACCOUNT=$($QS1_EXEC q interchainstaking zones --output=json | jq .zones[0].performance_address.address -r) +while [[ "$PERFORMANCE_ACCOUNT" == "null" ]]; do + sleep 2 + PERFORMANCE_ACCOUNT=$($QS1_EXEC q interchainstaking zones --output=json | jq .zones[0].performance_address.address -r) +done + +$GAIA1_EXEC tx bank send val2 $PERFORMANCE_ACCOUNT 40000uatom --chain-id $CHAINID_1 -y --keyring-backend=test + +sleep 3 + +$GAIA1_EXEC tx bank send demowallet2 $DEPOSIT_ACCOUNT 333333uatom --chain-id $CHAINID_1 -y --keyring-backend=test +sleep 5 +$GAIA1_EXEC tx bank send demowallet2 $DEPOSIT_ACCOUNT 20000000uatom --chain-id $CHAINID_1 -y --keyring-backend=test --note MgTUzEjWVVYoDZBarqFL1akb38mxlgTsqdZ/sFxTJBNf+tv6rtckvn3T +sleep 5 +$GAIA1_EXEC tx bank send demowallet2 $DEPOSIT_ACCOUNT 33000000uatom --chain-id $CHAINID_1 -y --keyring-backend=test +sleep 5 + + diff --git a/scripts/tg271/docker-compose.yml b/scripts/tg271/docker-compose.yml new file mode 100644 index 000000000..290b01d78 --- /dev/null +++ b/scripts/tg271/docker-compose.yml @@ -0,0 +1,87 @@ +version: '3.8' +services: + quicksilver: + image: quicksilverzone/quicksilver:v1.0.0-10-gddbec29 + hostname: quicksilver + volumes: + - ./data/qstest-1:/quicksilver/.quicksilverd + build: + context: . + dockerfile: Dockerfile + ports: + - 26657:26657 + - 1317:1317 + quicksilver2: + image: quicksilverzone/quicksilver:v1.0.0-10-gddbec29 + hostname: quicksilver2 + volumes: + - ./data/qstest-1a:/quicksilver/.quicksilverd + build: + context: . + dockerfile: Dockerfile + quicksilver3: + image: quicksilverzone/quicksilver:v1.0.0-10-gddbec29 + hostname: quicksilver3 + volumes: + - ./data/qstest-1b:/quicksilver/.quicksilverd + build: + context: . + dockerfile: Dockerfile + gaia: + image: quicksilverzone/gaia:v7.1.0-alpine + hostname: gaia + volumes: + - ./data/gaia-1:/gaia/.gaia + command: + - gaiad + - start + ports: + - 27657:26657 + - 23137:1317 + gaia2: + image: quicksilverzone/gaia:v7.1.0-alpine + hostname: gaia + volumes: + - ./data/gaia-1a:/gaia/.gaia + command: + - gaiad + - start + gaia3: + image: quicksilverzone/gaia:v7.1.0-alpine + hostname: gaia + volumes: + - ./data/gaia-1b:/gaia/.gaia + command: + - gaiad + - start + + hermes: + image: quicksilverzone/hermes:v1.2.0 + hostname: hermes + volumes: + - ./data/hermes:/hermes/.hermes + command: + - hermes + - start + restart: always + icq: + image: quicksilverzone/interchain-queries:v0.7.7 + volumes: + - ./data/icq:/icq/.icq + command: + - interchain-queries + - run + restart: always + relayer: + image: quicksilverzone/relayer:v2.1.1 + volumes: + - ./data/rly:/rly/.relayer + command: + - rly + - start + - demo + #- -p + #- events + #- -b + #- "100" + restart: always diff --git a/scripts/tg271/hermes.toml b/scripts/tg271/hermes.toml new file mode 100644 index 000000000..599e42686 --- /dev/null +++ b/scripts/tg271/hermes.toml @@ -0,0 +1,68 @@ +[mode] +[mode.clients] +enabled = true +refresh = true +misbehaviour = true + +[mode.connections] +enabled = true + +[mode.channels] +enabled = true + +[mode.packets] +enabled = true +clear_interval = 100 +clear_on_start = true + +[rest] +enabled = true +host = '0.0.0.0' +port = 3000 + +[telemetry] +enabled = false +host = '0.0.0.0' +port = 3001 + +[[chains]] +id = 'qstest-1' +rpc_addr = 'http://quicksilver:26657' +grpc_addr = 'http://quicksilver:9090' +websocket_addr = 'ws://quicksilver:26657/websocket' +rpc_timeout = '10s' +account_prefix = 'quick' +key_name = 'testkey' +store_prefix = 'ibc' +default_gas = 100000 +max_gas = 5000000 +gas_price = { price = 0.000000, denom = 'uqck' } +gas_multiplier = 1.5 +max_msg_num = 30 +max_tx_size = 2097152 +clock_drift = '5s' +max_block_time = '10s' +trusting_period = '3minutes' +trust_threshold = { numerator = '1', denominator = '3' } +address_type = { derivation = 'cosmos' } + +[[chains]] +id = 'gaia-1' +rpc_addr = 'http://gaia:26657' +grpc_addr = 'http://gaia:9090' +websocket_addr = 'ws://gaia:26657/websocket' +rpc_timeout = '10s' +account_prefix = 'cosmos' +key_name = 'testkey' +store_prefix = 'ibc' +default_gas = 100000 +max_gas = 3000000 +gas_price = { price = 0.000, denom = 'uatom' } +gas_multiplier = 1.5 +max_msg_num = 30 +max_tx_size = 2097152 +clock_drift = '5s' +max_block_time = '10s' +trusting_period = '3minutes' +trust_threshold = { numerator = '1', denominator = '3' } +address_type = { derivation = 'cosmos' } diff --git a/scripts/tg271/wallets.sh b/scripts/tg271/wallets.sh new file mode 100644 index 000000000..bb016363d --- /dev/null +++ b/scripts/tg271/wallets.sh @@ -0,0 +1,19 @@ +VAL_ADDRESS_1=quick18hl5c9xn5dze2g50uaw0l2mr02ew57zkpdc37j +DEMO_ADDRESS_1=quick1m9l358xunhhwds0568za49mzhvuxx9uxgaye9l +RLY_ADDRESS_1=quick1mjk79fjjgpplak5wq838w0yd982gzkyfgjlvyf +VAL_ADDRESS_6=quick157m90t8f98xt0q7xnfax47lhnyxwmr30krjg9x +DEMO_ADDRESS_6=quick1ervxcpt8xfhjj72y6lweg9d8j4u9a23lakpz7t +VAL_ADDRESS_7=quick14lznr7kt0r2thcuv5qap9q5n6mkth7rw9nel4a +DEMO_ADDRESS_7=quick1nj0gl8ywa46zcpcuvvyu3ya9ht75rqjrct9pwp +VAL_ADDRESS_2=cosmos1qnk2n4nlkpw9xfqntladh74w6ujtulwn7j8za9 +DEMO_ADDRESS_2=cosmos10h9stc5v6ntgeygf5xf945njqq5h32r53uquvw +RLY_ADDRESS_2=cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs +VAL_ADDRESS_3=cosmos1qn2vcjxk24tzsrvst2h2zj744ydaljd3ppsnph +DEMO_ADDRESS_3=cosmos1l3779e2g49ganyaqqhhuchfmhnq2e5rekwh5v4 + +VAL_ADDRESS_4=cosmos16pxh2v4hr28h2gkntgfk8qgh47pfmjfhfvfw6t +DEMO_ADDRESS_4=cosmos1wfwcegpsa3v47ht0cf3cg9q9f4h4vkk88w7hrn + +VAL_VALOPER_2=cosmosvaloper1qnk2n4nlkpw9xfqntladh74w6ujtulwnmxnh3k +VAL_VALOPER_3=cosmosvaloper1qn2vcjxk24tzsrvst2h2zj744ydaljd3y4yxdy +VAL_VALOPER_4=cosmosvaloper16pxh2v4hr28h2gkntgfk8qgh47pfmjfhvcamkc diff --git a/scripts/vars.sh b/scripts/vars.sh index f1009dacf..6b4f7f76c 100755 --- a/scripts/vars.sh +++ b/scripts/vars.sh @@ -20,9 +20,6 @@ else TIME="$(date --date '-2 minutes' +%Y-%m-%dT%H:%M:00Z -u)" fi -echo $SED -echo $TIME - QS_IMAGE=quicksilverzone/quicksilver QS_VERSION=latest TZ_IMAGE=quicksilverzone/testzone @@ -35,35 +32,41 @@ CHAINID_0=qstest-1 CHAINID_1=lstest-1 CHAINID_2=lstest-2 -QS1_RUN="docker-compose --ansi never run --rm -T quicksilver quicksilverd" -QS2_RUN="docker-compose --ansi never run --rm -T quicksilver2 quicksilverd" -QS3_RUN="docker-compose --ansi never run --rm -T quicksilver3 quicksilverd" -TZ1_1_RUN="docker-compose --ansi never run --rm -T testzone1-1 icad" -TZ1_2_RUN="docker-compose --ansi never run --rm -T testzone1-2 icad" -TZ1_3_RUN="docker-compose --ansi never run --rm -T testzone1-3 icad" -TZ1_4_RUN="docker-compose --ansi never run --rm -T testzone1-4 icad" -TZ2_1_RUN="docker-compose --ansi never run --rm -T testzone2-1 osmosisd" -TZ2_2_RUN="docker-compose --ansi never run --rm -T testzone2-2 osmosisd" -TZ2_3_RUN="docker-compose --ansi never run --rm -T testzone2-3 osmosisd" -TZ2_4_RUN="docker-compose --ansi never run --rm -T testzone2-4 osmosisd" -RLY_RUN="docker-compose --ansi never run --rm -T relayer rly" -HERMES_RUN="docker-compose --ansi never run --rm -T hermes hermes" +QS1_RUN="docker-compose $DC --ansi never run --rm -T quicksilver quicksilverd" +QS2_RUN="docker-compose $DC --ansi never run --rm -T quicksilver2 quicksilverd" +QS3_RUN="docker-compose $DC --ansi never run --rm -T quicksilver3 quicksilverd" +GAIA1_RUN="docker-compose $DC --ansi never run --rm -T gaia gaiad" +GAIA2_RUN="docker-compose $DC --ansi never run --rm -T gaia2 gaiad" +GAIA3_RUN="docker-compose $DC --ansi never run --rm -T gaia3 gaiad" +TZ1_1_RUN="docker-compose $DC --ansi never run --rm -T testzone1-1 icad" +TZ1_2_RUN="docker-compose $DC --ansi never run --rm -T testzone1-2 icad" +TZ1_3_RUN="docker-compose $DC --ansi never run --rm -T testzone1-3 icad" +TZ1_4_RUN="docker-compose $DC --ansi never run --rm -T testzone1-4 icad" +TZ2_1_RUN="docker-compose $DC --ansi never run --rm -T testzone2-1 osmosisd" +TZ2_2_RUN="docker-compose $DC --ansi never run --rm -T testzone2-2 osmosisd" +TZ2_3_RUN="docker-compose $DC --ansi never run --rm -T testzone2-3 osmosisd" +TZ2_4_RUN="docker-compose $DC --ansi never run --rm -T testzone2-4 osmosisd" +RLY_RUN="docker-compose $DC --ansi never run --rm -T relayer rly" +HERMES_RUN="docker-compose $DC --ansi never run --rm -T hermes hermes" -QS1_EXEC="docker-compose --ansi never exec -T quicksilver quicksilverd" -QS2_EXEC="docker-compose --ansi never exec -T quicksilver2 quicksilverd" -QS3_EXEC="docker-compose --ansi never exec -T quicksilver3 quicksilverd" -TZ1_1_EXEC="docker-compose --ansi never exec -T testzone1-1 icad" -TZ1_2_EXEC="docker-compose --ansi never exec -T testzone1-2 icad" -TZ1_3_EXEC="docker-compose --ansi never exec -T testzone1-3 icad" -TZ1_4_EXEC="docker-compose --ansi never exec -T testzone1-4 icad" -TZ2_1_EXEC="docker-compose --ansi never exec -T testzone2-1 osmosisd" -TZ2_2_EXEC="docker-compose --ansi never exec -T testzone2-2 osmosisd" -TZ2_3_EXEC="docker-compose --ansi never exec -T testzone2-3 osmosisd" -TZ2_4_EXEC="docker-compose --ansi never exec -T testzone2-4 osmosisd" -RLY_EXEC="docker-compose --ansi never exec -T relayer" +QS1_EXEC="docker-compose $DC --ansi never exec -T quicksilver quicksilverd" +QS2_EXEC="docker-compose $DC --ansi never exec -T quicksilver2 quicksilverd" +QS3_EXEC="docker-compose $DC --ansi never exec -T quicksilver3 quicksilverd" +GAIA1_EXEC="docker-compose $DC --ansi never exec -T gaia gaiad" +GAIA2_EXEC="docker-compose $DC --ansi never exec -T gaia2 gaiad" +GAIA3_EXEC="docker-compose $DC --ansi never exec -T gaia3 gaiad" +TZ1_1_EXEC="docker-compose $DC --ansi never exec -T testzone1-1 icad" +TZ1_2_EXEC="docker-compose $DC --ansi never exec -T testzone1-2 icad" +TZ1_3_EXEC="docker-compose $DC --ansi never exec -T testzone1-3 icad" +TZ1_4_EXEC="docker-compose $DC --ansi never exec -T testzone1-4 icad" +TZ2_1_EXEC="docker-compose $DC --ansi never exec -T testzone2-1 osmosisd" +TZ2_2_EXEC="docker-compose $DC --ansi never exec -T testzone2-2 osmosisd" +TZ2_3_EXEC="docker-compose $DC --ansi never exec -T testzone2-3 osmosisd" +TZ2_4_EXEC="docker-compose $DC --ansi never exec -T testzone2-4 osmosisd" +RLY_EXEC="docker-compose $DC --ansi never exec -T relayer" -ICQ_RUN="docker-compose --ansi never run --rm -T icq interchain-queries" -ICQ2_RUN="docker-compose --ansi never run --rm -T icq2 interchain-queries" +ICQ_RUN="docker-compose $DC --ansi never run --rm -T icq interchain-queries" +ICQ2_RUN="docker-compose $DC --ansi never run --rm -T icq2 interchain-queries" VAL_MNEMONIC_1="clock post desk civil pottery foster expand merit dash seminar song memory figure uniform spice circle try happy obvious trash crime hybrid hood cushion" VAL_MNEMONIC_2="angry twist harsh drastic left brass behave host shove marriage fall update business leg direct reward object ugly security warm tuna model broccoli choice" diff --git a/x/interchainstaking/keeper/abci.go b/x/interchainstaking/keeper/abci.go index cf4000745..8a4668458 100644 --- a/x/interchainstaking/keeper/abci.go +++ b/x/interchainstaking/keeper/abci.go @@ -16,6 +16,12 @@ type zoneItrFn func(index int64, zoneInfo types.Zone) (stop bool) // BeginBlocker of interchainstaking module func (k Keeper) BeginBlocker(ctx sdk.Context) { defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker) + + if ctx.ChainID() == "quicksilver-1" && ctx.BlockHeight() == 115001 { + // trigger one time function in lieu of upgrade handler that will trigger on chain resumption. + V010100UpgradeHandler(ctx, &k) + } + if ctx.BlockHeight()%30 == 0 { if err := k.GCCompletedRedelegations(ctx); err != nil { k.Logger(ctx).Error("error in GCCompletedRedelegations", "error", err) diff --git a/x/interchainstaking/keeper/hooks.go b/x/interchainstaking/keeper/hooks.go index 50a9a3033..ede98bebe 100644 --- a/x/interchainstaking/keeper/hooks.go +++ b/x/interchainstaking/keeper/hooks.go @@ -9,12 +9,21 @@ import ( "github.com/ingenuity-build/quicksilver/x/interchainstaking/types" ) +// we do not wish to process epoch boundaries that occurred during the chain halt. +func skipProductionEpoch(ctx sdk.Context, epochNumber int64) bool { + if ctx.ChainID() != "quicksilver-1" { + return false + } + + return epochNumber < 7 // epoch 7 will start on 4th Jan 2023. +} + func (k Keeper) BeforeEpochStart(ctx sdk.Context, epochIdentifier string, epochNumber int64) { } func (k Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumber int64) { // every epoch - if epochIdentifier == "epoch" { + if epochIdentifier == "epoch" && !skipProductionEpoch(ctx, epochNumber) { k.Logger(ctx).Info("handling epoch end") k.IterateZones(ctx, func(index int64, zoneInfo types.Zone) (stop bool) { diff --git a/x/interchainstaking/keeper/ibc_packet_handlers.go b/x/interchainstaking/keeper/ibc_packet_handlers.go index 632e199c0..759f0e554 100644 --- a/x/interchainstaking/keeper/ibc_packet_handlers.go +++ b/x/interchainstaking/keeper/ibc_packet_handlers.go @@ -20,6 +20,7 @@ import ( clienttypes "github.com/cosmos/ibc-go/v5/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v5/modules/core/04-channel/types" + "github.com/cosmos/cosmos-sdk/telemetry" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" @@ -37,6 +38,10 @@ func (k *Keeper) HandleAcknowledgement(ctx sdk.Context, packet channeltypes.Pack ack := channeltypes.Acknowledgement_Result{} err := json.Unmarshal(acknowledgement, &ack) if err != nil { + k.Logger(ctx).Error("unable to unmarshal acknowledgement", "error", err, "data", acknowledgement) + return err + } + if reflect.DeepEqual(ack, channeltypes.Acknowledgement_Result{}) { ackErr := channeltypes.Acknowledgement_Error{} err := json.Unmarshal(acknowledgement, &ackErr) if err != nil { @@ -44,10 +49,12 @@ func (k *Keeper) HandleAcknowledgement(ctx sdk.Context, packet channeltypes.Pack return err } - k.Logger(ctx).Error("unable to unmarshal acknowledgement result", "error", err, "remote_err", ackErr, "data", acknowledgement) - return err + k.Logger(ctx).Error("received an acknowledgement error", "error", err, "remote_err", ackErr, "data", acknowledgement) + defer telemetry.IncrCounter(1, types.ModuleName, "ica_acknowledgement_errors") + return nil + // return errors.New("received an acknowledgement error; unable to process") // this just causes the same errAck to be submitted repeatedly. } - + defer telemetry.IncrCounter(1, types.ModuleName, "ica_acknowledgement_success") txMsgData := &sdk.TxMsgData{} err = proto.Unmarshal(ack.Result, txMsgData) if err != nil { @@ -72,6 +79,7 @@ func (k *Keeper) HandleAcknowledgement(ctx sdk.Context, packet channeltypes.Pack } for msgIndex, msgData := range txMsgData.Data { + src := msgs[msgIndex] switch msgData.MsgType { case "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward": @@ -101,7 +109,6 @@ func (k *Keeper) HandleAcknowledgement(ctx sdk.Context, packet channeltypes.Pack return err } k.Logger(ctx).Info("Shares tokenized", "response", response) - // check tokenizedShareTransfers (inc. rebalance and unbond) if err := k.HandleTokenizedShares(ctx, src, response.Amount, packetData.Memo); err != nil { return err } @@ -338,7 +345,7 @@ func (k *Keeper) HandleWithdrawForUser(ctx sdk.Context, zone *types.Zone, msg *b if len(withdrawalRecord.Amount) == 1 && len(msg.Amount) == 1 && msg.Amount[0].Denom == withdrawalRecord.Amount[0].Denom && withdrawalRecord.Amount.IsEqual(msg.Amount) { k.Logger(ctx).Info("found matching withdrawal; marking as completed") k.UpdateWithdrawalRecordStatus(ctx, &withdrawalRecord, WithdrawStatusCompleted) - if err = k.BankKeeper.BurnCoins(ctx, types.ModuleName, sdk.NewCoins(withdrawalRecord.BurnAmount)); err != nil { + if err = k.BankKeeper.BurnCoins(ctx, types.EscrowModuleAccount, sdk.NewCoins(withdrawalRecord.BurnAmount)); err != nil { // if we can't burn the coins, fail. return err } @@ -357,7 +364,7 @@ func (k *Keeper) HandleWithdrawForUser(ctx sdk.Context, zone *types.Zone, msg *b // we just removed the last element k.Logger(ctx).Info("found matching withdrawal; marking as completed") k.UpdateWithdrawalRecordStatus(ctx, &withdrawalRecord, WithdrawStatusCompleted) - if err = k.BankKeeper.BurnCoins(ctx, types.ModuleName, sdk.NewCoins(withdrawalRecord.BurnAmount)); err != nil { + if err = k.BankKeeper.BurnCoins(ctx, types.EscrowModuleAccount, sdk.NewCoins(withdrawalRecord.BurnAmount)); err != nil { // if we can't burn the coins, fail. return err } @@ -442,7 +449,7 @@ func (k *Keeper) HandleQueuedUnbondings(ctx sdk.Context, zone *types.Zone, epoch err = fmt.Errorf("unable to find a validator we expected to exist [%s]", dist.Valoper) return true } - if val.DelegatorShares.Equal(sdk.NewDecFromInt(val.VotingPower)) { + if val.DelegatorShares.Equal(sdk.NewDecFromInt(val.VotingPower)) && dist.Amount > 0 { dist.Amount-- } } @@ -477,9 +484,11 @@ func (k *Keeper) HandleQueuedUnbondings(ctx sdk.Context, zone *types.Zone, epoch var msgs []sdk.Msg for _, valoper := range utils.Keys(out) { - sort.Strings(txhashes[valoper]) - k.SetUnbondingRecord(ctx, types.UnbondingRecord{ChainId: zone.ChainId, EpochNumber: epoch, Validator: valoper, RelatedTxhash: txhashes[valoper]}) - msgs = append(msgs, &stakingtypes.MsgUndelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorAddress: valoper, Amount: out[valoper]}) + if !out[valoper].Amount.IsZero() { + sort.Strings(txhashes[valoper]) + k.SetUnbondingRecord(ctx, types.UnbondingRecord{ChainId: zone.ChainId, EpochNumber: epoch, Validator: valoper, RelatedTxhash: txhashes[valoper]}) + msgs = append(msgs, &stakingtypes.MsgUndelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorAddress: valoper, Amount: out[valoper]}) + } } k.Logger(ctx).Error("unbonding messages", "msg", msgs) @@ -599,7 +608,7 @@ func (k *Keeper) HandleBeginRedelegate(ctx sdk.Context, msg sdk.Msg, completion record, found := k.GetRedelegationRecord(ctx, zone.ChainId, redelegateMsg.ValidatorSrcAddress, redelegateMsg.ValidatorDstAddress, epochNumber) if !found { k.Logger(ctx).Error("unable to find redelegation record", "chain", zone.ChainId, "source", redelegateMsg.ValidatorSrcAddress, "dst", redelegateMsg.ValidatorDstAddress, "epoch", epochNumber) - return errors.New("unable to find redelegation record") + return fmt.Errorf("unable to find redelegation record for chain %s, src: %s, dst: %s, at epoch %d", zone.ChainId, redelegateMsg.ValidatorSrcAddress, redelegateMsg.ValidatorDstAddress, epochNumber) } k.Logger(ctx).Error("updating redelegation record with completion time") record.CompletionTime = completion @@ -636,7 +645,7 @@ func (k *Keeper) HandleUndelegate(ctx sdk.Context, msg sdk.Msg, completion time. record, found := k.GetWithdrawalRecord(ctx, zone.ChainId, hash, WithdrawStatusUnbond) if !found { - return errors.New("unable to lookup withdrawal record") + return fmt.Errorf("unable to lookup withdrawal record; chain: %s, hash: %s", zone.ChainId, hash) } if completion.After(record.CompletionTime) { record.CompletionTime = completion diff --git a/x/interchainstaking/keeper/ibc_packet_handlers_test.go b/x/interchainstaking/keeper/ibc_packet_handlers_test.go index 870e43e66..c5f6348de 100644 --- a/x/interchainstaking/keeper/ibc_packet_handlers_test.go +++ b/x/interchainstaking/keeper/ibc_packet_handlers_test.go @@ -561,7 +561,10 @@ func (s *KeeperTestSuite) TestHandleWithdrawForUser() { // set up zones for _, record := range records { app.InterchainstakingKeeper.SetWithdrawalRecord(ctx, record) - app.BankKeeper.MintCoins(ctx, icstypes.ModuleName, sdk.NewCoins(record.BurnAmount)) + err := app.BankKeeper.MintCoins(ctx, icstypes.ModuleName, sdk.NewCoins(record.BurnAmount)) + s.Require().NoError(err) + err = app.BankKeeper.SendCoinsFromModuleToModule(ctx, icstypes.ModuleName, icstypes.EscrowModuleAccount, sdk.NewCoins(record.BurnAmount)) + s.Require().NoError(err) } // trigger handler @@ -672,7 +675,10 @@ func (s *KeeperTestSuite) TestHandleWithdrawForUserLSM() { // set up zones for _, record := range records { app.InterchainstakingKeeper.SetWithdrawalRecord(ctx, record) - app.BankKeeper.MintCoins(ctx, icstypes.ModuleName, sdk.NewCoins(record.BurnAmount)) + err := app.BankKeeper.MintCoins(ctx, icstypes.ModuleName, sdk.NewCoins(record.BurnAmount)) + s.Require().NoError(err) + err = app.BankKeeper.SendCoinsFromModuleToModule(ctx, icstypes.ModuleName, icstypes.EscrowModuleAccount, sdk.NewCoins(record.BurnAmount)) + s.Require().NoError(err) } // trigger handler diff --git a/x/interchainstaking/keeper/intent.go b/x/interchainstaking/keeper/intent.go index 5f16741bd..d3026b81d 100644 --- a/x/interchainstaking/keeper/intent.go +++ b/x/interchainstaking/keeper/intent.go @@ -136,14 +136,17 @@ func (k *Keeper) AggregateIntents(ctx sdk.Context, zone *types.Zone) error { } // normalise aggregated intents again. - for idx, intent := range aggregate.Sort() { - intent.Weight = intent.Weight.Quo(ordinalizedIntentSum) - aggregate[idx] = intent + newAggregate := make(types.ValidatorIntents, 0) + for _, intent := range aggregate.Sort() { + if !intent.Weight.IsZero() && intent.Weight.IsPositive() { + intent.Weight = intent.Weight.Quo(ordinalizedIntentSum) + newAggregate = append(newAggregate, intent) + } } - k.Logger(ctx).Info("aggregates", "agg", aggregate, "chain", zone.ChainId) + k.Logger(ctx).Info("aggregates", "agg", newAggregate, "chain", zone.ChainId) - zone.AggregateIntent = aggregate + zone.AggregateIntent = newAggregate k.SetZone(ctx, zone) return nil } @@ -172,6 +175,9 @@ func (k *Keeper) UpdateIntent(ctx sdk.Context, sender sdk.AccAddress, zone types // inAmount is ordinal with respect to the redemption rate, so we must scale baseBalance := zone.RedemptionRate.Mul(sdk.NewDecFromInt(balance.Amount)) + if baseBalance.IsZero() { + return nil + } if inAmount.IsValid() { intent = zone.UpdateIntentWithCoins(intent, baseBalance, inAmount) diff --git a/x/interchainstaking/keeper/intent_test.go b/x/interchainstaking/keeper/intent_test.go index 82debc294..bdd9b81e8 100644 --- a/x/interchainstaking/keeper/intent_test.go +++ b/x/interchainstaking/keeper/intent_test.go @@ -261,6 +261,36 @@ func (suite *KeeperTestSuite) TestAggregateIntent() { // out = append(out, &icstypes.ValidatorIntent{ValoperAddress: zone.GetValidatorsAddressesAsSlice()[0], Weight: sdk.OneDec().Quo(sdk.NewDec(2))}) // out = append(out, &icstypes.ValidatorIntent{ValoperAddress: zone.GetValidatorsAddressesAsSlice()[1], Weight: sdk.OneDec().Quo(sdk.NewDec(2))}) + // return out.Sort() + // }, + expected: func(zone icstypes.Zone) icstypes.ValidatorIntents { + // four delegators each at 25% + out := icstypes.ValidatorIntents{} + for _, val := range zone.GetValidatorsAddressesAsSlice() { + out = append(out, &icstypes.ValidatorIntent{ValoperAddress: val, Weight: sdk.OneDec().Quo(sdk.NewDec(4))}) + } + return out.Sort() + }, + }, + { + name: "two intents; with zer0 balances, diff val, returns default equal weights ", + intents: func(zone icstypes.Zone) []icstypes.DelegatorIntent { + out := make([]icstypes.DelegatorIntent, 0) + out = append(out, icstypes.DelegatorIntent{Delegator: user1.String(), Intents: icstypes.ValidatorIntents{&icstypes.ValidatorIntent{ValoperAddress: zone.GetValidatorsAddressesAsSlice()[0], Weight: sdk.ZeroDec()}}}) + out = append(out, icstypes.DelegatorIntent{Delegator: user2.String(), Intents: icstypes.ValidatorIntents{&icstypes.ValidatorIntent{ValoperAddress: zone.GetValidatorsAddressesAsSlice()[1], Weight: sdk.OneDec()}}}) + return out + }, + balances: func() map[string]int64 { + return map[string]int64{ + user1.String(): 0, + user2.String(): 0, + } + }, + // expected: func(zone icstypes.Zone) icstypes.ValidatorIntents { + // out := icstypes.ValidatorIntents{} + // out = append(out, &icstypes.ValidatorIntent{ValoperAddress: zone.GetValidatorsAddressesAsSlice()[0], Weight: sdk.OneDec().Quo(sdk.NewDec(2))}) + // out = append(out, &icstypes.ValidatorIntent{ValoperAddress: zone.GetValidatorsAddressesAsSlice()[1], Weight: sdk.OneDec().Quo(sdk.NewDec(2))}) + // return out.Sort() // }, expected: func(zone icstypes.Zone) icstypes.ValidatorIntents { diff --git a/x/interchainstaking/keeper/keeper.go b/x/interchainstaking/keeper/keeper.go index 3182fe147..96863f72e 100644 --- a/x/interchainstaking/keeper/keeper.go +++ b/x/interchainstaking/keeper/keeper.go @@ -57,6 +57,10 @@ func NewKeeper(cdc codec.Codec, storeKey storetypes.StoreKey, accountKeeper auth panic(fmt.Sprintf("%s module account has not been set", types.ModuleName)) } + if addr := accountKeeper.GetModuleAddress(types.EscrowModuleAccount); addr == nil { + panic(fmt.Sprintf("%s module account has not been set", types.ModuleName)) + } + if !ps.HasKeyTable() { ps = ps.WithKeyTable(types.ParamKeyTable()) } @@ -414,41 +418,29 @@ func (k Keeper) EmitPerformanceBalanceQuery(ctx sdk.Context, zone *types.Zone) e // redemption rate -func (k *Keeper) assertRedemptionRateWithinBounds(_ sdk.Context, previousRate sdk.Dec, newRate sdk.Dec) error { - ratio := newRate.Quo(previousRate) - if ratio.GT(sdk.NewDecWithPrec(120, 2)) || ratio.LT(sdk.NewDecWithPrec(95, 2)) { - return fmt.Errorf("redemption rate is outside of expected bounds; got %0.2f of previous rate", ratio.MustFloat64()) - } - return nil -} - func (k *Keeper) UpdateRedemptionRate(ctx sdk.Context, zone types.Zone, epochRewards math.Int) { - ratio := k.GetRatio(ctx, zone, epochRewards) + ratio, isZero := k.GetRatio(ctx, zone, epochRewards) k.Logger(ctx).Info("Epochly rewards", "coins", epochRewards) k.Logger(ctx).Info("Last redemption rate", "rate", zone.LastRedemptionRate) k.Logger(ctx).Info("Current redemption rate", "rate", zone.RedemptionRate) k.Logger(ctx).Info("New redemption rate", "rate", ratio, "supply", k.BankKeeper.GetSupply(ctx, zone.LocalDenom).Amount, "lv", k.GetDelegatedAmount(ctx, &zone).Amount.Add(epochRewards)) - if err := k.assertRedemptionRateWithinBounds(ctx, zone.RedemptionRate, ratio); err != nil { - panic(err.Error()) + // soft cap redemption rate, instead of panicking. + delta := ratio.Quo(zone.RedemptionRate) + if delta.GT(sdk.NewDecWithPrec(102, 2)) { + k.Logger(ctx).Error("ratio diverged by more than 2% upwards in the last epoch; capping at 1.02...") + ratio = zone.RedemptionRate.Mul(sdk.NewDecWithPrec(102, 2)) + } else if delta.LT(sdk.NewDecWithPrec(95, 2)) && !isZero { // we allow a bigger downshift if all assets were withdrawn and we revert to zero. + k.Logger(ctx).Error("ratio diverged by more than 5% downwards in the last epoch; 5% is the theoretical max if _all_ controlled tokens were tombstoned. capping at 0.95...") + ratio = zone.RedemptionRate.Mul(sdk.NewDecWithPrec(95, 2)) } - zone.LastRedemptionRate = zone.RedemptionRate - zone.RedemptionRate = ratio - k.SetZone(ctx, &zone) -} - -func (k *Keeper) UpdateRedemptionRateNoBounds(ctx sdk.Context, zone types.Zone) { - ratio := k.GetRatio(ctx, zone, math.ZeroInt()) - k.Logger(ctx).Info("Last redemption rate", "rate", zone.LastRedemptionRate) - k.Logger(ctx).Info("Current redemption rate", "rate", zone.RedemptionRate) - k.Logger(ctx).Info("New redemption rate", "rate", ratio, "supply", k.BankKeeper.GetSupply(ctx, zone.LocalDenom).Amount, "lv", k.GetDelegatedAmount(ctx, &zone).Amount) zone.LastRedemptionRate = zone.RedemptionRate zone.RedemptionRate = ratio k.SetZone(ctx, &zone) } -func (k *Keeper) GetRatio(ctx sdk.Context, zone types.Zone, epochRewards math.Int) sdk.Dec { +func (k *Keeper) GetRatio(ctx sdk.Context, zone types.Zone, epochRewards math.Int) (sdk.Dec, bool) { // native asset amount nativeAssetAmount := k.GetDelegatedAmount(ctx, &zone).Amount nativeAssetUnbondingAmount := k.GetUnbondingAmount(ctx, &zone).Amount @@ -460,10 +452,10 @@ func (k *Keeper) GetRatio(ctx sdk.Context, zone types.Zone, epochRewards math.In if qAssetAmount.IsZero() { // ratio 1.0 (default 1:1 ratio between nativeAssets and qAssets) // native assets should not reach zero before qAssets (discount rate asymptote) - return sdk.OneDec() + return sdk.OneDec(), true } - return sdk.NewDecFromInt(nativeAssetAmount.Add(epochRewards).Add(nativeAssetUnbondingAmount)).Quo(sdk.NewDecFromInt(qAssetAmount)) + return sdk.NewDecFromInt(nativeAssetAmount.Add(epochRewards).Add(nativeAssetUnbondingAmount)).Quo(sdk.NewDecFromInt(qAssetAmount)), false } func (k *Keeper) Rebalance(ctx sdk.Context, zone types.Zone, epochNumber int64) error { diff --git a/x/interchainstaking/keeper/keeper_test.go b/x/interchainstaking/keeper/keeper_test.go index 989151420..d365b91cf 100644 --- a/x/interchainstaking/keeper/keeper_test.go +++ b/x/interchainstaking/keeper/keeper_test.go @@ -485,7 +485,8 @@ func (s *KeeperTestSuite) TestGetRatio() { qapp.MintKeeper.MintCoins(ctx, sdk.NewCoins(sdk.NewCoin(zone.LocalDenom, tt.supply))) - actual := icsKeeper.GetRatio(ctx, zone, sdk.ZeroInt()) + actual, isZero := icsKeeper.GetRatio(ctx, zone, sdk.ZeroInt()) + s.Require().Equal(tt.supply.IsZero(), isZero) s.Require().Equal(tt.expected, actual) }) } diff --git a/x/interchainstaking/keeper/msg_server.go b/x/interchainstaking/keeper/msg_server.go index 19287b7b6..80834800a 100644 --- a/x/interchainstaking/keeper/msg_server.go +++ b/x/interchainstaking/keeper/msg_server.go @@ -101,7 +101,7 @@ func (k msgServer) RequestRedemption(goCtx context.Context, msg *types.MsgReques hash := sha256.Sum256(append(msg.GetSignBytes(), heightBytes...)) hashString := hex.EncodeToString(hash[:]) - if err := k.BankKeeper.SendCoinsFromAccountToModule(ctx, sender, types.ModuleName, sdk.NewCoins(msg.Value)); err != nil { + if err := k.BankKeeper.SendCoinsFromAccountToModule(ctx, sender, types.EscrowModuleAccount, sdk.NewCoins(msg.Value)); err != nil { return nil, err } diff --git a/x/interchainstaking/keeper/msg_server_test.go b/x/interchainstaking/keeper/msg_server_test.go index 8bec4c100..6d6ec19f3 100644 --- a/x/interchainstaking/keeper/msg_server_test.go +++ b/x/interchainstaking/keeper/msg_server_test.go @@ -281,7 +281,6 @@ func (s *KeeperTestSuite) TestRequestRedemption() { Amount: 3000000, CompletionTime: time.Time(s.chainA.GetContext().BlockTime().Add(time.Hour)), }) - }, "", "unable to satisfy unbond request; delegations may be locked", diff --git a/x/interchainstaking/keeper/v1_1_upgrade_handler.go b/x/interchainstaking/keeper/v1_1_upgrade_handler.go new file mode 100644 index 000000000..488b57337 --- /dev/null +++ b/x/interchainstaking/keeper/v1_1_upgrade_handler.go @@ -0,0 +1,83 @@ +package keeper + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + ibcchanneltypes "github.com/cosmos/ibc-go/v5/modules/core/04-channel/types" + "github.com/ingenuity-build/quicksilver/utils" + icstypes "github.com/ingenuity-build/quicksilver/x/interchainstaking/types" +) + +func closeChannel(ctx sdk.Context, k *Keeper, connectionID string, portID string) { //nolint:unparam + channelID, found := k.ICAControllerKeeper.GetActiveChannelID(ctx, connectionID, portID) + if !found { + panic("unable to fetch channelID for closing") + } + channel, found := k.IBCKeeper.ChannelKeeper.GetChannel(ctx, portID, channelID) + if !found { + panic("unable to fetch channel for closing") + } + channel.State = ibcchanneltypes.CLOSED + k.IBCKeeper.ChannelKeeper.SetChannel(ctx, portID, channelID, channel) +} + +// this is not a conventional upgrade handler, as it needs to be run by the begin blocker of the ICS module immediately on restart. +// it needs to be exported/public so can be called from the appropriate begin blocker. +func V010100UpgradeHandler(ctx sdk.Context, k *Keeper) { + // do NOT remove receipts, as reregistering the chain with the same connection will re-open the same deposit account, and existing txs would be re-processed. + // no delegation records, withdrawal, unbonding or rebalancing records exist, because the delegations never happened. + + // and delete the zone. + k.DeleteZone(ctx, "cosmoshub-4") + + // close channels 3,4,5 and 6 on connection-4. + closeChannel(ctx, k, "connection-4", "icacontroller-cosmoshub-4.deposit") + closeChannel(ctx, k, "connection-4", "icacontroller-cosmoshub-4.withdrawal") + closeChannel(ctx, k, "connection-4", "icacontroller-cosmoshub-4.performance") + closeChannel(ctx, k, "connection-4", "icacontroller-cosmoshub-4.delegate") + + // move all qAssets into interchainstakingtypes.EscrowModuleAccount, and burn. Original funds are returned to foundation address by the following + // Gaia migration: https://github.com/cosmos/gaia/pull/1976 + balances := map[string]int64{ + // depositor accounts; already refunded. + "quick1dpr6x7ggn32u2fgewtv08yvdrlh76mqwz4vva3": 4000000, + "quick1t9t4ch0gvt2wtyejnzd03gtdawlhhut56ymqzh": 3000000, + "quick133df0rz42d49jl3hzh6gtv6gf42x8vqas37vn3": 20000, + "quick1afj8d8e6tfdnj4hwczjugl5hu0frfamxsjh030": 750000, + "quick1kx3xxcpfaegq8nw0e46la339lgfmqahcph4nql": 2540000, + "quick1cu89smpf8cmlctxz5y5eud6qhpsp308ckgs0fu": 250000000, + "quick1nnhlu7j6r4e2efuaydyvdmqs5plp963es0ukex": 1000000, + "quick1rdhss0e720yjqu28xxen30t7u55selqfzwdnf5": 17100000, + "quick14hew5e5ua5pzhr6swnr0t2md6up7qmgpy8fe06": 10000000, + "quick1k00n9wvapdkwcmucct8f5wwnrmytqqrwkjkrmk": 10000000, + "quick1qgme8vlq4ly8tcye6xdgxnz4khzq9es03n2yzy": 10000000, + "quick1n4c56vddeqg67ktukprkteqdmpph2ck0xtm8sw": 2000000, + "quick1k8g0vlfmctyqtwahrxhudksz7rgrm6nsye3kpp": 66988, + "quick1gjgjsh74w5trmfaaauq4qt2mwvh8p7gsp4rc5v": 760000, + "quick1eslm0n3ypkd6f67n6ymf08m2t6kt9cypsf2w7d": 20000000, + // quicksilver accounts; to refund after gaia returns funds. + "quick1780znw95jjcdk4wtac44t5cjtrmxqfe9q49pej": 295000000, + "quick1954q9apawr6kg8ez4ukx8jyuaxakz7ye4jvyk4": 800000, + "quick16x03wcp37kx5e8ehckjxvwcgk9j0cqnhcccnty": 2833000000, + } + + for addressStr, balance := range balances { + addressBytes, err := utils.AccAddressFromBech32(addressStr, "quick") + if err != nil { + panic(err) + } + k.Logger(ctx).Info(fmt.Sprintf("Moving %d uqatom from %s to module account", balance, addressStr)) + if err := k.BankKeeper.SendCoinsFromAccountToModule(ctx, addressBytes, icstypes.EscrowModuleAccount, sdk.NewCoins(sdk.NewInt64Coin("uqatom", balance))); err != nil { + panic(err) + } + } + + k.Logger(ctx).Info(fmt.Sprintf("Burning %d uqatom in module account", 3460036988)) + if err := k.BankKeeper.BurnCoins(ctx, icstypes.EscrowModuleAccount, sdk.NewCoins(sdk.NewInt64Coin("uqatom", 3460036988))); err != nil { + panic(err) + } + + k.Logger(ctx).Info(fmt.Sprintf("%d uqatom burned and removed from supply; current supply (should be zero!): %v", 3460036988, k.BankKeeper.GetSupply(ctx, "uqatom"))) +} diff --git a/x/interchainstaking/keeper/v1_1_upgrade_handler_test.go b/x/interchainstaking/keeper/v1_1_upgrade_handler_test.go new file mode 100644 index 000000000..19bf5f6d0 --- /dev/null +++ b/x/interchainstaking/keeper/v1_1_upgrade_handler_test.go @@ -0,0 +1,99 @@ +package keeper_test + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + clienttypes "github.com/cosmos/ibc-go/v5/modules/core/02-client/types" + connectiontypes "github.com/cosmos/ibc-go/v5/modules/core/03-connection/types" + ibcchanneltypes "github.com/cosmos/ibc-go/v5/modules/core/04-channel/types" + tmclienttypes "github.com/cosmos/ibc-go/v5/modules/light-clients/07-tendermint/types" + "github.com/ingenuity-build/quicksilver/app" + "github.com/ingenuity-build/quicksilver/utils" + "github.com/ingenuity-build/quicksilver/x/interchainstaking/keeper" + icskeeper "github.com/ingenuity-build/quicksilver/x/interchainstaking/keeper" + icstypes "github.com/ingenuity-build/quicksilver/x/interchainstaking/types" +) + +func (suite *KeeperTestSuite) Test_v11UpgradeHandler() { + qApp := suite.GetQuicksilverApp(suite.chainA) + ctx := suite.chainA.GetContext() + qApp.IBCKeeper.ClientKeeper.SetClientState(ctx, "07-tendermint-0", &tmclienttypes.ClientState{ChainId: "cosmoshub-4", TrustingPeriod: time.Hour, LatestHeight: clienttypes.Height{RevisionNumber: 1, RevisionHeight: 100}}) + qApp.IBCKeeper.ClientKeeper.SetClientConsensusState(ctx, "07-tendermint-0", clienttypes.Height{RevisionNumber: 1, RevisionHeight: 100}, &tmclienttypes.ConsensusState{Timestamp: ctx.BlockTime()}) + qApp.IBCKeeper.ConnectionKeeper.SetConnection(ctx, "connection-4", connectiontypes.ConnectionEnd{ClientId: "07-tendermint-0", Versions: []*connectiontypes.Version{{Identifier: "1", Features: []string{"ORDER_ORDERED", "ORDER_UNORDERED"}}}}) + + proposal := &icstypes.RegisterZoneProposal{ + Title: "register zone A", + Description: "register zone A", + ConnectionId: "connection-4", + LocalDenom: "uqatom", + BaseDenom: "uatom", + AccountPrefix: "cosmos", + MultiSend: true, + LiquidityModule: true, + } + + err := icskeeper.HandleRegisterZoneProposal(ctx, qApp.InterchainstakingKeeper, proposal) + suite.Require().NoError(err) + + zone, found := qApp.InterchainstakingKeeper.GetZone(suite.chainA.GetContext(), "cosmoshub-4") + suite.Require().True(found) + + suite.Require().NoError(suite.setupChannelForICA(ctx, "cosmoshub-4", "connection-4", "deposit", zone.AccountPrefix)) + suite.Require().NoError(suite.setupChannelForICA(ctx, "cosmoshub-4", "connection-4", "withdrawal", zone.AccountPrefix)) + suite.Require().NoError(suite.setupChannelForICA(ctx, "cosmoshub-4", "connection-4", "performance", zone.AccountPrefix)) + suite.Require().NoError(suite.setupChannelForICA(ctx, "cosmoshub-4", "connection-4", "delegate", zone.AccountPrefix)) + + for _, val := range suite.GetQuicksilverApp(suite.chainB).StakingKeeper.GetBondedValidatorsByPower(suite.chainB.GetContext()) { + // refetch the zone for each validator, else we end up with an empty valset each time! + zone, found := qApp.InterchainstakingKeeper.GetZone(suite.chainA.GetContext(), "cosmoshub-4") + suite.Require().True(found) + suite.Require().NoError(icskeeper.SetValidatorForZone(&qApp.InterchainstakingKeeper, suite.chainA.GetContext(), zone, app.DefaultConfig().Codec.MustMarshal(&val))) + } + + qApp.MintKeeper.MintCoins(ctx, sdk.NewCoins(sdk.NewInt64Coin("uqatom", 3460036988))) + for addr, amount := range map[string]int64{ + // depositor accounts; already refunded. + "quick1dpr6x7ggn32u2fgewtv08yvdrlh76mqwz4vva3": 4000000, + "quick1t9t4ch0gvt2wtyejnzd03gtdawlhhut56ymqzh": 3000000, + "quick133df0rz42d49jl3hzh6gtv6gf42x8vqas37vn3": 20000, + "quick1afj8d8e6tfdnj4hwczjugl5hu0frfamxsjh030": 750000, + "quick1kx3xxcpfaegq8nw0e46la339lgfmqahcph4nql": 2540000, + "quick1cu89smpf8cmlctxz5y5eud6qhpsp308ckgs0fu": 250000000, + "quick1nnhlu7j6r4e2efuaydyvdmqs5plp963es0ukex": 1000000, + "quick1rdhss0e720yjqu28xxen30t7u55selqfzwdnf5": 17100000, + "quick14hew5e5ua5pzhr6swnr0t2md6up7qmgpy8fe06": 10000000, + "quick1k00n9wvapdkwcmucct8f5wwnrmytqqrwkjkrmk": 10000000, + "quick1qgme8vlq4ly8tcye6xdgxnz4khzq9es03n2yzy": 10000000, + "quick1n4c56vddeqg67ktukprkteqdmpph2ck0xtm8sw": 2000000, + "quick1k8g0vlfmctyqtwahrxhudksz7rgrm6nsye3kpp": 66988, + "quick1gjgjsh74w5trmfaaauq4qt2mwvh8p7gsp4rc5v": 760000, + "quick1eslm0n3ypkd6f67n6ymf08m2t6kt9cypsf2w7d": 20000000, + // quicksilver accounts; to refund after gaia returns funds. + "quick1780znw95jjcdk4wtac44t5cjtrmxqfe9q49pej": 295000000, + "quick1954q9apawr6kg8ez4ukx8jyuaxakz7ye4jvyk4": 800000, + "quick16x03wcp37kx5e8ehckjxvwcgk9j0cqnhcccnty": 2833000000, + } { + + addrBytes, _ := utils.AccAddressFromBech32(addr, "quick") + if err := qApp.BankKeeper.SendCoinsFromModuleToAccount(ctx, "mint", addrBytes, sdk.NewCoins(sdk.NewInt64Coin("uqatom", amount))); err != nil { + panic(err) + } + } + suite.coordinator.CommitNBlocks(suite.chainA, 2) + suite.coordinator.CommitNBlocks(suite.chainB, 2) + + keeper.V010100UpgradeHandler(ctx, &qApp.InterchainstakingKeeper) + + for _, ica := range qApp.ICAControllerKeeper.GetAllInterchainAccounts(ctx) { + channelId, found := qApp.ICAControllerKeeper.GetActiveChannelID(ctx, ica.ConnectionId, ica.PortId) + suite.Require().True(found) + channel, found := qApp.IBCKeeper.ChannelKeeper.GetChannel(ctx, ica.PortId, channelId) + suite.Require().True(found) + suite.Require().Equal(ibcchanneltypes.CLOSED, channel.State) + } + + suite.Require().Equal(sdk.Coin{Denom: "uqatom", Amount: sdk.ZeroInt()}, qApp.BankKeeper.GetSupply(ctx, "uqatom")) + _, found = qApp.InterchainstakingKeeper.GetZone(ctx, "cosmoshub-4") + suite.Require().False(found) +} diff --git a/x/interchainstaking/types/keys.go b/x/interchainstaking/types/keys.go index e6b831cf2..f263a59fd 100644 --- a/x/interchainstaking/types/keys.go +++ b/x/interchainstaking/types/keys.go @@ -37,7 +37,8 @@ const ( ICASuffixWithdrawal = "withdrawal" ICASuffixPerformance = "performance" - BankStoreKey = "store/bank/key" + BankStoreKey = "store/bank/key" + EscrowModuleAccount = "ics-escrow-account" ) var ( diff --git a/x/mint/keeper/keeper.go b/x/mint/keeper/keeper.go index d9da3f548..a36210c9f 100644 --- a/x/mint/keeper/keeper.go +++ b/x/mint/keeper/keeper.go @@ -10,6 +10,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + airdroptypes "github.com/ingenuity-build/quicksilver/x/airdrop/types" participationrewards "github.com/ingenuity-build/quicksilver/x/participationrewards/types" ) @@ -159,16 +160,12 @@ func (k Keeper) DistributeMintedCoin(ctx sdk.Context, mintedCoin sdk.Coin) error // allocate pool allocation ratio to pool-incentives module account account poolIncentivesCoins := sdk.NewCoins(k.GetProportions(ctx, mintedCoin, proportions.PoolIncentives)) // temporary until we have incentives pool sorted :) - err = k.bankKeeper.BurnCoins(ctx, types.ModuleName, poolIncentivesCoins) + + err = k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, airdroptypes.ModuleName, poolIncentivesCoins) if err != nil { return err } - // err = k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, poolincentivestypes.ModuleName, poolIncentivesCoins) - // if err != nil { - // return err - // } - participationRewardCoin := k.GetProportions(ctx, mintedCoin, proportions.ParticipationRewards) participationRewardCoins := sdk.NewCoins(participationRewardCoin) participationRewardsAddress := k.accountKeeper.GetModuleAddress(participationrewards.ModuleName) diff --git a/x/participationrewards/types/expected_keepers.go b/x/participationrewards/types/expected_keepers.go index 025251bbb..1ce582674 100644 --- a/x/participationrewards/types/expected_keepers.go +++ b/x/participationrewards/types/expected_keepers.go @@ -22,8 +22,6 @@ type BankKeeper interface { SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error SendCoinsFromModuleToModule(ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins) error MintCoins(ctx sdk.Context, name string, amt sdk.Coins) error - BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) error - // AddSupplyOffset(ctx sdk.Context, denom string, offsetAmount sdk.Int) } // StakingKeeper defines the contract for staking APIs.