Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: in-place testnet creator #7374

Merged
merged 8 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Misc Improvements

* [#7360](https://github.com/osmosis-labs/osmosis/pull/7360) Bump cometbft-db from 0.8.0 to 0.10.0
* [#7374](https://github.com/osmosis-labs/osmosis/pull/7374) In place testnet creation CLI
* [#7385](https://github.com/osmosis-labs/osmosis/pull/7385) Add missing protobuf interface

### Config
Expand Down
231 changes: 231 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"path/filepath"
"reflect"
"time"

wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"

Expand Down Expand Up @@ -41,12 +42,15 @@ import (

autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"

runtimeservices "github.com/cosmos/cosmos-sdk/runtime/services"

"github.com/CosmWasm/wasmd/x/wasm"
dbm "github.com/cometbft/cometbft-db"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/crypto"
"github.com/cometbft/cometbft/libs/bytes"
tmjson "github.com/cometbft/cometbft/libs/json"
"github.com/cometbft/cometbft/libs/log"
tmos "github.com/cometbft/cometbft/libs/os"
Expand All @@ -66,12 +70,14 @@ import (
"github.com/cosmos/cosmos-sdk/server/config"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/bech32"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
"github.com/cosmos/cosmos-sdk/x/crisis"

minttypes "github.com/osmosis-labs/osmosis/v22/x/mint/types"
protorevtypes "github.com/osmosis-labs/osmosis/v22/x/protorev/types"

"github.com/osmosis-labs/osmosis/v22/app/keepers"
Expand Down Expand Up @@ -404,6 +410,231 @@ func NewOsmosisApp(
return app
}

// InitOsmosisAppForTestnet is broken down into two sections:
// Required Changes: Changes that, if not made, will cause the testnet to halt or panic
// Optional Changes: Changes to customize the testnet to one's liking (lower vote times, fund accounts, etc)
func InitOsmosisAppForTestnet(app *OsmosisApp, newValAddr bytes.HexBytes, newValPubKey crypto.PubKey, newOperatorAddress, upgradeToTrigger string) *OsmosisApp {
//
// Required Changes:
//

ctx := app.BaseApp.NewUncachedContext(true, tmproto.Header{})
pubkey := &ed25519.PubKey{Key: newValPubKey.Bytes()}
pubkeyAny, err := types.NewAnyWithValue(pubkey)
if err != nil {
tmos.Exit(err.Error())
}

// STAKING
//

// Create Validator struct for our new validator.
_, bz, err := bech32.DecodeAndConvert(newOperatorAddress)
if err != nil {
tmos.Exit(err.Error())
}
bech32Addr, err := bech32.ConvertAndEncode("osmovaloper", bz)
if err != nil {
tmos.Exit(err.Error())
}
newVal := stakingtypes.Validator{
OperatorAddress: bech32Addr,
ConsensusPubkey: pubkeyAny,
Jailed: false,
Status: stakingtypes.Bonded,
Tokens: sdk.NewInt(900000000000000),
DelegatorShares: sdk.MustNewDecFromStr("10000000"),
Description: stakingtypes.Description{
Moniker: "Testnet Validator",
},
Commission: stakingtypes.Commission{
CommissionRates: stakingtypes.CommissionRates{
Rate: sdk.MustNewDecFromStr("0.05"),
MaxRate: sdk.MustNewDecFromStr("0.1"),
MaxChangeRate: sdk.MustNewDecFromStr("0.05"),
},
},
MinSelfDelegation: sdk.OneInt(),
}

// Remove all validators from power store
stakingKey := app.GetKey(stakingtypes.ModuleName)
stakingStore := ctx.KVStore(stakingKey)
iterator := app.StakingKeeper.ValidatorsPowerStoreIterator(ctx)
for ; iterator.Valid(); iterator.Next() {
stakingStore.Delete(iterator.Key())
}
iterator.Close()

// Remove all valdiators from last validators store
iterator = app.StakingKeeper.LastValidatorsIterator(ctx)
for ; iterator.Valid(); iterator.Next() {
stakingStore.Delete(iterator.Key())
}
iterator.Close()

// Add our validator to power and last validators store
app.StakingKeeper.SetValidator(ctx, newVal)
err = app.StakingKeeper.SetValidatorByConsAddr(ctx, newVal)
if err != nil {
tmos.Exit(err.Error())
}
app.StakingKeeper.SetValidatorByPowerIndex(ctx, newVal)
app.StakingKeeper.SetLastValidatorPower(ctx, newVal.GetOperator(), 0)
if err := app.StakingKeeper.Hooks().AfterValidatorCreated(ctx, newVal.GetOperator()); err != nil {
panic(err)
}

// DISTRIBUTION
//

// Initialize records for this validator across all distribution stores
app.DistrKeeper.SetValidatorHistoricalRewards(ctx, newVal.GetOperator(), 0, distrtypes.NewValidatorHistoricalRewards(sdk.DecCoins{}, 1))
app.DistrKeeper.SetValidatorCurrentRewards(ctx, newVal.GetOperator(), distrtypes.NewValidatorCurrentRewards(sdk.DecCoins{}, 1))
app.DistrKeeper.SetValidatorAccumulatedCommission(ctx, newVal.GetOperator(), distrtypes.InitialValidatorAccumulatedCommission())
app.DistrKeeper.SetValidatorOutstandingRewards(ctx, newVal.GetOperator(), distrtypes.ValidatorOutstandingRewards{Rewards: sdk.DecCoins{}})

// SLASHING
//

// Set validator signing info for our new validator.
newConsAddr := sdk.ConsAddress(newValAddr.Bytes())
newValidatorSigningInfo := slashingtypes.ValidatorSigningInfo{
Address: newConsAddr.String(),
StartHeight: app.LastBlockHeight() - 1,
Tombstoned: false,
}
app.SlashingKeeper.SetValidatorSigningInfo(ctx, newConsAddr, newValidatorSigningInfo)

//
// Optional Changes:
//

// GOV
//

newExpeditedVotingPeriod := time.Minute
newVotingPeriod := time.Minute * 2

govParams := app.GovKeeper.GetParams(ctx)
govParams.ExpeditedVotingPeriod = &newExpeditedVotingPeriod
govParams.VotingPeriod = &newVotingPeriod
govParams.MinDeposit = sdk.NewCoins(sdk.NewInt64Coin("uosmo", 100000000))
govParams.ExpeditedMinDeposit = sdk.NewCoins(sdk.NewInt64Coin("uosmo", 150000000))

err = app.GovKeeper.SetParams(ctx, govParams)
if err != nil {
tmos.Exit(err.Error())
}

// EPOCHS
//

dayEpochInfo := app.EpochsKeeper.GetEpochInfo(ctx, "day")
dayEpochInfo.Duration = time.Hour * 6
// Prevents epochs from running back to back
dayEpochInfo.CurrentEpochStartTime = time.Now().UTC()
dayEpochInfo.CurrentEpochStartHeight = app.LastBlockHeight()
app.EpochsKeeper.DeleteEpochInfo(ctx, "day")
err = app.EpochsKeeper.AddEpochInfo(ctx, dayEpochInfo)
if err != nil {
tmos.Exit(err.Error())
}

weekEpochInfo := app.EpochsKeeper.GetEpochInfo(ctx, "week")
weekEpochInfo.Duration = time.Hour * 12
// Prevents epochs from running back to back
weekEpochInfo.CurrentEpochStartTime = time.Now().UTC()
weekEpochInfo.CurrentEpochStartHeight = app.LastBlockHeight()
app.EpochsKeeper.DeleteEpochInfo(ctx, "week")
err = app.EpochsKeeper.AddEpochInfo(ctx, weekEpochInfo)
if err != nil {
tmos.Exit(err.Error())
}

// BANK
//

defaultCoins := sdk.NewCoins(
sdk.NewInt64Coin("ibc/0CD3A0285E1341859B5E86B6AB7682F023D03E97607CCC1DC95706411D866DF7", 1000000000000), // DAI
sdk.NewInt64Coin("uosmo", 1000000000000),
sdk.NewInt64Coin("uion", 1000000000))

localOsmosisAccounts := []sdk.AccAddress{
sdk.MustAccAddressFromBech32("osmo12smx2wdlyttvyzvzg54y2vnqwq2qjateuf7thj"),
sdk.MustAccAddressFromBech32("osmo1cyyzpxplxdzkeea7kwsydadg87357qnahakaks"),
sdk.MustAccAddressFromBech32("osmo18s5lynnmx37hq4wlrw9gdn68sg2uxp5rgk26vv"),
sdk.MustAccAddressFromBech32("osmo1qwexv7c6sm95lwhzn9027vyu2ccneaqad4w8ka"),
sdk.MustAccAddressFromBech32("osmo14hcxlnwlqtq75ttaxf674vk6mafspg8xwgnn53"),
sdk.MustAccAddressFromBech32("osmo12rr534cer5c0vj53eq4y32lcwguyy7nndt0u2t"),
sdk.MustAccAddressFromBech32("osmo1nt33cjd5auzh36syym6azgc8tve0jlvklnq7jq"),
sdk.MustAccAddressFromBech32("osmo10qfrpash5g2vk3hppvu45x0g860czur8ff5yx0"),
sdk.MustAccAddressFromBech32("osmo1f4tvsdukfwh6s9swrc24gkuz23tp8pd3e9r5fa"),
sdk.MustAccAddressFromBech32("osmo1myv43sqgnj5sm4zl98ftl45af9cfzk7nhjxjqh"),
sdk.MustAccAddressFromBech32("osmo14gs9zqh8m49yy9kscjqu9h72exyf295afg6kgk"),
sdk.MustAccAddressFromBech32("osmo1jllfytsz4dryxhz5tl7u73v29exsf80vz52ucc")}

// Fund localosmosis accounts
for _, account := range localOsmosisAccounts {
err := app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, defaultCoins)
if err != nil {
tmos.Exit(err.Error())
}
err = app.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, account, defaultCoins)
if err != nil {
tmos.Exit(err.Error())
}
}

// Fund edgenet faucet
faucetCoins := sdk.NewCoins(
sdk.NewInt64Coin("ibc/0CD3A0285E1341859B5E86B6AB7682F023D03E97607CCC1DC95706411D866DF7", 1000000000000000), // DAI
sdk.NewInt64Coin("uosmo", 1000000000000000),
sdk.NewInt64Coin("uion", 1000000000000))
err = app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, faucetCoins)
if err != nil {
tmos.Exit(err.Error())
}
err = app.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, sdk.MustAccAddressFromBech32("osmo1rqgf207csps822qwmd3k2n6k6k4e99w502e79t"), faucetCoins)
if err != nil {
tmos.Exit(err.Error())
}

// Mars bank account
marsCoins := sdk.NewCoins(
sdk.NewInt64Coin("uosmo", 10000000000000),
sdk.NewInt64Coin("ibc/903A61A498756EA560B85A85132D3AEE21B5DEDD41213725D22ABF276EA6945E", 400000000000),
sdk.NewInt64Coin("ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858", 3000000000000),
sdk.NewInt64Coin("ibc/C140AFD542AE77BD7DCC83F13FDD8C5E5BB8C4929785E6EC2F4C636F98F17901", 200000000000),
sdk.NewInt64Coin("ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2", 700000000000),
sdk.NewInt64Coin("ibc/D1542AA8762DB13087D8364F3EA6509FD6F009A34F00426AF9E4F9FA85CBBF1F", 2000000000),
sdk.NewInt64Coin("ibc/EA1D43981D5C9A1C4AAEA9C23BB1D4FA126BA9BC7020A25E0AE4AA841EA25DC5", 3000000000000000000))
err = app.BankKeeper.MintCoins(ctx, minttypes.ModuleName, marsCoins)
if err != nil {
tmos.Exit(err.Error())
}
err = app.BankKeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, sdk.MustAccAddressFromBech32("osmo1ev02crc36675xd8s029qh7wg3wjtfk37jr004z"), marsCoins)
if err != nil {
tmos.Exit(err.Error())
}

// UPGRADE
//

if upgradeToTrigger != "" {
upgradePlan := upgradetypes.Plan{
Name: upgradeToTrigger,
Height: app.LastBlockHeight(),
}
err = app.UpgradeKeeper.ScheduleUpgrade(ctx, upgradePlan)
if err != nil {
panic(err)
}
}

return app
}

