Skip to content

Commit

Permalink
feat: initializeSwingset snapshots XS supervisor
Browse files Browse the repository at this point in the history
  - add snapstore to SwingStore API
  • Loading branch information
dckc committed Apr 9, 2021
1 parent 6300770 commit dea5483
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 6 deletions.
4 changes: 0 additions & 4 deletions packages/SwingSet/src/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -395,9 +395,7 @@ export async function makeSwingsetController(
* debugPrefix?: string,
* slogCallbacks?: unknown,
* testTrackDecref?: unknown,
* snapstorePath?: string,
* }} runtimeOptions
* @typedef { import('@agoric/swing-store-simple').SwingStore } SwingStore
*/
export async function buildVatController(
config,
Expand All @@ -411,14 +409,12 @@ export async function buildVatController(
debugPrefix,
slogCallbacks,
testTrackDecref,
snapstorePath,
} = runtimeOptions;
const actualRuntimeOptions = {
verbose,
debugPrefix,
testTrackDecref,
slogCallbacks,
snapstorePath,
};
const initializationOptions = { verbose, kernelBundles };
let bootstrapResult;
Expand Down
36 changes: 35 additions & 1 deletion packages/SwingSet/src/initializeSwingset.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
// @ts-check
import fs from 'fs';
import path from 'path';
import { spawn } from 'child_process';
import { type as osType } from 'os';

import { assert, details as X } from '@agoric/assert';
import bundleSource from '@agoric/bundle-source';
import { initSwingStore } from '@agoric/swing-store-simple';

import { xsnap } from '@agoric/xsnap';
import { insistStorageAPI } from './storageAPI';
import { initializeKernel } from './kernel/initializeKernel';

Expand Down Expand Up @@ -214,6 +217,26 @@ export function swingsetIsInitialized(storage) {
return !!storage.get('initialized');
}

/**
* @param {Record<string, BundleGE>} bundles
* @param {ReturnType<typeof import('@agoric/xsnap').makeSnapstore>} snapstore
* @param {boolean} debug
* @typedef { any } BundleGE TODO: types for bundleSource
* @returns { Promise<string> } hash of supervisor snapshot
*/
async function snapshotSupervisor(bundles, snapstore, debug) {
const worker = xsnap({
handleCommand: async bytes => bytes,
spawn,
os: osType(),
debug,
});
await worker.evaluate(`(${bundles.lockdown.source}\n)()`);
await worker.evaluate(`(${bundles.supervisor.source}\n)()`);
const supervisorHash = await snapstore.save(async fn => worker.snapshot(fn));
return supervisorHash;
}

/**
* @param {SwingSetConfig} config
* @param {string[]} argv
Expand Down Expand Up @@ -248,7 +271,9 @@ export async function initializeSwingset(
}

// Use ambient process.env only if caller did not specify.
const { env: { SWINGSET_WORKER_TYPE } = process.env } = runtimeOptions;
const {
env: { SWINGSET_WORKER_TYPE, XSNAP_DEBUG } = process.env,
} = runtimeOptions;
const defaultManagerType = config.defaultManagerType || SWINGSET_WORKER_TYPE;
switch (defaultManagerType) {
case 'local':
Expand All @@ -270,6 +295,15 @@ export async function initializeSwingset(
hostStorage.set('lockdownBundle', JSON.stringify(kernelBundles.lockdown));
hostStorage.set('supervisorBundle', JSON.stringify(kernelBundles.supervisor));

if (hostStorage.snapstore) {
const supervisorHash = await snapshotSupervisor(
kernelBundles,
hostStorage.snapstore,
!!XSNAP_DEBUG,
);
hostStorage.set('supervisorHash', JSON.stringify(supervisorHash));
}

if (config.bootstrap && argv) {
const bootConfig = config.vats[config.bootstrap];
if (bootConfig) {
Expand Down
6 changes: 6 additions & 0 deletions packages/SwingSet/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,9 @@
*
* Swingsets defined by scanning a directory in this manner define no devices.
*/

/**
* @typedef { import('@agoric/swing-store-simple').SwingStore & {
* snapstore?: ReturnType<typeof import('@agoric/xsnap').makeSnapstore>
* }} SwingStore
*/
25 changes: 25 additions & 0 deletions packages/SwingSet/test/test-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
import { test } from '../tools/prepare-test-env-ava';

import path from 'path';
import fs from 'fs';
import { tmpName } from 'tmp';
import { initSwingStore } from '@agoric/swing-store-simple';
import { makeSnapstore } from '@agoric/xsnap';
import { buildVatController, loadBasedir } from '../src/index';
import { checkKT } from './util';

Expand Down Expand Up @@ -117,6 +120,28 @@ test('XS bootstrap', async t => {
);
});

test('SwingStore with snapstore', async t => {
const snapstorePath = path.resolve(__dirname, './fixture-xs-snapshots/');
fs.mkdirSync(snapstorePath, { recursive: true });

const kvStorage = initSwingStore().storage;

const snapstore = makeSnapstore(snapstorePath, {
tmpName,
existsSync: fs.existsSync,
createReadStream: fs.createReadStream,
createWriteStream: fs.createWriteStream,
rename: fs.promises.rename,
unlink: fs.promises.unlink,
resolve: path.resolve,
});
const hostStorage = { snapstore, ...kvStorage };
await buildVatController({}, [], { hostStorage });
const supervisorHash = hostStorage.get('supervisorHash');
t.is(typeof supervisorHash, 'string', 'supervisorHash is available');
t.is(supervisorHash.length, 66, 'supervisorHash is available');
});

test('validate config.defaultManagerType', async t => {
const config = await loadBasedir(
path.resolve(__dirname, 'basedir-controller-2'),
Expand Down
17 changes: 16 additions & 1 deletion packages/cosmic-swingset/lib/ag-solo/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import fs from 'fs';
import path from 'path';
import temp from 'temp';
import { tmpName } from 'tmp'; // TODO: reconcile tmp vs. temp
import { fork } from 'child_process';
import { promisify } from 'util';
// import { createHash } from 'crypto';
Expand All @@ -24,6 +25,7 @@ import {
buildPlugin,
buildTimer,
} from '@agoric/swingset-vat';
import { makeSnapstore } from '@agoric/xsnap';
import { getBestSwingStore } from '../check-lmdb';

import { deliver, addDeliveryTarget } from './outbound';
Expand Down Expand Up @@ -141,7 +143,20 @@ async function buildSwingset(

const tempdir = path.resolve(kernelStateDBDir, 'check-lmdb-tempdir');
const { openSwingStore } = getBestSwingStore(tempdir);
const { storage, commit } = openSwingStore(kernelStateDBDir);
const { storage: storage0, commit } = openSwingStore(kernelStateDBDir);
const snapstore = makeSnapstore(
path.resolve(kernelStateDBDir, 'xs-snapshots'),
{
tmpName,
existsSync: fs.existsSync,
createReadStream: fs.createReadStream,
createWriteStream: fs.createWriteStream,
rename: fs.promises.rename,
unlink: fs.promises.unlink,
resolve: path.resolve,
},
);
const storage = { snapstore, ...storage0 };

if (!swingsetIsInitialized(storage)) {
if (defaultManagerType && !config.defaultManagerType) {
Expand Down

0 comments on commit dea5483

Please sign in to comment.