Skip to content

Commit

Permalink
feat(cosmic-swingset): add repair-metadata snapshot restore option
Browse files Browse the repository at this point in the history
  • Loading branch information
mhofman committed Aug 10, 2023
1 parent ce6daeb commit 1da112d
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 8 deletions.
2 changes: 1 addition & 1 deletion golang/cosmos/x/swingset/keeper/extension_snapshotter.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,6 @@ func (snapshotter *ExtensionSnapshotter) RestoreExtension(blockHeight uint64, fo

return snapshotter.swingStoreExportsHandler.RestoreExport(
SwingStoreExportProvider{BlockHeight: blockHeight, GetExportDataReader: getExportDataReader, ReadArtifact: readArtifact},
SwingStoreRestoreOptions{ArtifactMode: SwingStoreArtifactModeReplay},
SwingStoreRestoreOptions{ArtifactMode: SwingStoreArtifactModeReplay, ExportDataMode: SwingStoreExportDataModeAll},
)
}
15 changes: 12 additions & 3 deletions golang/cosmos/x/swingset/keeper/swing_store_exports_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@ const (
// an export. ArtifactMode cannot be "none" in this case.
SwingStoreExportDataModeSkip = "skip"

// SwingStoreRepairMetadataExportDataMode indicates the "export data" should be
// used to repair the metadata of an existing swing-store for an import
// operation. ArtifactMode must be "none" in this case.
SwingStoreRepairMetadataExportDataMode = "repair-metadata"

// SwingStoreExportDataModeAll indicates "export data" should be part of the
// export or import. For import, ArtifactMode cannot be "none".
SwingStoreExportDataModeAll = "all"
Expand All @@ -211,6 +216,11 @@ type SwingStoreRestoreOptions struct {
// Use SwingStore*ArtifactMode const
// See packages/cosmic-swingset/src/import-kernel-db.js performStateSyncImport
ArtifactMode string `json:"artifactMode,omitempty"`
// ExportDataMode can be or "all" of "repair-metadata". It selects the purpose
// of the restore, to recreate a swing-store, or just to import missing metadata.
// If "repair-metadata", ArtifactMode should be "none". If "all", ArtifactMode
// must be at least "operational". Use SwingStoreExportDataMode* const
ExportDataMode string `json:"exportDataMode,omitempty"`
}

type swingStoreImportOptions struct {
Expand All @@ -219,8 +229,7 @@ type swingStoreImportOptions struct {
ExportDir string `json:"exportDir"`
// ArtifactMode is a copy of SwingStoreRestoreOptions.ArtifactMode
ArtifactMode string `json:"artifactMode,omitempty"`
// ExportDataMode must currently be "all" for import, since "export data" is
// needed to restore a swing-store.
// ExportDataMode is a copy of SwingStoreRestoreOptions.ExportDataMode
ExportDataMode string `json:"exportDataMode,omitempty"`
}

Expand Down Expand Up @@ -810,7 +819,7 @@ func (exportsHandler SwingStoreExportsHandler) RestoreExport(provider SwingStore
Args: [1]swingStoreImportOptions{{
ExportDir: exportDir,
ArtifactMode: restoreOptions.ArtifactMode,
ExportDataMode: SwingStoreExportDataModeAll,
ExportDataMode: restoreOptions.ExportDataMode,
}},
}

Expand Down
10 changes: 9 additions & 1 deletion packages/cosmic-swingset/src/export-kernel-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const ExportManifestFileName = 'export-manifest.json';

/**
* @typedef {'skip' // Do not include any "export data" (artifacts only)
* | 'repair-metadata' // Add missing artifact metadata (import only)
* | 'all' // Include all export data, create new swing-store on import
* } SwingStoreExportDataMode
*/
Expand Down Expand Up @@ -66,15 +67,22 @@ export const getExportModeFromArtifactMode = artifactMode => {

/**
* @param {string | undefined} mode
* @param {boolean} [isImport]
* @returns {asserts mode is SwingStoreExportDataMode | undefined}
*/
export const checkExportDataMode = mode => {
export const checkExportDataMode = (mode, isImport = false) => {
switch (mode) {
case 'skip':
case undefined:
break;
case 'all':
break;
case 'repair-metadata': {
if (isImport) {
break;
}
// Fall through
}
default:
throw Fail`Invalid value ${q(mode)} for "export-data-mode"`;
}
Expand Down
31 changes: 28 additions & 3 deletions packages/cosmic-swingset/src/import-kernel-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import pathPower from 'path';

import BufferLineTransform from '@agoric/internal/src/node/buffer-line-transform.js';
import { Fail, q } from '@agoric/assert';
import { importSwingStore } from '@agoric/swing-store';
import { importSwingStore, openSwingStore } from '@agoric/swing-store';

import { isEntrypoint } from './helpers/is-entrypoint.js';
import { makeProcessValue } from './helpers/process-value.js';
Expand Down Expand Up @@ -45,7 +45,7 @@ export const validateImporterOptions = options => {
options.blockHeight == null ||
typeof options.blockHeight === 'number' ||
Fail`optional blockHeight option not a number`;
checkExportDataMode(options.exportDataMode);
checkExportDataMode(options.exportDataMode, true);
getExportModeFromArtifactMode(options.artifactMode);
options.includeHistorical === undefined ||
Fail`deprecated includeHistorical option found`;
Expand Down Expand Up @@ -84,6 +84,7 @@ const checkAndGetImportSwingStoreOptions = (options, manifest) => {
* @param {Pick<import('fs/promises'), 'readFile'> & Pick<import('fs'), 'createReadStream'>} powers.fs
* @param {import('path')['resolve']} powers.pathResolve
* @param {typeof import('@agoric/swing-store')['importSwingStore']} [powers.importSwingStore]
* @param {typeof import('@agoric/swing-store')['openSwingStore']} [powers.openSwingStore]
* @param {null | ((...args: any[]) => void)} [powers.log]
* @returns {Promise<void>}
*/
Expand All @@ -93,6 +94,7 @@ export const performStateSyncImport = async (
fs: { createReadStream, readFile },
pathResolve,
importSwingStore: importDB = importSwingStore,
openSwingStore: openDB = openSwingStore,
log = console.log,
},
) => {
Expand Down Expand Up @@ -173,6 +175,29 @@ export const performStateSyncImport = async (
const { hostStorage } = swingstore;

hostStorage.kvStore.set('host.height', String(manifest.blockHeight));
await hostStorage.commit();
await hostStorage.close();
} else if (exportDataMode === 'repair-metadata') {
blockHeight !== 0 || Fail`repair metadata requires a block height`;

manifest.data || Fail`State-sync manifest missing export data`;

artifactMode === 'none' ||
Fail`Cannot restore artifacts while repairing metadata`;

const { hostStorage } = openDB(stateDir);

const savedBlockHeight =
Number(hostStorage.kvStore.get('host.height')) || 0;

if (blockHeight !== savedBlockHeight) {
throw Fail`block height doesn't match. requested=${q(
blockHeight,
)}, current=${q(savedBlockHeight)}`;
}

await hostStorage.repairMetadata(exporter);

await hostStorage.commit();
await hostStorage.close();
} else if (exportDataMode === 'skip') {
Expand Down Expand Up @@ -221,7 +246,7 @@ export const main = async (
getExportModeFromArtifactMode(artifactMode);

const exportDataMode = processValue.getFlag('export-data-mode');
checkExportDataMode(exportDataMode);
checkExportDataMode(exportDataMode, true);

if (
processValue.getBoolean({ flagName: 'include-historical' }) !== undefined
Expand Down

0 comments on commit 1da112d

Please sign in to comment.