@agoric/cosmic-swingset 0.41.4-dev-99fc025.0 → 0.41.4-dev-2c609b8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,138 +1,146 @@
1
- [
2
- "@agoric/builders/scripts/vats/init-core.js",
3
- "@agoric/builders/scripts/vats/init-network.js",
4
- {
5
- "module": "@agoric/builders/scripts/inter-protocol/init-core.js",
6
- "entrypoint": "defaultProposalBuilder",
7
- "args": [
1
+ {
2
+ "steps": [
3
+ [
4
+ "@agoric/builders/scripts/vats/init-core.js"
5
+ ],
6
+ [
7
+ "@agoric/builders/scripts/vats/init-network.js",
8
+ "@agoric/builders/scripts/pegasus/init-core.js"
9
+ ],
10
+ [
8
11
  {
9
- "econCommitteeOptions": {
10
- "committeeSize": 1
11
- },
12
- "minInitialPoolLiquidity": "0"
13
- }
14
- ]
15
- },
16
- "@agoric/builders/scripts/pegasus/init-core.js",
17
- {
18
- "module": "@agoric/builders/scripts/inter-protocol/add-collateral-core.js",
19
- "entrypoint": "defaultProposalBuilder",
20
- "args": [
12
+ "module": "@agoric/builders/scripts/inter-protocol/init-core.js",
13
+ "entrypoint": "defaultProposalBuilder",
14
+ "args": [
15
+ {
16
+ "econCommitteeOptions": {
17
+ "committeeSize": 1
18
+ },
19
+ "minInitialPoolLiquidity": "0"
20
+ }
21
+ ]
22
+ },
21
23
  {
22
- "interchainAssetOptions": {
23
- "denom": "ibc/toyatom",
24
- "decimalPlaces": 4,
25
- "keyword": "ATOM",
26
- "oracleBrand": "ATOM",
27
- "proposedName": "ATOM"
28
- }
29
- }
30
- ]
31
- },
32
- {
33
- "module": "@agoric/builders/scripts/inter-protocol/add-collateral-core.js",
34
- "entrypoint": "psmProposalBuilder",
35
- "args": [
24
+ "module": "@agoric/builders/scripts/inter-protocol/add-collateral-core.js",
25
+ "entrypoint": "defaultProposalBuilder",
26
+ "args": [
27
+ {
28
+ "interchainAssetOptions": {
29
+ "denom": "ibc/toyatom",
30
+ "decimalPlaces": 4,
31
+ "keyword": "ATOM",
32
+ "oracleBrand": "ATOM",
33
+ "proposedName": "ATOM"
34
+ }
35
+ }
36
+ ]
37
+ },
36
38
  {
37
- "anchorOptions": {
38
- "denom": "ibc/toyusdc",
39
- "decimalPlaces": 6,
40
- "keyword": "USDC_axl",
41
- "proposedName": "USD Coin"
42
- }
43
- }
44
- ]
45
- },
46
- {
47
- "module": "@agoric/builders/scripts/inter-protocol/add-collateral-core.js",
48
- "entrypoint": "psmProposalBuilder",
49
- "args": [
39
+ "module": "@agoric/builders/scripts/inter-protocol/add-collateral-core.js",
40
+ "entrypoint": "psmProposalBuilder",
41
+ "args": [
42
+ {
43
+ "anchorOptions": {
44
+ "denom": "ibc/toyusdc",
45
+ "decimalPlaces": 6,
46
+ "keyword": "USDC_axl",
47
+ "proposedName": "USD Coin"
48
+ }
49
+ }
50
+ ]
51
+ },
50
52
  {
51
- "anchorOptions": {
52
- "denom": "ibc/usdc5678",
53
- "decimalPlaces": 6,
54
- "keyword": "USDC_grv",
55
- "proposedName": "USC Coin"
56
- }
57
- }
58
- ]
59
- },
60
- {
61
- "module": "@agoric/builders/scripts/inter-protocol/add-collateral-core.js",
62
- "entrypoint": "psmProposalBuilder",
63
- "args": [
53
+ "module": "@agoric/builders/scripts/inter-protocol/add-collateral-core.js",
54
+ "entrypoint": "psmProposalBuilder",
55
+ "args": [
56
+ {
57
+ "anchorOptions": {
58
+ "denom": "ibc/usdc5678",
59
+ "decimalPlaces": 6,
60
+ "keyword": "USDC_grv",
61
+ "proposedName": "USC Coin"
62
+ }
63
+ }
64
+ ]
65
+ },
64
66
  {
65
- "anchorOptions": {
66
- "denom": "ibc/usdt1234",
67
- "decimalPlaces": 6,
68
- "keyword": "USDT_axl",
69
- "proposedName": "Tether USD"
70
- }
71
- }
72
- ]
73
- },
74
- {
75
- "module": "@agoric/builders/scripts/inter-protocol/add-collateral-core.js",
76
- "entrypoint": "psmProposalBuilder",
77
- "args": [
67
+ "module": "@agoric/builders/scripts/inter-protocol/add-collateral-core.js",
68
+ "entrypoint": "psmProposalBuilder",
69
+ "args": [
70
+ {
71
+ "anchorOptions": {
72
+ "denom": "ibc/usdt1234",
73
+ "decimalPlaces": 6,
74
+ "keyword": "USDT_axl",
75
+ "proposedName": "Tether USD"
76
+ }
77
+ }
78
+ ]
79
+ },
78
80
  {
79
- "anchorOptions": {
80
- "denom": "ibc/toyollie",
81
- "decimalPlaces": 6,
82
- "keyword": "USDT_grv",
83
- "proposedName": "Tether USD"
84
- }
85
- }
86
- ]
87
- },
88
- {
89
- "module": "@agoric/builders/scripts/inter-protocol/add-collateral-core.js",
90
- "entrypoint": "psmProposalBuilder",
91
- "args": [
81
+ "module": "@agoric/builders/scripts/inter-protocol/add-collateral-core.js",
82
+ "entrypoint": "psmProposalBuilder",
83
+ "args": [
84
+ {
85
+ "anchorOptions": {
86
+ "denom": "ibc/toyollie",
87
+ "decimalPlaces": 6,
88
+ "keyword": "USDT_grv",
89
+ "proposedName": "Tether USD"
90
+ }
91
+ }
92
+ ]
93
+ },
92
94
  {
93
- "anchorOptions": {
94
- "denom": "ibc/toyellie",
95
- "decimalPlaces": 6,
96
- "keyword": "AUSD",
97
- "proposedName": "Anchor USD"
98
- }
99
- }
100
- ]
101
- },
102
- {
103
- "module": "@agoric/builders/scripts/inter-protocol/price-feed-core.js",
104
- "entrypoint": "defaultProposalBuilder",
105
- "args": [
95
+ "module": "@agoric/builders/scripts/inter-protocol/add-collateral-core.js",
96
+ "entrypoint": "psmProposalBuilder",
97
+ "args": [
98
+ {
99
+ "anchorOptions": {
100
+ "denom": "ibc/toyellie",
101
+ "decimalPlaces": 6,
102
+ "keyword": "AUSD",
103
+ "proposedName": "Anchor USD"
104
+ }
105
+ }
106
+ ]
107
+ },
106
108
  {
107
- "AGORIC_INSTANCE_NAME": "ATOM-USD price feed",
108
- "oracleAddresses": [
109
- "@PRIMARY_ADDRESS@",
110
- "agoric1dy0yegdsev4xvce3dx7zrz2ad9pesf5svzud6y"
111
- ],
112
- "IN_BRAND_LOOKUP": [
113
- "agoricNames",
114
- "oracleBrand",
115
- "ATOM"
116
- ],
117
- "IN_BRAND_DECIMALS": 6,
118
- "OUT_BRAND_LOOKUP": [
119
- "agoricNames",
120
- "oracleBrand",
121
- "USD"
122
- ],
123
- "OUT_BRAND_DECIMALS": 4
124
- }
125
- ]
126
- },
127
- {
128
- "module": "@agoric/builders/scripts/inter-protocol/invite-committee-core.js",
129
- "entrypoint": "defaultProposalBuilder",
130
- "args": [
109
+ "module": "@agoric/builders/scripts/inter-protocol/price-feed-core.js",
110
+ "entrypoint": "defaultProposalBuilder",
111
+ "args": [
112
+ {
113
+ "AGORIC_INSTANCE_NAME": "ATOM-USD price feed",
114
+ "oracleAddresses": [
115
+ "@PRIMARY_ADDRESS@",
116
+ "agoric1dy0yegdsev4xvce3dx7zrz2ad9pesf5svzud6y"
117
+ ],
118
+ "IN_BRAND_LOOKUP": [
119
+ "agoricNames",
120
+ "oracleBrand",
121
+ "ATOM"
122
+ ],
123
+ "IN_BRAND_DECIMALS": 6,
124
+ "OUT_BRAND_LOOKUP": [
125
+ "agoricNames",
126
+ "oracleBrand",
127
+ "USD"
128
+ ],
129
+ "OUT_BRAND_DECIMALS": 4
130
+ }
131
+ ]
132
+ },
131
133
  {
132
- "voterAddresses": {
133
- "someone": "@PRIMARY_ADDRESS@"
134
- }
134
+ "module": "@agoric/builders/scripts/inter-protocol/invite-committee-core.js",
135
+ "entrypoint": "defaultProposalBuilder",
136
+ "args": [
137
+ {
138
+ "voterAddresses": {
139
+ "someone": "@PRIMARY_ADDRESS@"
140
+ }
141
+ }
142
+ ]
135
143
  }
136
144
  ]
