Skip to content

Commit

Permalink
feat: standalone to consumer changeover part 1 (#757)
Browse files Browse the repository at this point in the history
* on-chain upgrade to consumer chain wip

* add preCCV store and use it on democracy staking

* add TODOs and one more packet possibility

* status update

* Resolve hermes start issue for trusted validator set by changing revision height

* remove intermediary logs

* remove further unused codebase

* updates for endblocker test, existing test fixes, get last validators

* update for slashing sovereign validators for the fault made before consumer chain upgrade height

* resolve comments on github and slack communication

* update sovereign app to use v4 ibc from v3 & resolve consumer module merge conflict fix issue

* Update app/sovereign/upgrades/v3/upgrades.go

Co-authored-by: yaruwangway <69694322+yaruwangway@users.noreply.github.com>

* rm sovereign chain and tests. Will be replaced by simapp and integration tests

* duplicate module name

* add comment

* small rename

* remove democracy staking changes

* consumer ccv beginblock, endblock, and initgenesis order shouldn't matter

* add mock calls to compile

* adjust tests for new keeper field

* add registerDemocConsumer method

* split out preCCV flag and initial valset

* cleanup consumer module

* cleanup

* more cleanup

* temp changes to validators.go

* comment out test

* rm bad code from merge

* comment

* Update app.go

* UTs for CRUD

* UTs for keys

* use make for mocks

* todo

* changeover method and test

* resolve #783

* comment

* comments

* add appropriate TODOs, restore changes to main

* final nits before non-draft

* comment on ChangeoverToConsumer

* more clear comment

* small comment change

* update InitGenesis comment

* sovereign -> standalone

* missed a file

* builds now

* update comment after debug

* naming refactor

* edge case for val in old and new sets

* restore keys after rebase

---------

Co-authored-by: jstr1121 <jun@stridelabs.co>
Co-authored-by: jstr1121 <118450565+jstr1121@users.noreply.github.com>
Co-authored-by: yaruwangway <69694322+yaruwangway@users.noreply.github.com>
  • Loading branch information
4 people authored Apr 5, 2023
1 parent 45afa5c commit 9fa783f
Show file tree
Hide file tree
Showing 17 changed files with 766 additions and 90 deletions.
50 changes: 43 additions & 7 deletions app/consumer-democracy/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"os"
"path/filepath"

genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
Expand Down Expand Up @@ -114,7 +116,7 @@ import (

const (
AppName = "interchain-security-cd"
upgradeName = "v07-Theta"
upgradeName = "v07-Theta" // arbitrary name, define your own appropriately named upgrade
AccountAddressPrefix = "cosmos"
)

Expand Down Expand Up @@ -331,7 +333,7 @@ func New(
app.AccountKeeper,
)

ccvstakingKeeper := stakingkeeper.NewKeeper(
stakingKeeper := stakingkeeper.NewKeeper(
appCodec,
keys[stakingtypes.StoreKey],
app.AccountKeeper,
Expand All @@ -340,7 +342,7 @@ func New(
)

app.MintKeeper = mintkeeper.NewKeeper(
appCodec, keys[minttypes.StoreKey], app.GetSubspace(minttypes.ModuleName), &ccvstakingKeeper,
appCodec, keys[minttypes.StoreKey], app.GetSubspace(minttypes.ModuleName), &stakingKeeper,
app.AccountKeeper, app.BankKeeper, authtypes.FeeCollectorName,
)

Expand All @@ -356,7 +358,7 @@ func New(
app.GetSubspace(distrtypes.ModuleName),
app.AccountKeeper,
app.BankKeeper,
&ccvstakingKeeper,
&stakingKeeper,
consumertypes.ConsumerRedistributeName,
app.ModuleAccountAddrs(),
)
Expand All @@ -377,7 +379,7 @@ func New(
// register the staking hooks
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
// NOTE: slashing hook was removed since it's only relevant for consumerKeeper
app.StakingKeeper = *ccvstakingKeeper.SetHooks(
app.StakingKeeper = *stakingKeeper.SetHooks(
stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks()),
)

Expand All @@ -390,7 +392,7 @@ func New(
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper))
govKeeper := govkeeper.NewKeeper(
appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
&ccvstakingKeeper, ccvgovRouter,
&stakingKeeper, ccvgovRouter,
)

app.GovKeeper = *govKeeper.SetHooks(
Expand Down Expand Up @@ -426,6 +428,9 @@ func New(
authtypes.FeeCollectorName,
)

// Setting the staking keeper is only needed for standalone to consumer changeover chains
app.ConsumerKeeper.SetStandaloneStakingKeeper(app.StakingKeeper)

// consumer keeper satisfies the staking keeper interface
// of the slashing module
app.SlashingKeeper = slashingkeeper.NewKeeper(
Expand Down Expand Up @@ -626,6 +631,7 @@ func New(
app.UpgradeKeeper.SetUpgradeHandler(
upgradeName,
func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) {

app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams())

fromVM := make(map[string]uint64)
Expand All @@ -634,8 +640,33 @@ func New(
fromVM[moduleName] = eachModule.ConsensusVersion()
}

// For a new consumer chain, this code (together with the entire SetUpgradeHandler) is not needed at all,
// upgrade handler code is application specific. However, as an example, standalone to consumer
// changeover chains should utilize customized upgrade handler code similar to below.

// TODO: should have a way to read from current node home
userHomeDir, err := os.UserHomeDir()
if err != nil {
stdlog.Println("Failed to get home dir %2", err)
}
nodeHome := userHomeDir + "/.sovereign/config/genesis.json"
appState, _, err := genutiltypes.GenesisStateFromGenFile(nodeHome)
if err != nil {
return fromVM, fmt.Errorf("failed to unmarshal genesis state: %w", err)
}

var consumerGenesis = consumertypes.GenesisState{}
appCodec.MustUnmarshalJSON(appState[consumertypes.ModuleName], &consumerGenesis)

consumerGenesis.PreCCV = true
app.ConsumerKeeper.InitGenesis(ctx, &consumerGenesis)

ctx.Logger().Info("start to run module migrations...")

// Note: consumer ccv module is added to app.MM.Modules constructor above,
// meaning the consumer ccv module will have an entry in fromVM.
// Since a consumer ccv module entry exists in fromVM, the RunMigrations method
// will not call the consumer ccv module's InitGenesis method a second time.
return app.MM.RunMigrations(ctx, app.configurator, fromVM)
},
)
Expand All @@ -646,7 +677,12 @@ func New(
}

if upgradeInfo.Name == upgradeName && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
storeUpgrades := store.StoreUpgrades{}
// Chains may need to add a KV store to their application. The following code
// is needed for standalone chains that're changing over to a consumer chain, with a consumer ccv module.
// When a chain starts from height 0 (like for testing purposes in this repo), the following code is not needed.
storeUpgrades := store.StoreUpgrades{
Added: []string{consumertypes.ModuleName},
}

// configure store loader that checks if version == upgradeHeight and applies store upgrades
app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades))
Expand Down
1 change: 1 addition & 0 deletions proto/interchain_security/ccv/consumer/v1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ message GenesisState {
// LastTransmissionBlockHeight nil on new chain, filled in on restart.
interchain_security.ccv.consumer.v1.LastTransmissionBlockHeight last_transmission_block_height = 12
[ (gogoproto.nullable) = false ];
bool preCCV = 13; // flag indicating whether the consumer CCV module starts in pre-CCV state
}

// HeightValsetUpdateID defines the genesis information for the mapping
Expand Down
108 changes: 108 additions & 0 deletions testutil/keeper/mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions x/ccv/consumer/keeper/changeover.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package keeper

import (
sdk "github.com/cosmos/cosmos-sdk/types"
abci "github.com/tendermint/tendermint/abci/types"
)

// ChangeoverToConsumer includes the logic that needs to execute during the process of a
// standalone to consumer changeover, where the previously standalone chain has
// just been upgraded to include the consumer ccv module, but the provider valset is not
// yet responsible for POS/block production. This method constructs validator updates
// that will be given to tendermint, which allows the consumer chain to
// start using the provider valset, while the standalone valset is given zero voting power where appropriate.
func (k Keeper) ChangeoverToConsumer(ctx sdk.Context) (initialValUpdates []abci.ValidatorUpdate) {

initialValUpdates = k.GetInitialValSet(ctx)
// set last standalone height
k.SetLastStandaloneHeight(ctx, ctx.BlockHeight())
// populate cross chain validators states with initial valset
k.ApplyCCValidatorChanges(ctx, initialValUpdates)

// Add validator updates to initialValUpdates, such that the "old" validators returned from standalone staking module
// are given zero power, and the provider validators are given their full power.
initialUpdatesFlag := make(map[string]bool)
for _, val := range initialValUpdates {
initialUpdatesFlag[val.PubKey.String()] = true
}
for _, val := range k.GetLastStandaloneValidators(ctx) {
zeroPowerUpdate := val.ABCIValidatorUpdateZero()
if !initialUpdatesFlag[zeroPowerUpdate.PubKey.String()] {
initialValUpdates = append(initialValUpdates, zeroPowerUpdate)
}
}

// Note: this method should only be executed once as a part of the changeover process.
// Therefore we set the PreCCV state to false so the endblocker caller doesn't call this method again.
k.DeletePreCCV(ctx)

return initialValUpdates
}
Loading

0 comments on commit 9fa783f

Please sign in to comment.