Skip to content

Commit

Permalink
feat(cosmic-swingset): run upgrade actions to completion
Browse files Browse the repository at this point in the history
  • Loading branch information
mhofman committed Jan 19, 2024
1 parent 6bc0905 commit 98bf836
Showing 1 changed file with 54 additions and 31 deletions.
85 changes: 54 additions & 31 deletions packages/cosmic-swingset/src/launch-chain.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import {
BeansPerXsnapComputron,
} from './sim-params.js';
import { parseParams } from './params.js';
import { makeQueue } from './helpers/make-queue.js';
import { makeQueue, makeQueueStorageMock } from './helpers/make-queue.js';
import { exportStorage } from './export-storage.js';
import { parseLocatedJson } from './helpers/json.js';

Expand Down Expand Up @@ -312,6 +312,14 @@ export async function launch({
const actionQueue = makeQueue(actionQueueStorage);
/** @type {InboundQueue} */
const highPriorityQueue = makeQueue(highPriorityQueueStorage);
/**
* In memory queue holding actions that must be consumed entirely
* during the block. If it's not drained, we open the gates to
* hangover hell.
*
* @type {InboundQueue}
*/
const runThisBlock = makeQueue(makeQueueStorageMock().storage);

// Not to be confused with the gas model, this meter is for OpenTelemetry.
const metricMeter = metricsProvider.getMeter('ag-chain-cosmos');
Expand Down Expand Up @@ -582,6 +590,13 @@ export async function launch({
let keepGoing = await runSwingset();
if (!keepGoing) return;

// Then, if we have anything in the special runThisBlock queue, process
// it and do no further work.
if (runThisBlock.size()) {
await processActions(runThisBlock, runSwingset);
return;
}

// Then, process as much as we can from the priorityQueue.
keepGoing = await processActions(highPriorityQueue, runSwingset);
if (!keepGoing) return;
Expand Down Expand Up @@ -611,11 +626,15 @@ export async function launch({
// First, record new actions (bridge/mailbox/etc events that cosmos
// added up for delivery to swingset) into our inboundQueue metrics
inboundQueueMetrics.updateLength(
actionQueue.size() + highPriorityQueue.size(),
actionQueue.size() + highPriorityQueue.size() + runThisBlock.size(),
);

// If we have work to complete this block, it needs to run to completion.
// It will also run to completion any work that swingset still had pending.
const neverStop = runThisBlock.size() > 0;

// make a runPolicy that will be shared across all cycles
const runPolicy = computronCounter(params.beansPerUnit);
const runPolicy = computronCounter(params.beansPerUnit, neverStop);
const runSwingset = makeRunSwingset(blockHeight, runPolicy);

await runKernel(runSwingset, blockHeight, blockTime);
Expand Down Expand Up @@ -747,38 +766,36 @@ export async function launch({
}
if (upgradePlan) {
const blockHeight = upgradePlan.height;
if (blockNeedsExecution(blockHeight)) {
controller.writeSlogObject({
type: 'cosmic-swingset-upgrade-start',
blockHeight,
blockTime,
upgradePlan,
});
// Process upgrade plan
const upgradedAction = {
type: ActionType.ENACTED_UPGRADE,
upgradePlan,
blockHeight,
blockTime,
};
await doBlockingSend(upgradedAction);
controller.writeSlogObject({
type: 'cosmic-swingset-upgrade-finish',
blockHeight,
blockTime,
});
}

// Process upgrade plan
const upgradedAction = {
type: ActionType.ENACTED_UPGRADE,
upgradePlan,
blockHeight,
blockTime,
};
await doBlockingSend(upgradedAction);
}
return true;
}

case ActionType.ENACTED_UPGRADE: {
// Install and execute new core proposals.
const {
upgradePlan: { info: upgradeInfoJson = null } = {},
const { upgradePlan, blockHeight, blockTime } = action;

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

controller.writeSlogObject({
type: 'cosmic-swingset-upgrade-start',
blockHeight,
blockTime,
} = action;
upgradePlan,
});

const { info: upgradeInfoJson = null } = upgradePlan || {};

const upgradePlanInfo =
upgradeInfoJson &&
parseLocatedJson(upgradeInfoJson, 'ENACTED_UPGRADE upgradePlan.info');
Expand Down Expand Up @@ -813,9 +830,6 @@ export async function launch({
}

// Now queue the code for evaluation.
//
// TODO: Once SwingSet sprouts some tools for preemption, we should use
// them to help the upgrade process finish promptly.
const coreEvalAction = {
type: ActionType.CORE_EVAL,
blockHeight,
Expand All @@ -827,7 +841,7 @@ export async function launch({
},
],
};
highPriorityQueue.push({
runThisBlock.push({
context: {
blockHeight,
txHash: 'x/upgrade',
Expand All @@ -836,6 +850,12 @@ export async function launch({
action: coreEvalAction,
});

controller.writeSlogObject({
type: 'cosmic-swingset-upgrade-finish',
blockHeight,
blockTime,
});

return undefined;
}

Expand All @@ -849,6 +869,9 @@ export async function launch({
);
}

runThisBlock.size() === 0 ||
Fail`We didn't process all "run this block" actions`;

controller.writeSlogObject({
type: 'cosmic-swingset-commit-block-start',
blockHeight,
Expand Down

0 comments on commit 98bf836

Please sign in to comment.