137
- }
138
- ]
145
+ ]
146
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/cosmic-swingset",
3
- "version": "0.41.4-dev-99fc025.0+99fc025",
3
+ "version": "0.41.4-dev-2c609b8.0+2c609b8",
4
4
  "description": "Agoric's Cosmos blockchain integration",
5
5
  "type": "module",
6
6
  "bin": {
@@ -22,16 +22,16 @@
22
22
  "author": "Agoric",
23
23
  "license": "Apache-2.0",
24
24
  "dependencies": {
25
- "@agoric/assert": "0.6.1-dev-99fc025.0+99fc025",
26
- "@agoric/builders": "0.1.1-dev-99fc025.0+99fc025",
27
- "@agoric/cosmos": "0.34.2-dev-99fc025.0+99fc025",
28
- "@agoric/deploy-script-support": "0.10.4-dev-99fc025.0+99fc025",
29
- "@agoric/internal": "0.3.3-dev-99fc025.0+99fc025",
30
- "@agoric/store": "0.9.3-dev-99fc025.0+99fc025",
31
- "@agoric/swing-store": "0.9.2-dev-99fc025.0+99fc025",
32
- "@agoric/swingset-vat": "0.32.3-dev-99fc025.0+99fc025",
33
- "@agoric/telemetry": "0.6.3-dev-99fc025.0+99fc025",
34
- "@agoric/vm-config": "0.1.1-dev-99fc025.0+99fc025",
25
+ "@agoric/assert": "0.6.1-dev-2c609b8.0+2c609b8",
26
+ "@agoric/builders": "0.1.1-dev-2c609b8.0+2c609b8",
27
+ "@agoric/cosmos": "0.34.2-dev-2c609b8.0+2c609b8",
28
+ "@agoric/deploy-script-support": "0.10.4-dev-2c609b8.0+2c609b8",
29
+ "@agoric/internal": "0.3.3-dev-2c609b8.0+2c609b8",
30
+ "@agoric/store": "0.9.3-dev-2c609b8.0+2c609b8",
31
+ "@agoric/swing-store": "0.9.2-dev-2c609b8.0+2c609b8",
32
+ "@agoric/swingset-vat": "0.32.3-dev-2c609b8.0+2c609b8",
33
+ "@agoric/telemetry": "0.6.3-dev-2c609b8.0+2c609b8",
34
+ "@agoric/vm-config": "0.1.1-dev-2c609b8.0+2c609b8",
35
35
  "@endo/bundle-source": "^3.0.2",
36
36
  "@endo/far": "^1.0.2",
37
37
  "@endo/import-bundle": "^1.0.2",
@@ -69,5 +69,5 @@
69
69
  "typeCoverage": {
70
70
  "atLeast": 79.32
71
71
  },
72
- "gitHead": "99fc025340e007fa01de005fa6133491d2c75d6e"
72
+ "gitHead": "2c609b84ddd07536404dedf45b118b1625ce81a0"
73
73
  }
@@ -28,7 +28,10 @@ import { BridgeId as BRIDGE_ID } from '@agoric/internal';
28
28
  import { makeWithQueue } from '@agoric/internal/src/queue.js';
29
29
  import * as ActionType from '@agoric/internal/src/action-types.js';
30
30
 
31
- import { extractCoreProposalBundles } from '@agoric/deploy-script-support/src/extract-proposal.js';
31
+ import {
32
+ extractCoreProposalBundles,
33
+ mergeCoreProposals,
34
+ } from '@agoric/deploy-script-support/src/extract-proposal.js';
32
35
  import { fileURLToPath } from 'url';
33
36
 
34
37
  import {
@@ -51,6 +54,23 @@ import { parseLocatedJson } from './helpers/json.js';
51
54
  const console = anylogger('launch-chain');
52
55
  const blockManagerConsole = anylogger('block-manager');
53
56
 
57
+ /**
58
+ * @param {{ info: string } | null | undefined} upgradePlan
59
+ * @param {string} prefix
60
+ */
61
+ const parseUpgradePlanInfo = (upgradePlan, prefix = '') => {
62
+ const { info: upgradeInfoJson = null } = upgradePlan || {};
63
+
64
+ const upgradePlanInfo =
65
+ upgradeInfoJson &&
66
+ parseLocatedJson(
67
+ upgradeInfoJson,
68
+ `${prefix && `${prefix} `}upgradePlan.info`,
69
+ );
70
+
71
+ return harden(upgradePlanInfo || {});
72
+ };
73
+
54
74
  /** @typedef {import('@agoric/swingset-vat').SwingSetConfig} SwingSetConfig */
55
75
 
56
76
  /**
@@ -89,6 +109,7 @@ export async function buildSwingset(
89
109
  bootstrapArgs,
90
110
  env,
91
111
  {
112
+ callerWillEvaluateCoreProposals = !!bridgeOutbound,
92
113
  debugName = undefined,
93
114
  slogCallbacks,
94
115
  slogSender,
@@ -152,18 +173,6 @@ export async function buildSwingset(
152
173
  const bootVat =
153
174
  swingsetConfig.vats[swingsetConfig.bootstrap || 'bootstrap'];
154
175
 
155
- // Find the entrypoints for all the core proposals.
156
- if (coreProposals) {
157
- const { bundles, code } = await extractCoreProposalBundles(
158
- coreProposals,
159
- configLocation, // for path resolution
160
- );
161
- swingsetConfig.bundles = { ...swingsetConfig.bundles, ...bundles };
162
-
163
- // Tell the bootstrap code how to run the core proposals.
164
- bootVat.parameters = { ...bootVat.parameters, coreProposalCode: code };
165
- }
166
-
167
176
  if (bridgeOutbound) {
168
177
  const batchChainStorage = (method, args) =>
169
178
  bridgeOutbound(BRIDGE_ID.STORAGE, { method, args });
@@ -177,14 +186,36 @@ export async function buildSwingset(
177
186
  bootVat.parameters = { ...bootVat.parameters, chainStorageEntries };
178
187
  }
179
188
 
189
+ // Since only on-chain swingsets like `agd` have a bridge (and thereby
190
+ // `CORE_EVAL` support), things like `ag-solo` will need to do the
191
+ // coreProposals in the bootstrap vat.
192
+ let bridgedCoreProposals;
193
+ if (callerWillEvaluateCoreProposals) {
194
+ // We have a bridge to run the coreProposals, so do it in the caller.
195
+ bridgedCoreProposals = coreProposals;
196
+ } else if (coreProposals) {
197
+ // We don't have a bridge to run the coreProposals, so do it in the bootVat.
198
+ const { bundles, codeSteps } = await extractCoreProposalBundles(
199
+ coreProposals,
200
+ configLocation, // for path resolution
201
+ );
202
+ swingsetConfig.bundles = { ...swingsetConfig.bundles, ...bundles };
203
+ bootVat.parameters = {
204
+ ...bootVat.parameters,
205
+ coreProposalCodeSteps: codeSteps,
206
+ };
207
+ }
208
+
180
209
  swingsetConfig.pinBootstrapRoot = true;
181
210
  await initializeSwingset(swingsetConfig, bootstrapArgs, kernelStorage, {
182
211
  // @ts-expect-error debugPrefix? what's that?
183
212
  debugPrefix,
184
213
  });
214
+ // Let our caller schedule our core proposals.
215
+ return bridgedCoreProposals;
185
216
  }
186
217
 
187
- await ensureSwingsetInitialized();
218
+ const coreProposals = await ensureSwingsetInitialized();
188
219
  const controller = await makeSwingsetController(
189
220
  kernelStorage,
190
221
  deviceEndowments,
@@ -202,6 +233,7 @@ export async function buildSwingset(
202
233
  // (either on bootstrap block (0) or in endBlock).
203
234
 
204
235
  return {
236
+ coreProposals,
205
237
  controller,
206
238
  mb: mailboxDevice,
207
239
  bridgeInbound: bridgeDevice && bridgeDevice.deliverInbound,
@@ -342,7 +374,13 @@ export async function launch({
342
374
  });
343
375
 
344
376
  console.debug(`buildSwingset`);
345
- const { controller, mb, bridgeInbound, timer } = await buildSwingset(
377
+ const {
378
+ coreProposals: bootstrapCoreProposals,
379
+ controller,
380
+ mb,
381
+ bridgeInbound,
382
+ timer,
383
+ } = await buildSwingset(
346
384
  mailboxStorage,
347
385
  bridgeOutbound,
348
386
  kernelStorage,
@@ -583,8 +621,7 @@ export async function launch({
583
621
  */
584
622
  async function processActions(inboundQueue, runSwingset) {
585
623
  let keepGoing = true;
586
- await null;
587
- for (const { action, context } of inboundQueue.consumeAll()) {
624
+ for await (const { action, context } of inboundQueue.consumeAll()) {
588
625
  const inboundNum = `${context.blockHeight}-${context.txHash}-${context.msgIdx}`;
589
626
  inboundQueueMetrics.decStat();
590
627
  await performAction(action, inboundNum);
@@ -741,111 +778,70 @@ export async function launch({
741
778
  });
742
779
  }
743
780
 
744
- // Handle block related actions
745
- // Some actions that are integration specific may be handled by the caller
746
- // For example SWING_STORE_EXPORT is handled in chain-main.js
747
- async function doBlockingSend(action) {
748
- await null;
749
- // blockManagerConsole.warn(
750
- // 'FIGME: blockHeight',
751
- // action.blockHeight,
752
- // 'received',
753
- // action.type,
754
- // );
755
- switch (action.type) {
756
- case ActionType.AG_COSMOS_INIT: {
757
- const { isBootstrap, upgradePlan, blockTime, params } = action;
758
- // This only runs for the very first block on the chain.
759
- if (isBootstrap) {
760
- verboseBlocks && blockManagerConsole.info('block bootstrap');
761
- (savedHeight === 0 && savedBeginHeight === 0) ||
762
- Fail`Cannot run a bootstrap block at height ${savedHeight}`;
763
- const bootstrapBlockParams = parseParams(params);
764
- const blockHeight = 0;
765
- controller.writeSlogObject({
766
- type: 'cosmic-swingset-bootstrap-block-start',
767
- blockTime,
768
- });
769
- // Start a block transaction, but without changing state
770
- // for the upcoming begin block check
771
- saveBeginHeight(savedBeginHeight);
772
- await processAction(action.type, async () =>
773
- bootstrapBlock(blockHeight, blockTime, bootstrapBlockParams),
774
- );
775
- controller.writeSlogObject({
776
- type: 'cosmic-swingset-bootstrap-block-finish',
777
- blockTime,
778
- });
779
- }
780
- if (upgradePlan) {
781
- const blockHeight = upgradePlan.height;
782
-
783
- // Process upgrade plan
784
- const upgradedAction = {
785
- type: ActionType.ENACTED_UPGRADE,
786
- upgradePlan,
787
- blockHeight,
788
- blockTime,
789
- };
790
- await doBlockingSend(upgradedAction);
791
- }
792
- return true;
793
- }
794
-
795
- case ActionType.ENACTED_UPGRADE: {
796
- // Install and execute new core proposals.
797
- const { upgradePlan, blockHeight, blockTime } = action;
781
+ const doBootstrap = async action => {
782
+ const { blockTime, blockHeight, params } = action;
783
+ controller.writeSlogObject({
784
+ type: 'cosmic-swingset-bootstrap-block-start',
785
+ blockTime,
786
+ });
798
787
 
799
- if (!blockNeedsExecution(blockHeight)) {
800
- return undefined;
801
- }
788
+ await null;
789
+ try {
790
+ verboseBlocks && blockManagerConsole.info('block bootstrap');
791
+ (savedHeight === 0 && savedBeginHeight === 0) ||
792
+ Fail`Cannot run a bootstrap block at height ${savedHeight}`;
793
+ const bootstrapBlockParams = parseParams(params);
794
+
795
+ // Start a block transaction, but without changing state
796
+ // for the upcoming begin block check
797
+ saveBeginHeight(savedBeginHeight);
798
+ await processAction(action.type, async () =>
799
+ bootstrapBlock(blockHeight, blockTime, bootstrapBlockParams),
800
+ );
801
+ } finally {
802
+ controller.writeSlogObject({
803
+ type: 'cosmic-swingset-bootstrap-block-finish',
804
+ blockTime,
805
+ });
806
+ }
807
+ };
802
808
 
803
- // Start a block transaction, but without changing state
804
- // for the upcoming begin block check
805
- saveBeginHeight(savedBeginHeight);
809
+ const doCoreProposals = async ({ blockHeight, blockTime }, coreProposals) => {
810
+ controller.writeSlogObject({
811
+ type: 'cosmic-swingset-upgrade-start',
812
+ blockHeight,
813
+ blockTime,
814
+ coreProposals,
815
+ });
806
816
 
807
- controller.writeSlogObject({
808
- type: 'cosmic-swingset-upgrade-start',
809
- blockHeight,
810
- blockTime,
811
- upgradePlan,
817
+ await null;
818
+ try {
819
+ // Start a block transaction, but without changing state
820
+ // for the upcoming begin block check
821
+ saveBeginHeight(savedBeginHeight);
822
+
823
+ // Find scripts relative to our location.
824
+ const myFilename = fileURLToPath(import.meta.url);
825
+ const { bundles, codeSteps: coreEvalCodeSteps } =
826
+ await extractCoreProposalBundles(coreProposals, myFilename, {
827
+ handleToBundleSpec: async (handle, source, _sequence, _piece) => {
828
+ const bundle = await bundleSource(source);
829
+ const { endoZipBase64Sha512: hash } = bundle;
830
+ const bundleID = `b1-${hash}`;
831
+ handle.bundleID = bundleID;
832
+ harden(handle);
833
+ return harden([`${bundleID}: ${source}`, bundle]);
834
+ },
812
835
  });
813
836
 
814
- const { info: upgradeInfoJson = null } = upgradePlan || {};
815
-
816
- const upgradePlanInfo =
817
- upgradeInfoJson &&
818
- parseLocatedJson(upgradeInfoJson, 'ENACTED_UPGRADE upgradePlan.info');
819
-
820
- // Handle the planned core proposals as just another action.
821
- const { coreProposals = [] } = upgradePlanInfo || {};
822
-
823
- if (!coreProposals.length) {
824
- // Nothing to do.
825
- return undefined;
826
- }
827
-
828
- // Find scripts relative to our location.
829
- const myFilename = fileURLToPath(import.meta.url);
830
- const { bundles, code: coreEvalCode } =
831
- await extractCoreProposalBundles(coreProposals, myFilename, {
832
- handleToBundleSpec: async (handle, source, _sequence, _piece) => {
833
- const bundle = await bundleSource(source);
834
- const { endoZipBase64Sha512: hash } = bundle;
835
- const bundleID = `b1-${hash}`;
836
- handle.bundleID = bundleID;
837
- harden(handle);
838
- return harden([`${bundleID}: ${source}`, bundle]);
839
- },
840
- });
841
-
842
- for (const [meta, bundle] of Object.entries(bundles)) {
843
- await controller
844
- .validateAndInstallBundle(bundle)
845
- .catch(e => Fail`Cannot validate and install ${meta}: ${e}`);
846
- }
837
+ for (const [meta, bundle] of Object.entries(bundles)) {
838
+ await controller
839
+ .validateAndInstallBundle(bundle)
840
+ .catch(e => Fail`Cannot validate and install ${meta}: ${e}`);
841
+ }
847
842
 
848
- // Now queue the code for evaluation.
843
+ // Now queue each step's code for evaluation.
844
+ for (const [key, coreEvalCode] of Object.entries(coreEvalCodeSteps)) {
849
845
  const coreEvalAction = {
850
846
  type: ActionType.CORE_EVAL,
851
847
  blockHeight,
@@ -861,18 +857,60 @@ export async function launch({
861
857
  context: {
862
858
  blockHeight,
863
859
  txHash: 'x/upgrade',
864
- msgIdx: 0,
860
+ msgIdx: key,
865
861
  },
866
862
  action: coreEvalAction,
867
863
  });
864
+ }
865
+ } finally {
866
+ controller.writeSlogObject({
867
+ type: 'cosmic-swingset-upgrade-finish',
868
+ blockHeight,
869
+ blockTime,
870
+ });
871
+ }
872
+ };
868
873
 
869
- controller.writeSlogObject({
870
- type: 'cosmic-swingset-upgrade-finish',
871
- blockHeight,
872
- blockTime,
873
- });
874
+ // Handle block related actions
875
+ // Some actions that are integration specific may be handled by the caller
876
+ // For example SWING_STORE_EXPORT is handled in chain-main.js
877
+ async function doBlockingSend(action) {
878
+ await null;
879
+ // blockManagerConsole.warn(
880
+ // 'FIGME: blockHeight',
881
+ // action.blockHeight,
882
+ // 'received',
883
+ // action.type,
884
+ // );
885
+ switch (action.type) {
886
+ case ActionType.AG_COSMOS_INIT: {
887
+ const { blockHeight, isBootstrap, upgradePlan } = action;
874
888
 
875
- return undefined;
889
+ if (!blockNeedsExecution(blockHeight)) {
890
+ return true;
891
+ }
892
+
893
+ let { coreProposals } = parseUpgradePlanInfo(
894
+ upgradePlan,
895
+ ActionType.AG_COSMOS_INIT,
896
+ );
897
+
898
+ if (isBootstrap) {
899
+ // This only runs for the very first block on the chain.
900
+ await doBootstrap(action);
901
+
902
+ // Merge the core proposals from the bootstrap block with the
903
+ // ones from the upgrade plan.
904
+ coreProposals = mergeCoreProposals(
905
+ bootstrapCoreProposals,
906
+ coreProposals,
907
+ );
908
+ }
909
+
910
+ if (coreProposals) {
911
+ await doCoreProposals(action, coreProposals);
912
+ }
913
+ return true;
876
914
  }
877
915
 
878
916
  case ActionType.COMMIT_BLOCK: {