// MakeCodecs returns the application codec and a legacy Amino codec.
func MakeCodecs() (codec.Codec, *codec.LegacyAmino) {
config := MakeEncodingConfig()
Expand Down
59 changes: 53 additions & 6 deletions cmd/osmosisd/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ import (

"github.com/osmosis-labs/osmosis/osmomath"
"github.com/osmosis-labs/osmosis/v22/app/params"
v23 "github.com/osmosis-labs/osmosis/v22/app/upgrades/v23" // should be automated to be updated to current version every upgrade
"github.com/osmosis-labs/osmosis/v22/ingest/sqs"

tmcfg "github.com/cometbft/cometbft/config"
"github.com/cometbft/cometbft/crypto"
"github.com/cometbft/cometbft/libs/bytes"
tmcli "github.com/cometbft/cometbft/libs/cli"
"github.com/cometbft/cometbft/libs/log"
tmtypes "github.com/cometbft/cometbft/types"
Expand Down Expand Up @@ -55,6 +58,7 @@ import (
genutil "github.com/cosmos/cosmos-sdk/x/genutil"
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

"github.com/CosmWasm/wasmd/x/wasm"
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
Expand Down Expand Up @@ -682,6 +686,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
)

server.AddCommands(rootCmd, osmosis.DefaultNodeHome, newApp, createOsmosisAppAndExport, addModuleInitFlags)
server.AddTestnetCreatorCommand(rootCmd, osmosis.DefaultNodeHome, newTestnetApp, addModuleInitFlags)

for i, cmd := range rootCmd.Commands() {
if cmd.Name() == "start" {
Expand Down Expand Up @@ -828,12 +833,7 @@ func newApp(logger log.Logger, db cometbftdb.DB, traceStore io.Writer, appOpts s
wasmOpts = append(wasmOpts, wasmkeeper.WithVMCacheMetrics(prometheus.DefaultRegisterer))
}

return osmosis.NewOsmosisApp(
logger, db, traceStore, true, skipUpgradeHeights,
cast.ToString(appOpts.Get(flags.FlagHome)),
cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)),
appOpts,
wasmOpts,
baseAppOptions := []func(*baseapp.BaseApp){
baseapp.SetPruning(pruningOpts),
baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(server.FlagMinGasPrices))),
baseapp.SetMinRetainBlocks(cast.ToUint64(appOpts.Get(server.FlagMinRetainBlocks))),
Expand All @@ -847,9 +847,56 @@ func newApp(logger log.Logger, db cometbftdb.DB, traceStore io.Writer, appOpts s
baseapp.SetIAVLCacheSize(cast.ToInt(appOpts.Get(server.FlagIAVLCacheSize))),
baseapp.SetIAVLDisableFastNode(cast.ToBool(appOpts.Get(server.FlagDisableIAVLFastNode))),
baseapp.SetChainID(chainID),
}

// If this is an in place testnet, set any new stores that may exist
if cast.ToBool(appOpts.Get(server.KeyIsTestnet)) {
version := store.NewCommitMultiStore(db).LatestVersion() + 1
fmt.Println("version", version)
baseAppOptions = append(baseAppOptions, baseapp.SetStoreLoader(upgradetypes.UpgradeStoreLoader(version, &v23.Upgrade.StoreUpgrades)))
}

return osmosis.NewOsmosisApp(
logger, db, traceStore, true, skipUpgradeHeights,
cast.ToString(appOpts.Get(flags.FlagHome)),
cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)),
appOpts,
wasmOpts,
baseAppOptions...,
)
}

