From 6a9f533b5b9095768f25b5642e001fd6e9aa8b47 Mon Sep 17 00:00:00 2001 From: Kris Kowal Date: Tue, 7 Jun 2022 17:41:29 -0700 Subject: [PATCH] fix(cosmic-swingset): Publish installation success and failure topic --- golang/cosmos/x/swingset/keeper/keeper.go | 1 + packages/cosmic-swingset/package.json | 2 + packages/cosmic-swingset/src/block-manager.js | 43 ++++++++++++++++--- packages/cosmic-swingset/src/chain-main.js | 16 +++++++ packages/cosmic-swingset/src/launch-chain.js | 2 +- packages/vats/src/chain-storage-paths.js | 1 + 6 files changed, 59 insertions(+), 6 deletions(-) diff --git a/golang/cosmos/x/swingset/keeper/keeper.go b/golang/cosmos/x/swingset/keeper/keeper.go index e1bc662ec07..7ae71f872f1 100644 --- a/golang/cosmos/x/swingset/keeper/keeper.go +++ b/golang/cosmos/x/swingset/keeper/keeper.go @@ -26,6 +26,7 @@ const ( StoragePathEgress = "egress" StoragePathMailbox = "mailbox" StoragePathCustom = "published" + StoragePathBundles = "bundles" ) // Keeper maintains the link to data vstorage and exposes getter/setter methods for the various parts of the state machine diff --git a/packages/cosmic-swingset/package.json b/packages/cosmic-swingset/package.json index d66a89c075c..02b78ce1948 100644 --- a/packages/cosmic-swingset/package.json +++ b/packages/cosmic-swingset/package.json @@ -27,6 +27,7 @@ "@agoric/deploy-script-support": "^0.9.0", "@agoric/internal": "^0.1.0", "@agoric/nat": "^4.1.0", + "@agoric/notifier": "^0.4.0", "@agoric/store": "^0.7.2", "@agoric/swing-store": "^0.7.0", "@agoric/swingset-vat": "^0.28.0", @@ -36,6 +37,7 @@ "@endo/far": "^0.2.9", "@endo/import-bundle": "^0.2.51", "@endo/init": "^0.5.47", + "@endo/marshal": "^0.7.3", "@iarna/toml": "^2.2.3", "@opentelemetry/sdk-metrics-base": "^0.27.0", "agoric": "^0.16.0", diff --git a/packages/cosmic-swingset/src/block-manager.js b/packages/cosmic-swingset/src/block-manager.js index a828b2b6f88..b362843900a 100644 --- a/packages/cosmic-swingset/src/block-manager.js +++ b/packages/cosmic-swingset/src/block-manager.js @@ -2,12 +2,15 @@ /* global process */ import anylogger from 'anylogger'; +import { makeMarshal } from '@endo/marshal'; import { assert, details as X } from '@agoric/assert'; import { BridgeId as BRIDGE_ID } from '@agoric/internal'; - +import { makeStoredSubscriber, makePublishKit } from '@agoric/notifier'; import * as ActionType from './action-types.js'; import { parseParams } from './params.js'; +import '@agoric/notifier/exported.js'; + const console = anylogger('block-manager'); // Artificially create load if set. @@ -15,6 +18,8 @@ const END_BLOCK_SPIN_MS = process.env.END_BLOCK_SPIN_MS ? parseInt(process.env.END_BLOCK_SPIN_MS, 10) : 0; +/** @typedef {Record} InstallationNotification */ + export default function makeBlockManager({ actionQueue, deliverInbound, @@ -27,6 +32,7 @@ export default function makeBlockManager({ saveOutsideState, savedHeight, validateAndInstallBundle, + installationStorageNode = undefined, verboseBlocks = false, }) { let computedHeight = savedHeight; @@ -35,6 +41,9 @@ export default function makeBlockManager({ let latestParams; let beginBlockAction; + /** @type {PublishKit['publisher'] | undefined} */ + let installationPublisher; + async function processAction(action) { const start = Date.now(); const finish = res => { @@ -43,6 +52,16 @@ export default function makeBlockManager({ return res; }; + if ( + installationPublisher === undefined && + installationStorageNode !== undefined + ) { + const marshaller = makeMarshal(); + const { publisher, subscriber } = makePublishKit(); + makeStoredSubscriber(subscriber, installationStorageNode, marshaller); + installationPublisher = publisher; + } + // console.error('Performing action', action); let p; switch (action.type) { @@ -83,10 +102,24 @@ export default function makeBlockManager({ p = (async () => { const bundle = JSON.parse(action.bundle); harden(bundle); - return validateAndInstallBundle(bundle); - })().catch(error => { - console.error(error); - }); + + const error = await validateAndInstallBundle(bundle).then( + () => null, + (/** @type {unknown} */ errorValue) => errorValue, + ); + + const { endoZipBase64Sha512 } = bundle; + + if (installationPublisher !== undefined) { + installationPublisher.publish( + harden({ + endoZipBase64Sha512, + installed: error === null, + error, + }), + ); + } + })(); break; } diff --git a/packages/cosmic-swingset/src/chain-main.js b/packages/cosmic-swingset/src/chain-main.js index 59ae9f5040d..8ed1bd53b3b 100644 --- a/packages/cosmic-swingset/src/chain-main.js +++ b/packages/cosmic-swingset/src/chain-main.js @@ -15,7 +15,10 @@ import { makeBufferedStorage } from '@agoric/swingset-vat/src/lib/storageAPI.js' import { assert, details as X } from '@agoric/assert'; import { makeSlogSenderFromModule } from '@agoric/telemetry'; +import { makeChainStorageRoot } from '@agoric/vats/src/lib-chainStorage.js'; + import * as STORAGE_PATH from '@agoric/vats/src/chain-storage-paths.js'; +import { BridgeId as BRIDGE_ID } from '@agoric/internal'; import stringify from './json-stable-stringify.js'; import { launch } from './launch-chain.js'; import makeBlockManager from './block-manager.js'; @@ -502,14 +505,27 @@ export default async function main(progname, args, { env, homedir, agcc }) { portNums.lien = action.lienPort; } + // Ensure that initialization has completed. if (!blockingSend) { const { savedChainSends: scs, ...fns } = await launchAndInitializeSwingSet(action); + + const toStorage = message => { + return fns.bridgeOutbound(BRIDGE_ID.STORAGE, message); + }; + const installationStorageNode = makeChainStorageRoot( + toStorage, + 'swingset', + STORAGE_PATH.BUNDLES, + { sequence: true }, + ); + savedChainSends = scs; blockingSend = makeBlockManager({ ...fns, flushChainSends, verboseBlocks: true, + installationStorageNode, }); } diff --git a/packages/cosmic-swingset/src/launch-chain.js b/packages/cosmic-swingset/src/launch-chain.js index a5590693785..27c7868c25d 100644 --- a/packages/cosmic-swingset/src/launch-chain.js +++ b/packages/cosmic-swingset/src/launch-chain.js @@ -351,7 +351,7 @@ export async function launch({ actionQueue, deliverInbound, doBridgeInbound, - // bridgeOutbound, + bridgeOutbound, bootstrapBlock, beginBlock, endBlock, diff --git a/packages/vats/src/chain-storage-paths.js b/packages/vats/src/chain-storage-paths.js index c5841b24f85..c2d82a595ea 100644 --- a/packages/vats/src/chain-storage-paths.js +++ b/packages/vats/src/chain-storage-paths.js @@ -9,4 +9,5 @@ export const ACTIVITYHASH = 'activityhash'; export const BEANSOWING = 'beansOwing'; export const EGRESS = 'egress'; export const MAILBOX = 'mailbox'; +export const BUNDLES = 'bundles'; export const CUSTOM = 'published';