From 92b63b6105c055b14bb5412c9ebf12f213896244 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Wed, 10 Mar 2021 18:55:19 -0800 Subject: [PATCH] fix(cosmic-swingset): apply Far/Data as necessary (#2567) Annotate cosmic-swingset objects with Far or Data. We didn't try to mark everything. Instead, we marked everything we could easily find and which seemed like it was important to mark (ambiguous empty objects). Also, we changed `store` to reject empty pass-by-copy objects as keys, and we marked enough empty objects to survive that check, which ought to be enough for the immediate goal (changing `{}` to be pass-by-copy). We'll defer the other half of #2018 (requiring Far on all pass-by-reference objects) for later. refs #2018 --- .../lib/ag-solo/vats/bootstrap.js | 23 ++++++++++--------- .../lib/ag-solo/vats/bridge.js | 5 ++-- .../cosmic-swingset/lib/ag-solo/vats/captp.js | 3 ++- .../cosmic-swingset/lib/ag-solo/vats/ibc.js | 7 +++--- .../lib/ag-solo/vats/lib-board.js | 3 ++- .../lib/ag-solo/vats/vat-board.js | 3 ++- .../lib/ag-solo/vats/vat-host.js | 5 ++-- .../lib/ag-solo/vats/vat-http.js | 9 ++++---- .../lib/ag-solo/vats/vat-ibc.js | 3 ++- .../lib/ag-solo/vats/vat-mints.js | 3 ++- .../lib/ag-solo/vats/vat-network.js | 2 +- .../lib/ag-solo/vats/vat-priceAuthority.js | 3 ++- .../lib/ag-solo/vats/vat-provisioning.js | 5 ++-- .../lib/ag-solo/vats/vat-registrar.js | 3 ++- .../lib/ag-solo/vats/vat-sharing.js | 3 ++- .../lib/ag-solo/vats/vat-uploads.js | 3 ++- .../lib/ag-solo/vats/vat-zoe.js | 3 ++- packages/cosmic-swingset/test/test-home.js | 3 ++- .../test/unitTests/test-lib-board.js | 5 ++-- 19 files changed, 56 insertions(+), 38 deletions(-) diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/bootstrap.js b/packages/cosmic-swingset/lib/ag-solo/vats/bootstrap.js index f494e6f7725..53d54b69909 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/bootstrap.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/bootstrap.js @@ -5,6 +5,7 @@ import { makeEchoConnectionHandler, } from '@agoric/swingset-vat/src/vats/network'; import { E } from '@agoric/eventual-send'; +import { Far } from '@agoric/marshal'; // this will return { undefined } until `ag-solo set-gci-ingress` // has been run to update gci.js @@ -24,7 +25,7 @@ const PROVISIONER_INDEX = 1; function makeVattpFrom(vats) { const { vattp, comms } = vats; - return harden({ + return Far('vattp', { makeNetworkHost(allegedName, console = undefined) { return E(vattp).makeNetworkHost(allegedName, comms, console); }, @@ -205,7 +206,7 @@ export function buildRootObject(vatPowers, vatParameters) { }), ); - return harden({ + return Far('chainBundler', { async createUserBundle(_nickname, powerFlags = []) { // Bind to some fresh ports (unspecified name) on the IBC implementation // and provide them for the user to have. @@ -238,12 +239,12 @@ export function buildRootObject(vatPowers, vatParameters) { pursePetname: issuerNameToRecord.get(issuerName).pursePetname, })); - const faucet = { + const faucet = Far('faucet', { // A method to reap the spoils of our on-chain provisioning. async tapFaucet() { return paymentInfo; }, - }; + }); const bundle = harden({ ...additionalPowers, @@ -275,7 +276,7 @@ export function buildRootObject(vatPowers, vatParameters) { ); if (bridgeMgr) { // We have access to the bridge, and therefore IBC. - const callbacks = harden({ + const callbacks = Far('callbacks', { downcall(method, obj) { return bridgeMgr.toBridge('dibc', { ...obj, @@ -304,7 +305,7 @@ export function buildRootObject(vatPowers, vatParameters) { // Add an echo listener on our ibc-port network. const port = await E(vats.network).bind('/ibc-port/echo'); E(port).addListener( - harden({ + Far('listener', { async onAccept(_port, _localAddr, _remoteAddr, _listenHandler) { return harden(makeEchoConnectionHandler()); }, @@ -314,7 +315,7 @@ export function buildRootObject(vatPowers, vatParameters) { if (bridgeMgr) { // Register a provisioning handler over the bridge. - const handler = harden({ + const handler = Far('provisioningHandler', { async fromBridge(_srcID, obj) { switch (obj.type) { case 'PLEASE_PROVISION': { @@ -355,7 +356,7 @@ export function buildRootObject(vatPowers, vatParameters) { } // This will allow dApp developers to register in their api/deploy.js - const httpRegCallback = { + const httpRegCallback = Far('httpRegCallback', { doneLoading(subsystems) { return E(vats.http).doneLoading(subsystems); }, @@ -378,7 +379,7 @@ export function buildRootObject(vatPowers, vatParameters) { E(vats.http).setWallet(wallet), ]); }, - }; + }); return allComparable( harden({ @@ -395,7 +396,7 @@ export function buildRootObject(vatPowers, vatParameters) { ); } - return harden({ + return Far('root', { async bootstrap(vats, devices) { const bridgeManager = devices.bridge && makeBridgeManager(E, D, devices.bridge); @@ -494,7 +495,7 @@ export function buildRootObject(vatPowers, vatParameters) { // Allow some hardcoded client address connections into the chain. // This is necessary for fake-chain, which does not have Cosmos SDK // transactions to provision its client. - const demoProvider = harden({ + const demoProvider = Far('demoProvider', { // build a chain-side bundle for a client. async getDemoBundle(nickname) { if (giveMeAllTheAgoricPowers) { diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/bridge.js b/packages/cosmic-swingset/lib/ag-solo/vats/bridge.js index d98fd323851..4d94f7aca34 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/bridge.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/bridge.js @@ -3,6 +3,7 @@ import makeStore from '@agoric/store'; import '@agoric/store/exported'; import { assert, details as X } from '@agoric/assert'; +import { Far } from '@agoric/marshal'; /** * @template T @@ -53,7 +54,7 @@ export function makeBridgeManager(E, D, bridgeDevice) { // No return value. } - const bridgeHandler = harden({ inbound: bridgeInbound }); + const bridgeHandler = Far('bridgeHandler', { inbound: bridgeInbound }); function callOutbound(dstID, obj) { assert(bridgeDevice, X`bridge device not yet connected`); @@ -70,7 +71,7 @@ export function makeBridgeManager(E, D, bridgeDevice) { // We now manage the device. D(bridgeDevice).registerInboundHandler(bridgeHandler); - return harden({ + return Far('bridgeManager', { toBridge(dstID, obj) { return callOutbound(dstID, obj); }, diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/captp.js b/packages/cosmic-swingset/lib/ag-solo/vats/captp.js index 143ccb32f42..3c2ed577d8e 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/captp.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/captp.js @@ -2,6 +2,7 @@ // in its own makeHardener, etc. import { makeCapTP } from '@agoric/captp/lib/captp'; import { E } from '@agoric/eventual-send'; +import { Data } from '@agoric/marshal'; export const getCapTPHandler = ( send, @@ -11,7 +12,7 @@ export const getCapTPHandler = ( const chans = new Map(); const doFallback = async (method, ...args) => { if (!fallback) { - return {}; + return Data({}); } return E(fallback)[method](...args); }; diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/ibc.js b/packages/cosmic-swingset/lib/ag-solo/vats/ibc.js index cb21305cb13..022486501be 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/ibc.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/ibc.js @@ -8,6 +8,7 @@ import { import makeStore from '@agoric/store'; import { makePromiseKit } from '@agoric/promise-kit'; import { assert, details as X } from '@agoric/assert'; +import { Far } from '@agoric/marshal'; import '@agoric/store/exported'; import '@agoric/swingset-vat/src/vats/network/types'; @@ -176,7 +177,7 @@ export function makeIBCProtocolHandler(E, rawCallIBCDevice) { onReceive = withChannelReceiveQueue(onReceive); } - return harden({ + return Far('IBCConnectionHandler', { async onOpen(conn, localAddr, remoteAddr, _handler) { console.debug( 'onOpen Remote IBC Connection', @@ -244,7 +245,7 @@ export function makeIBCProtocolHandler(E, rawCallIBCDevice) { /** * @type {ProtocolHandler} */ - const protocol = harden({ + const protocol = Far('ProtocolHandler', { async onCreate(impl, _protocolHandler) { console.debug('IBC onCreate'); protocolImpl = impl; @@ -378,7 +379,7 @@ EOF }, }); - return harden({ + return Far('IBCProtocolHandler', { ...protocol, async fromBridge(srcID, obj) { console.info('IBC fromBridge', srcID, obj); diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/lib-board.js b/packages/cosmic-swingset/lib/ag-solo/vats/lib-board.js index eed4db85abd..a5115ad5d3a 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/lib-board.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/lib-board.js @@ -2,6 +2,7 @@ import { generateSparseInts } from '@agoric/sparse-ints'; import { assert, details as X, q } from '@agoric/assert'; +import { Far } from '@agoric/marshal'; import makeStore from '@agoric/store'; import { models as crcmodels } from 'polycrc'; @@ -40,7 +41,7 @@ function makeBoard(seed = 0) { const sparseInts = generateSparseInts(seed); /** @type {Board} */ - const board = harden({ + const board = Far('Board', { // Add if not already present getId: value => { if (!valToId.has(value)) { diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/vat-board.js b/packages/cosmic-swingset/lib/ag-solo/vats/vat-board.js index 3f5031bcad8..95bf344be02 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/vat-board.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/vat-board.js @@ -1,6 +1,7 @@ +import { Far } from '@agoric/marshal'; import { makeBoard } from './lib-board'; export function buildRootObject(_vatPowers) { const board = makeBoard(); - return harden({ getBoard: () => board }); + return Far('board', { getBoard: () => board }); } diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/vat-host.js b/packages/cosmic-swingset/lib/ag-solo/vats/vat-host.js index f43b82a9811..0a5c9eb7b89 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/vat-host.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/vat-host.js @@ -1,11 +1,12 @@ // Copyright (C) 2018 Agoric, under Apache License 2.0 +import { Far } from '@agoric/marshal'; import { makeContractHost } from '@agoric/spawner'; export function buildRootObject(vatPowers) { - return harden({ + return Far('root', { makeHost() { - return harden(makeContractHost(vatPowers)); + return makeContractHost(vatPowers); }, }); } diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/vat-http.js b/packages/cosmic-swingset/lib/ag-solo/vats/vat-http.js index f687a57f51a..b55437dee9a 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/vat-http.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/vat-http.js @@ -1,5 +1,6 @@ import { makeNotifierKit } from '@agoric/notifier'; import { E } from '@agoric/eventual-send'; +import { Far } from '@agoric/marshal'; import { assert, details as X } from '@agoric/assert'; import { getReplHandler } from './repl'; import { getCapTPHandler } from './captp'; @@ -71,7 +72,7 @@ export function buildRootObject(vatPowers) { urlToHandler.set(url, commandHandler); } - return harden({ + return Far('root', { setCommandDevice(d) { commandDevice = d; @@ -79,7 +80,7 @@ export function buildRootObject(vatPowers) { registerURLHandler(replHandler, '/private/repl'); // Assign the captp handler. - const captpHandler = harden({ + const captpHandler = Far('captpHandler', { getBootstrap(_otherSide, _meta) { // Harden only our exported objects, and fetch them afresh each time. return harden(exportedToCapTP); @@ -113,7 +114,7 @@ export function buildRootObject(vatPowers) { ...decentralObjects, // TODO: Remove; replaced by .agoric ...privateObjects, // TODO: Remove; replaced by .local ...handyObjects, - agoric: { ...decentralObjects }, + agoric: { ...decentralObjects }, // TODO: maybe needs Data()??? local: { ...privateObjects }, }; @@ -161,7 +162,7 @@ export function buildRootObject(vatPowers) { try { let channelHandle = channelIdToHandle.get(rawChannelID); if (dispatcher === 'onOpen') { - channelHandle = harden({}); + channelHandle = Far('channelHandle'); channelIdToHandle.set(rawChannelID, channelHandle); channelHandleToId.set(channelHandle, rawChannelID); } else if (dispatcher === 'onClose') { diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/vat-ibc.js b/packages/cosmic-swingset/lib/ag-solo/vats/vat-ibc.js index d2d1704d683..c06fdcef161 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/vat-ibc.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/vat-ibc.js @@ -1,3 +1,4 @@ +import { Far } from '@agoric/marshal'; import { E } from '@agoric/eventual-send'; import { makeIBCProtocolHandler } from './ibc'; @@ -10,7 +11,7 @@ export function buildRootObject(_vatPowers) { ); return harden(ibcHandler); } - return harden({ + return Far('root', { createInstance, }); } diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/vat-mints.js b/packages/cosmic-swingset/lib/ag-solo/vats/vat-mints.js index 82e9aaac2ec..107eb66c8dd 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/vat-mints.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/vat-mints.js @@ -1,3 +1,4 @@ +import { Far } from '@agoric/marshal'; import { makeIssuerKit } from '@agoric/ertp'; import makeStore from '@agoric/store'; @@ -8,7 +9,7 @@ import makeStore from '@agoric/store'; export function buildRootObject(_vatPowers) { const mintsAndMath = makeStore('issuerName'); - const api = harden({ + const api = Far('api', { getAllIssuerNames: () => mintsAndMath.keys(), getIssuer: issuerName => { const mint = mintsAndMath.get(issuerName); diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/vat-network.js b/packages/cosmic-swingset/lib/ag-solo/vats/vat-network.js index 139346c1b43..19fed98197a 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/vat-network.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/vat-network.js @@ -3,5 +3,5 @@ import { E } from '@agoric/eventual-send'; import { makeRouterProtocol } from '@agoric/swingset-vat/src/vats/network/router'; export function buildRootObject(_vatPowers) { - return harden(makeRouterProtocol(E)); + return makeRouterProtocol(E); // already Far('Router') } diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/vat-priceAuthority.js b/packages/cosmic-swingset/lib/ag-solo/vats/vat-priceAuthority.js index a4e1a3d7ba6..b3dfc5353a0 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/vat-priceAuthority.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/vat-priceAuthority.js @@ -1,9 +1,10 @@ +import { Far } from '@agoric/marshal'; import { makePriceAuthorityRegistry } from '@agoric/zoe/tools/priceAuthorityRegistry'; import { makeFakePriceAuthority } from '@agoric/zoe/tools/fakePriceAuthority'; import { makeLocalAmountMath } from '@agoric/ertp'; export function buildRootObject(_vatPowers) { - return harden({ + return Far('root', { makePriceAuthority: makePriceAuthorityRegistry, async makeFakePriceAuthority(options) { const { issuerIn, issuerOut } = options; diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/vat-provisioning.js b/packages/cosmic-swingset/lib/ag-solo/vats/vat-provisioning.js index c5db6234ba8..e29de6ce383 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/vat-provisioning.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/vat-provisioning.js @@ -1,4 +1,5 @@ import { E } from '@agoric/eventual-send'; +import { Far } from '@agoric/marshal'; // This vat contains the controller-side provisioning service. To enable local // testing, it is loaded by both the controller and other ag-solo vat machines. @@ -16,7 +17,7 @@ export function buildRootObject(_vatPowers) { async function pleaseProvision(nickname, pubkey, powerFlags) { let chainBundle; - const fetch = harden({ + const fetch = Far('fetch', { getDemoBundle() { return chainBundle; }, @@ -35,5 +36,5 @@ export function buildRootObject(_vatPowers) { return { ingressIndex: INDEX }; } - return harden({ register, pleaseProvision }); + return Far('root', { register, pleaseProvision }); } diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/vat-registrar.js b/packages/cosmic-swingset/lib/ag-solo/vats/vat-registrar.js index 16da2ea41ed..811e0d9669f 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/vat-registrar.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/vat-registrar.js @@ -1,3 +1,4 @@ +import { Far } from '@agoric/marshal'; import { makeRegistrar } from '@agoric/registrar'; // This vat contains the registrar for the demo. @@ -9,5 +10,5 @@ export function buildRootObject(_vatPowers) { return sharedRegistrar; } - return harden({ getSharedRegistrar }); + return Far('root', { getSharedRegistrar }); } diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/vat-sharing.js b/packages/cosmic-swingset/lib/ag-solo/vats/vat-sharing.js index 3c714ddf107..350f9d6fae8 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/vat-sharing.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/vat-sharing.js @@ -1,3 +1,4 @@ +import { Far } from '@agoric/marshal'; import { makeSharingService } from '@agoric/sharing-service'; // This vat contains the sharing service for the demo. @@ -9,5 +10,5 @@ export function buildRootObject(_vatPowers) { return sharingService; } - return harden({ getSharingService }); + return Far('root', { getSharingService }); } diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/vat-uploads.js b/packages/cosmic-swingset/lib/ag-solo/vats/vat-uploads.js index 3be4ba64433..e0c12e333c7 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/vat-uploads.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/vat-uploads.js @@ -1,3 +1,4 @@ +import { Far } from '@agoric/marshal'; import makeScratchPad from './scratch'; // This vat contains the private upload scratch pad. @@ -9,5 +10,5 @@ export function buildRootObject(_vatPowers) { return uploads; } - return harden({ getUploads }); + return Far('root', { getUploads }); } diff --git a/packages/cosmic-swingset/lib/ag-solo/vats/vat-zoe.js b/packages/cosmic-swingset/lib/ag-solo/vats/vat-zoe.js index f07315dd0c6..c2564f40335 100644 --- a/packages/cosmic-swingset/lib/ag-solo/vats/vat-zoe.js +++ b/packages/cosmic-swingset/lib/ag-solo/vats/vat-zoe.js @@ -1,7 +1,8 @@ +import { Far } from '@agoric/marshal'; import { makeZoe } from '@agoric/zoe'; export function buildRootObject(_vatPowers, vatParameters) { - return harden({ + return Far('root', { buildZoe: adminVat => makeZoe(adminVat, vatParameters.zcfBundleName), }); } diff --git a/packages/cosmic-swingset/test/test-home.js b/packages/cosmic-swingset/test/test-home.js index df65e90a609..46e50bf029a 100644 --- a/packages/cosmic-swingset/test/test-home.js +++ b/packages/cosmic-swingset/test/test-home.js @@ -2,6 +2,7 @@ import '@agoric/install-ses'; import test from 'ava'; import bundleSource from '@agoric/bundle-source'; +import { Far } from '@agoric/marshal'; import { makeFixture, E } from './captp-fixture'; @@ -44,7 +45,7 @@ test.serial('home.board', async t => { `using a non-verified id throws`, ); - const myValue = {}; + const myValue = Far('myValue', {}); const myId = await E(board).getId(myValue); t.is(typeof myId, 'string', `board key is string`); diff --git a/packages/cosmic-swingset/test/unitTests/test-lib-board.js b/packages/cosmic-swingset/test/unitTests/test-lib-board.js index e7b30f05352..696a621da60 100644 --- a/packages/cosmic-swingset/test/unitTests/test-lib-board.js +++ b/packages/cosmic-swingset/test/unitTests/test-lib-board.js @@ -3,13 +3,14 @@ import '@agoric/install-ses'; import test from 'ava'; +import { Far } from '@agoric/marshal'; import { makeBoard } from '../../lib/ag-solo/vats/lib-board'; test('makeBoard', async t => { const board = makeBoard(); - const obj1 = harden({}); - const obj2 = harden({}); + const obj1 = Far('obj1', {}); + const obj2 = Far('obj2', {}); t.deepEqual(board.ids(), [], `board is empty to start`);