Skip to content

Commit

Permalink
Merge pull request #8844 from Agoric/mhofman/8843-core-proposal-upgra…
Browse files Browse the repository at this point in the history
…de-handler

Core proposals in upgrade handler
  • Loading branch information
mergify[bot] authored Jan 31, 2024
2 parents 7386420 + 605eb4b commit a253f74
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 39 deletions.
66 changes: 42 additions & 24 deletions golang/cosmos/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ type GaiaApp struct { // nolint: golint
vibcPort int
vstoragePort int

upgradePlan *upgradetypes.Plan
upgradeDetails *upgradeDetails

invCheckPeriod uint

Expand Down Expand Up @@ -829,8 +829,21 @@ func NewAgoricApp(
func unreleasedUpgradeHandler(app *GaiaApp, targetUpgrade string) func(sdk.Context, upgradetypes.Plan, module.VersionMap) (module.VersionMap, error) {
return func(ctx sdk.Context, plan upgradetypes.Plan, fromVm module.VersionMap) (module.VersionMap, error) {
app.CheckControllerInited(false)
// Record the plan to send to SwingSet
app.upgradePlan = &plan

// Each CoreProposalStep runs sequentially, and can be constructed from
// one or more modules executing in parallel within the step.
CoreProposalSteps := []vm.CoreProposalStep{
// vm.CoreProposalStepForModules("@agoric/builders/scripts/vats/init-network.js"),
}

app.upgradeDetails = &upgradeDetails{
// Record the plan to send to SwingSet
Plan: plan,
// Core proposals that should run during the upgrade block
// These will be merged with any coreProposals specified in the
// upgradeInfo field of the upgrade plan ran as subsequent steps
CoreProposals: vm.CoreProposalsFromSteps(CoreProposalSteps...),
}

// Always run module migrations
mvm, err := app.mm.RunMigrations(ctx, app.configurator, fromVm)
Expand Down Expand Up @@ -865,18 +878,23 @@ func normalizeModuleAccount(ctx sdk.Context, ak authkeeper.AccountKeeper, name s
ak.SetModuleAccount(ctx, newAcct)
}

type upgradeDetails struct {
Plan upgradetypes.Plan `json:"plan"`
CoreProposals *vm.CoreProposals `json:"coreProposals,omitempty"`
}

type cosmosInitAction struct {
vm.ActionHeader `actionType:"AG_COSMOS_INIT"`
ChainID string `json:"chainID"`
IsBootstrap bool `json:"isBootstrap"`
Params swingset.Params `json:"params"`
SupplyCoins sdk.Coins `json:"supplyCoins"`
UpgradePlan *upgradetypes.Plan `json:"upgradePlan,omitempty"`
LienPort int `json:"lienPort"`
StoragePort int `json:"storagePort"`
SwingsetPort int `json:"swingsetPort"`
VbankPort int `json:"vbankPort"`
VibcPort int `json:"vibcPort"`
ChainID string `json:"chainID"`
IsBootstrap bool `json:"isBootstrap"`
UpgradeDetails *upgradeDetails `json:"upgradeDetails,omitempty"`
Params swingset.Params `json:"params"`
SupplyCoins sdk.Coins `json:"supplyCoins"`
LienPort int `json:"lienPort"`
StoragePort int `json:"storagePort"`
SwingsetPort int `json:"swingsetPort"`
VbankPort int `json:"vbankPort"`
VibcPort int `json:"vibcPort"`
}

// Name returns the name of the App
Expand All @@ -901,22 +919,22 @@ func (app *GaiaApp) initController(ctx sdk.Context, bootstrap bool) {

// Begin initializing the controller here.
action := &cosmosInitAction{
ChainID: ctx.ChainID(),
IsBootstrap: bootstrap,
Params: app.SwingSetKeeper.GetParams(ctx),
SupplyCoins: sdk.NewCoins(app.BankKeeper.GetSupply(ctx, "uist")),
UpgradePlan: app.upgradePlan,
LienPort: app.lienPort,
StoragePort: app.vstoragePort,
SwingsetPort: app.swingsetPort,
VbankPort: app.vbankPort,
VibcPort: app.vibcPort,
ChainID: ctx.ChainID(),
IsBootstrap: bootstrap,
Params: app.SwingSetKeeper.GetParams(ctx),
SupplyCoins: sdk.NewCoins(app.BankKeeper.GetSupply(ctx, "uist")),
UpgradeDetails: app.upgradeDetails,
LienPort: app.lienPort,
StoragePort: app.vstoragePort,
SwingsetPort: app.swingsetPort,
VbankPort: app.vbankPort,
VibcPort: app.vibcPort,
}
// This uses `BlockingSend` as a friendly wrapper for `sendToController`
//
// CAVEAT: we are restarting after an in-consensus halt or just because this
// node felt like it. The controller must be able to handle either case
// (inConsensus := action.IsBootstrap || action.UpgradePlan != nil).
// (inConsensus := action.IsBootstrap || action.UpgradeDetails != nil).
out, err := app.SwingSetKeeper.BlockingSend(ctx, action)

// fmt.Fprintf(os.Stderr, "AG_COSMOS_INIT Returned from SwingSet: %s, %v\n", out, err)
Expand Down
31 changes: 31 additions & 0 deletions golang/cosmos/vm/core_proposals.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package vm

// CoreProposalStep is a set of core proposal configs which are executed
// concurrently
type CoreProposalStep []Jsonable

// CoreProposals is one possible shape for core proposals expressed as a series
// of sequential steps
// see SequentialCoreProposals in packages/deploy-script-support/src/extract-proposal.js
type CoreProposals struct {
Steps []CoreProposalStep `json:"steps"`
}

// CoreProposalStepForModules generates a single core proposal step from
// the given modules, which will be executed concurrently during that step
func CoreProposalStepForModules(modules ...string) CoreProposalStep {
step := make([]Jsonable, len(modules))
for i := range modules {
step[i] = modules[i]
}
return step
}

// CoreProposalsFromSteps returns a CoreProposals from the given steps
func CoreProposalsFromSteps(steps ...CoreProposalStep) *CoreProposals {
if steps == nil {
// Deal with https://github.com/golang/go/issues/37711
return &CoreProposals{Steps: []CoreProposalStep{}}
}
return &CoreProposals{Steps: steps}
}
30 changes: 17 additions & 13 deletions packages/cosmic-swingset/src/launch-chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -884,30 +884,34 @@ export async function launch({
// );
switch (action.type) {
case ActionType.AG_COSMOS_INIT: {
const { blockHeight, isBootstrap, upgradePlan } = action;
const { blockHeight, isBootstrap, upgradeDetails } = action;

if (!blockNeedsExecution(blockHeight)) {
return true;
}

let { coreProposals } = parseUpgradePlanInfo(
upgradePlan,
ActionType.AG_COSMOS_INIT,
);
const softwareUpgradeCoreProposals = upgradeDetails?.coreProposals;

const { coreProposals: upgradeInfoCoreProposals } =
parseUpgradePlanInfo(upgradeDetails?.plan, ActionType.AG_COSMOS_INIT);

if (isBootstrap) {
// This only runs for the very first block on the chain.
await doBootstrap(action);

// Merge the core proposals from the bootstrap block with the
// ones from the upgrade plan.
coreProposals = mergeCoreProposals(
bootstrapCoreProposals,
coreProposals,
);
}

if (coreProposals) {
// Merge the core proposals from the bootstrap block with the
// ones from the upgrade.
const coreProposals = mergeCoreProposals(
bootstrapCoreProposals,
softwareUpgradeCoreProposals,
upgradeInfoCoreProposals,
);

if (coreProposals.steps.length) {
upgradeDetails ||
isBootstrap ||
Fail`Unexpected core proposals outside of consensus start`;
await doCoreProposals(action, coreProposals);
}
return true;
Expand Down
5 changes: 3 additions & 2 deletions packages/deploy-script-support/src/extract-proposal.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
*/

/**
* @typedef {ConfigProposal[] | {steps: ConfigProposal[][]}} CoreProposals
* @typedef {{steps: ConfigProposal[][]}} SequentialCoreProposals
* @typedef {ConfigProposal[] | SequentialCoreProposals} CoreProposals
*/

const { Fail } = assert;
Expand All @@ -24,7 +25,7 @@ const req = createRequire(import.meta.url);

/**
* @param {...(CoreProposals | undefined | null)} args
* @returns {CoreProposals}
* @returns {SequentialCoreProposals}
*/
export const mergeCoreProposals = (...args) => {
/** @type {ConfigProposal[][]} */
Expand Down

0 comments on commit a253f74

Please sign in to comment.