@agoric/cosmic-swingset 0.41.4-dev-42d1d4f.0 → 0.41.4-dev-a7d06d8.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/cosmic-swingset",
3
- "version": "0.41.4-dev-42d1d4f.0+42d1d4f",
3
+ "version": "0.41.4-dev-a7d06d8.0+a7d06d8",
4
4
  "description": "Agoric's Cosmos blockchain integration",
5
5
  "type": "module",
6
6
  "bin": {
@@ -22,15 +22,15 @@
22
22
  "author": "Agoric",
23
23
  "license": "Apache-2.0",
24
24
  "dependencies": {
25
- "@agoric/builders": "0.1.1-dev-42d1d4f.0+42d1d4f",
26
- "@agoric/cosmos": "0.34.2-dev-42d1d4f.0+42d1d4f",
27
- "@agoric/deploy-script-support": "0.10.4-dev-42d1d4f.0+42d1d4f",
28
- "@agoric/internal": "0.3.3-dev-42d1d4f.0+42d1d4f",
29
- "@agoric/store": "0.9.3-dev-42d1d4f.0+42d1d4f",
30
- "@agoric/swing-store": "0.9.2-dev-42d1d4f.0+42d1d4f",
31
- "@agoric/swingset-vat": "0.32.3-dev-42d1d4f.0+42d1d4f",
32
- "@agoric/telemetry": "0.6.3-dev-42d1d4f.0+42d1d4f",
33
- "@agoric/vm-config": "0.1.1-dev-42d1d4f.0+42d1d4f",
25
+ "@agoric/builders": "0.1.1-dev-a7d06d8.0+a7d06d8",
26
+ "@agoric/cosmos": "0.34.2-dev-a7d06d8.0+a7d06d8",
27
+ "@agoric/deploy-script-support": "0.10.4-dev-a7d06d8.0+a7d06d8",
28
+ "@agoric/internal": "0.3.3-dev-a7d06d8.0+a7d06d8",
29
+ "@agoric/store": "0.9.3-dev-a7d06d8.0+a7d06d8",
30
+ "@agoric/swing-store": "0.9.2-dev-a7d06d8.0+a7d06d8",
31
+ "@agoric/swingset-vat": "0.32.3-dev-a7d06d8.0+a7d06d8",
32
+ "@agoric/telemetry": "0.6.3-dev-a7d06d8.0+a7d06d8",
33
+ "@agoric/vm-config": "0.1.1-dev-a7d06d8.0+a7d06d8",
34
34
  "@endo/bundle-source": "^3.3.0",
35
35
  "@endo/env-options": "^1.1.5",
36
36
  "@endo/errors": "^1.2.4",
@@ -70,5 +70,5 @@
70
70
  "typeCoverage": {
71
71
  "atLeast": 80.6
72
72
  },
73
- "gitHead": "42d1d4fa872b48c3851a66187cda08671a38c70c"
73
+ "gitHead": "a7d06d8884c22e8190916d0bb1454bf9f5e92b57"
74
74
  }
package/src/chain-main.js CHANGED
@@ -48,6 +48,8 @@ import {
48
48
  validateImporterOptions,
49
49
  } from './import-kernel-db.js';
50
50
 
51
+ const ignore = () => {};
52
+
51
53
  // eslint-disable-next-line no-unused-vars
52
54
  let whenHellFreezesOver = null;
53
55
 
@@ -62,6 +64,32 @@ const toNumber = specimen => {
62
64
  return number;
63
65
  };
64
66
 
67
+ /**
68
+ * A boot message consists of cosmosInitAction fields that are subject to
69
+ * consensus. See cosmosInitAction in {@link ../../../golang/cosmos/app/app.go}.
70
+ *
71
+ * @param {any} initAction
72
+ */
73
+ const makeBootMsg = initAction => {
74
+ const {
75
+ type,
76
+ blockTime,
77
+ blockHeight,
78
+ chainID,
79
+ params,
80
+ // NB: resolvedConfig is independent of consensus and MUST NOT be included
81
+ supplyCoins,
82
+ } = initAction;
83
+ return {
84
+ type,
85
+ blockTime,
86
+ blockHeight,
87
+ chainID,
88
+ params,
89
+ supplyCoins,
90
+ };
91
+ };
92
+
65
93
  /**
66
94
  * @template {unknown} [T=unknown]
67
95
  * @param {(req: string) => string} call
@@ -214,7 +242,7 @@ export default async function main(progname, args, { env, homedir, agcc }) {
214
242
 
215
243
  const clearChainSends = async () => {
216
244
  // Cosmos should have blocked before calling commit, but wait just in case
217
- await stateSyncExport?.exporter?.onStarted().catch(() => {});
245
+ await stateSyncExport?.exporter?.onStarted().catch(ignore);
218
246
 
219
247
  const chainSends = savedChainSends;
220
248
  savedChainSends = [];
@@ -246,10 +274,15 @@ export default async function main(progname, args, { env, homedir, agcc }) {
246
274
  /** @type {((obj: object) => void) | undefined} */
247
275
  let writeSlogObject;
248
276
 
249
- // the storagePort used to change for every single message. It's defined out
277
+ // In the past, storagePort could change with every message. It's defined out
250
278
  // here so 'sendToChainStorage' can close over the single mutable instance,
251
279
  // when we updated the 'portNums.storage' value each time toSwingSet was called.
252
- async function launchAndInitializeSwingSet(bootMsg) {
280
+ async function launchAndInitializeSwingSet(initAction) {
281
+ // As a kludge, back-propagate selected configuration into environment variables.
282
+ const { slogfile } = initAction.resolvedConfig || {};
283
+ // eslint-disable-next-line dot-notation
284
+ if (slogfile) env['SLOGFILE'] = slogfile;
285
+
253
286
  const sendToChainStorage = msg => chainSend(portNums.storage, msg);
254
287
  // this object is used to store the mailbox state.
255
288
  const fromBridgeMailbox = data => {
@@ -363,7 +396,7 @@ export default async function main(progname, args, { env, homedir, agcc }) {
363
396
  };
364
397
 
365
398
  const argv = {
366
- bootMsg,
399
+ bootMsg: makeBootMsg(initAction),
367
400
  };
368
401
  const getVatConfig = async () => {
369
402
  const vatHref = await importMetaResolve(
@@ -489,21 +522,19 @@ export default async function main(progname, args, { env, homedir, agcc }) {
489
522
 
490
523
  let pendingBlockingSend = Promise.resolve();
491
524
 
492
- registerShutdown(async interrupted =>
493
- Promise.all([
525
+ registerShutdown(async interrupted => {
526
+ await Promise.all([
494
527
  interrupted && pendingBlockingSend.then(shutdown),
495
528
  discardStateSyncExport(),
496
- ]).then(() => {}),
497
- );
529
+ ]);
530
+ });
498
531
 
499
- return async action => {
532
+ const blockingSendSpy = async action => {
500
533
  const result = blockingSend(action);
501
- pendingBlockingSend = Promise.resolve(result).then(
502
- () => {},
503
- () => {},
504
- );
534
+ pendingBlockingSend = Promise.resolve(result).then(ignore, ignore);
505
535
  return result;
506
536
  };
537
+ return blockingSendSpy;
507
538
  }
508
539
 
509
540
  /** @type {Awaited<ReturnType<typeof launch>>['blockingSend'] | undefined} */
@@ -658,6 +689,7 @@ export default async function main(progname, args, { env, homedir, agcc }) {
658
689
 
659
690
  !blockingSend || Fail`Swingset already initialized`;
660
691
 
692
+ // Capture "port numbers" for communicating with cosmos modules.
661
693
  for (const [key, value] of Object.entries(action)) {
662
694
  const portAlias = CosmosInitKeyToBridgeId[key];
663
695
  if (portAlias) {
@@ -214,7 +214,7 @@ export async function buildSwingset(
214
214
  return bridgedCoreProposals;
215
215
  }
216
216
 
217
- const coreProposals = await ensureSwingsetInitialized();
217
+ const pendingCoreProposals = await ensureSwingsetInitialized();
218
218
  upgradeSwingset(kernelStorage);
219
219
  const controller = await makeSwingsetController(
220
220
  kernelStorage,
@@ -233,7 +233,7 @@ export async function buildSwingset(
233
233
  // (either on bootstrap block (0) or in endBlock).
234
234
 
235
235
  return {
236
- coreProposals,
236
+ coreProposals: pendingCoreProposals,
237
237
  controller,
238
238
  mb: mailboxDevice,
239
239
  bridgeInbound: bridgeDevice.deliverInbound,
@@ -568,8 +568,15 @@ export async function launch({
568
568
  let savedBeginHeight = Number(
569
569
  kvStore.get(getHostKey('beginHeight')) || savedHeight,
570
570
  );
571
+ /**
572
+ * duration of the latest swingset execution in either END_BLOCK or
573
+ * once-per-chain bootstrap (the latter excluding "bridged" core proposals
574
+ * that run outside the bootstrap vat)
575
+ */
571
576
  let runTime = 0;
577
+ /** duration of the latest saveChainState(), which commits mailbox data to chain storage */
572
578
  let chainTime;
579
+ /** duration of the latest saveOutsideState(), which commits to swing-store host storage */
573
580
  let saveTime = 0;
574
581
  let endBlockFinish = 0;
575
582
  let blockParams;
@@ -724,33 +731,16 @@ export async function launch({
724
731
 
725
732
  /**
726
733
  * @template T
727
- * @param {string} type
734
+ * @param {string} label
728
735
  * @param {() => Promise<T>} fn
736
+ * @param {() => void} onSettled
729
737
  */
730
- async function processAction(type, fn) {
731
- const start = Date.now();
732
- const finish = res => {
733
- // blockManagerConsole.error(
734
- // 'Action',
735
- // action.type,
736
- // action.blockHeight,
737
- // 'is done!',
738
- // );
739
- runTime += Date.now() - start;
740
- return res;
741
- };
742
-
738
+ function withErrorLogging(label, fn, onSettled) {
743
739
  const p = fn();
744
- // Just attach some callbacks, but don't use the resulting neutered result
745
- // promise.
746
- void E.when(p, finish, e => {
747
- // None of these must fail, and if they do, log them verbosely before
748
- // returning to the chain.
749
- blockManagerConsole.error(type, 'error:', e);
750
- finish();
740
+ void E.when(p, onSettled, err => {
741
+ blockManagerConsole.error(label, 'error:', err);
742
+ onSettled();
751
743
  });
752
- // Return the original promise so that the caller gets the original
753
- // resolution or rejection.
754
744
  return p;
755
745
  }
756
746
 
@@ -821,8 +811,13 @@ export async function launch({
821
811
  // Start a block transaction, but without changing state
822
812
  // for the upcoming begin block check
823
813
  saveBeginHeight(savedBeginHeight);
824
- await processAction(action.type, async () =>
825
- bootstrapBlock(blockHeight, blockTime, bootstrapBlockParams),
814
+ const start = Date.now();
815
+ await withErrorLogging(
816
+ action.type,
817
+ () => bootstrapBlock(blockHeight, blockTime, bootstrapBlockParams),
818
+ () => {
819
+ runTime += Date.now() - start;
820
+ },
826
821
  );
827
822
  } finally {
828
823
  controller.writeSlogObject({
@@ -927,17 +922,16 @@ export async function launch({
927
922
  await doBootstrap(action);
928
923
  }
929
924
 
930
- // Merge the core proposals from the bootstrap block with the
931
- // ones from the upgrade.
925
+ // Concatenate together any pending core proposals from chain bootstrap
926
+ // with any from this inbound init action, then execute them all.
932
927
  const coreProposals = mergeCoreProposals(
933
928
  bootstrapCoreProposals,
934
929
  softwareUpgradeCoreProposals,
935
930
  upgradeInfoCoreProposals,
936
931
  );
937
-
938
932
  if (coreProposals.steps.length) {
939
- upgradeDetails ||
940
- isBootstrap ||
933
+ isBootstrap ||
934
+ upgradeDetails ||
941
935
  Fail`Unexpected core proposals outside of consensus start`;
942
936
  await doCoreProposals(action, coreProposals);
943
937
  }
@@ -964,9 +958,9 @@ export async function launch({
964
958
  });
965
959
 
966
960
  // Save the kernel's computed state just before the chain commits.
967
- const start2 = Date.now();
961
+ const start = Date.now();
968
962
  await saveOutsideState(savedHeight);
969
- saveTime = Date.now() - start2;
963
+ saveTime = Date.now() - start;
970
964
 
971
965
  blockParams = undefined;
972
966
 
@@ -1064,14 +1058,19 @@ export async function launch({
1064
1058
 
1065
1059
  provideInstallationPublisher();
1066
1060
 
1067
- await processAction(action.type, async () =>
1068
- endBlock(blockHeight, blockTime, blockParams),
1061
+ const start = Date.now();
1062
+ await withErrorLogging(
1063
+ action.type,
1064
+ () => endBlock(blockHeight, blockTime, blockParams),
1065
+ () => {
1066
+ runTime += Date.now() - start;
1067
+ },
1069
1068
  );
1070
1069
 
1071
1070
  // We write out our on-chain state as a number of chainSends.
1072
- const start = Date.now();
1071
+ const start2 = Date.now();
1073
1072
  await saveChainState();
1074
- chainTime = Date.now() - start;
1073
+ chainTime = Date.now() - start2;
1075
1074
 
1076
1075
  // Advance our saved state variables.
1077
1076
  savedHeight = blockHeight;