// newTestnetApp starts by running the normal newApp method. From there, the app interface returned is modified in order
// for a testnet to be created from the provided app.
func newTestnetApp(logger log.Logger, db cometbftdb.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application {
// Create an app and type cast to an OsmosisApp
app := newApp(logger, db, traceStore, appOpts)
osmosisApp, ok := app.(*osmosis.OsmosisApp)
if !ok {
panic("app created from newApp is not of type osmosisApp")
}

newValAddr, ok := appOpts.Get(server.KeyNewValAddr).(bytes.HexBytes)
if !ok {
panic("newValAddr is not of type bytes.HexBytes")
}
newValPubKey, ok := appOpts.Get(server.KeyUserPubKey).(crypto.PubKey)
if !ok {
panic("newValPubKey is not of type crypto.PubKey")
}
newOperatorAddress, ok := appOpts.Get(server.KeyNewOpAddr).(string)
if !ok {
panic("newOperatorAddress is not of type string")
}
upgradeToTrigger, ok := appOpts.Get(server.KeyTriggerTestnetUpgrade).(string)
if !ok {
panic("upgradeToTrigger is not of type string")
}

// Make modifications to the normal OsmosisApp required to run the network locally
return osmosis.InitOsmosisAppForTestnet(osmosisApp, newValAddr, newValPubKey, newOperatorAddress, upgradeToTrigger)
}

// createOsmosisAppAndExport creates and exports the new Osmosis app, returns the state of the new Osmosis app for a genesis file.
func createOsmosisAppAndExport(
logger log.Logger, db cometbftdb.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailWhiteList []string,
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -390,9 +390,9 @@ replace (
// v1.0.0-beta.3 is incompatible, so we use v1.0.0-beta.2
github.com/cosmos/cosmos-proto => github.com/cosmos/cosmos-proto v1.0.0-beta.2

// Our cosmos-sdk branch is: https://github.com/osmosis-labs/cosmos-sdk/tree/osmo-v22/v0.47.5, current branch: osmo-v22/v0.47.5. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/cf358f6fc20cabfb5cb8ce75fc10b2623150869e
// Our cosmos-sdk branch is: https://github.com/osmosis-labs/cosmos-sdk/tree/osmo-v22/v0.47.5, current branch: osmo-v22/v0.47.5. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/97b06aa49e4c814f9ec4e64be2d5eaf7be42a259
// https://github.com/osmosis-labs/cosmos-sdk/releases/tag/v0.47.5-v22-osmo-2
github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.47.5-v22-osmo-2
github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.47.5-v22-osmo-3
github.com/cosmos/gogoproto => github.com/cosmos/gogoproto v1.4.10
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1

Expand Down
Loading