Skip to content

Commit

Permalink
chore(cosmic-swingset): thread snapshot options through
Browse files Browse the repository at this point in the history
  • Loading branch information
mhofman committed Aug 4, 2023
1 parent a1290ef commit ead6730
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 30 deletions.
6 changes: 5 additions & 1 deletion golang/cosmos/x/swingset/keeper/extension_snapshotter.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,10 @@ func (snapshotter *ExtensionSnapshotter) InitiateSnapshot(height int64) error {

blockHeight := uint64(height)

return snapshotter.swingStoreExportsHandler.InitiateExport(blockHeight, snapshotter)
return snapshotter.swingStoreExportsHandler.InitiateExport(blockHeight, snapshotter, SwingStoreExportOptions{
ExportMode: SwingStoreExportModeCurrent,
IncludeExportData: false,
})
}

// OnExportStarted performs the actual cosmos state-sync app snapshot.
Expand Down Expand Up @@ -313,5 +316,6 @@ func (snapshotter *ExtensionSnapshotter) RestoreExtension(blockHeight uint64, fo

return snapshotter.swingStoreExportsHandler.RestoreExport(
SwingStoreExportProvider{BlockHeight: blockHeight, GetExportData: getExportData, ReadArtifact: readArtifact},
SwingStoreRestoreOptions{IncludeHistorical: false},
)
}
65 changes: 55 additions & 10 deletions golang/cosmos/x/swingset/keeper/swing_store_exports_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,10 @@ const swingStoreExportActionType = "SWING_STORE_EXPORT"
const initiateRequest = "initiate"

type swingStoreInitiateExportAction struct {
Type string `json:"type"` // "SWING_STORE_EXPORT"
Request string `json:"request"` // "initiate"
BlockHeight uint64 `json:"blockHeight,omitempty"` // empty if no blockHeight requested (latest)
Type string `json:"type"` // "SWING_STORE_EXPORT"
Request string `json:"request"` // "initiate"
BlockHeight uint64 `json:"blockHeight,omitempty"` // empty if no blockHeight requested (latest)
Args [1]SwingStoreExportOptions `json:"args"`
}

// retrieveRequest is the request type for retrieving an initiated export
Expand All @@ -150,10 +151,50 @@ type swingStoreDiscardExportAction struct {
const restoreRequest = "restore"

type swingStoreRestoreExportAction struct {
Type string `json:"type"` // "SWING_STORE_EXPORT"
Request string `json:"request"` // "restore"
BlockHeight uint64 `json:"blockHeight,omitempty"` // empty if deferring blockHeight to the manifest
Args [1]string `json:"args"` // args[1] is the directory in which the export to restore from is located
Type string `json:"type"` // "SWING_STORE_EXPORT"
Request string `json:"request"` // "restore"
BlockHeight uint64 `json:"blockHeight,omitempty"` // empty if deferring blockHeight to the manifest
Args [1]swingStoreImportOptions `json:"args"`
}

// SwingStoreExportModeCurrent represents the minimal set of artifacts needed
// to operate a node.
const SwingStoreExportModeCurrent = "current"

// SwingStoreExportModeArchival represents the set of all artifacts needed to
// not lose any historical state.
const SwingStoreExportModeArchival = "archival"

// SwingStoreExportModeDebug represents the maximal set of artifacts available
// in the JS swing-store, including any kept around for debugging purposed only
// (like previous XS heap snapshots)
const SwingStoreExportModeDebug = "debug"

// SwingStoreExportOptions are configurable options provided to the JS swing-store export
type SwingStoreExportOptions struct {
// The export mode can be "current", "archival" or "debug" (SwingStoreExportMode* const)
// See packages/cosmic-swingset/src/export-kernel-db.js initiateSwingStoreExport and
// packages/swing-store/src/swingStore.js makeSwingStoreExporter
ExportMode string `json:"exportMode,omitempty"`
// A flag indicating whether "export data" should be part of the swing-store export
// If false, the resulting SwingStoreExportProvider's GetExportData will
// return an empty list of "export data" entries.
IncludeExportData bool `json:"includeExportData,omitempty"`
}

// SwingStoreRestoreOptions are configurable options provided to the JS swing-store import
type SwingStoreRestoreOptions struct {
// A flag indicating whether the swing-store import should attempt to load
// all historical artifacts available from the export provider
IncludeHistorical bool `json:"includeHistorical,omitempty"`
}

type swingStoreImportOptions struct {
// ExportDir is the directory created by RestoreExport that JS swing-store
// should import from.
ExportDir string `json:"exportDir"`
// IncludeHistorical is a copy of SwingStoreRestoreOptions.IncludeHistorical
IncludeHistorical bool `json:"includeHistorical,omitempty"`
}

var disallowedArtifactNameChar = regexp.MustCompile(`[^-_.a-zA-Z0-9]`)
Expand Down Expand Up @@ -393,7 +434,7 @@ func NewSwingStoreExportsHandler(logger log.Logger, blockingSend func(action vm.
// from the goroutine that initiated the export.
//
// Must be called by the main goroutine
func (exportsHandler SwingStoreExportsHandler) InitiateExport(blockHeight uint64, eventHandler SwingStoreExportEventHandler) error {
func (exportsHandler SwingStoreExportsHandler) InitiateExport(blockHeight uint64, eventHandler SwingStoreExportEventHandler, exportOptions SwingStoreExportOptions) error {
err := checkNotActive()
if err != nil {
return err
Expand Down Expand Up @@ -447,6 +488,7 @@ func (exportsHandler SwingStoreExportsHandler) InitiateExport(blockHeight uint64
Type: swingStoreExportActionType,
BlockHeight: blockHeight,
Request: initiateRequest,
Args: [1]SwingStoreExportOptions{exportOptions},
}

// blockingSend for SWING_STORE_EXPORT action is safe to call from a goroutine
Expand Down Expand Up @@ -645,7 +687,7 @@ func (exportsHandler SwingStoreExportsHandler) retrieveExport(onExportRetrieved
// RestoreExport restores the JS swing-store using previously exported data and artifacts.
//
// Must be called by the main goroutine
func (exportsHandler SwingStoreExportsHandler) RestoreExport(provider SwingStoreExportProvider) error {
func (exportsHandler SwingStoreExportsHandler) RestoreExport(provider SwingStoreExportProvider, restoreOptions SwingStoreRestoreOptions) error {
err := checkNotActive()
if err != nil {
return err
Expand Down Expand Up @@ -759,7 +801,10 @@ func (exportsHandler SwingStoreExportsHandler) RestoreExport(provider SwingStore
Type: swingStoreExportActionType,
BlockHeight: blockHeight,
Request: restoreRequest,
Args: [1]string{exportDir},
Args: [1]swingStoreImportOptions{{
ExportDir: exportDir,
IncludeHistorical: restoreOptions.IncludeHistorical,
}},
}

_, err = exportsHandler.blockingSend(action, true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func TestSwingStoreSnapshotterInProgress(t *testing.T) {
<-ch
return nil
}
err := exportsHandler.InitiateExport(123, exportEventHandler)
err := exportsHandler.InitiateExport(123, exportEventHandler, SwingStoreExportOptions{})
if err != nil {
t.Fatal(err)
}
Expand All @@ -67,12 +67,12 @@ func TestSwingStoreSnapshotterInProgress(t *testing.T) {
t.Fatal(err)
}

err = exportsHandler.InitiateExport(456, newTestSwingStoreEventHandler())
err = exportsHandler.InitiateExport(456, newTestSwingStoreEventHandler(), SwingStoreExportOptions{})
if err == nil {
t.Error("wanted error for export operation in progress")
}

err = exportsHandler.RestoreExport(SwingStoreExportProvider{BlockHeight: 456})
err = exportsHandler.RestoreExport(SwingStoreExportProvider{BlockHeight: 456}, SwingStoreRestoreOptions{})
if err == nil {
t.Error("wanted error for export operation in progress")
}
Expand All @@ -82,7 +82,7 @@ func TestSwingStoreSnapshotterInProgress(t *testing.T) {
if err != nil {
t.Fatal(err)
}
err = exportsHandler.InitiateExport(456, exportEventHandler)
err = exportsHandler.InitiateExport(456, exportEventHandler, SwingStoreExportOptions{})
if err != nil {
t.Fatal(err)
}
Expand All @@ -108,7 +108,7 @@ func TestSwingStoreSnapshotterSecondCommit(t *testing.T) {
if err != nil {
t.Fatal(err)
}
err = exportsHandler.InitiateExport(123, exportEventHandler)
err = exportsHandler.InitiateExport(123, exportEventHandler, SwingStoreExportOptions{})
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -138,7 +138,7 @@ func TestSwingStoreSnapshotterInitiateFails(t *testing.T) {
return "", nil
}

err := exportsHandler.InitiateExport(123, exportEventHandler)
err := exportsHandler.InitiateExport(123, exportEventHandler, SwingStoreExportOptions{})
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -180,7 +180,7 @@ func TestSwingStoreSnapshotterRetrievalFails(t *testing.T) {
return savedErr
}

err := exportsHandler.InitiateExport(123, exportEventHandler)
err := exportsHandler.InitiateExport(123, exportEventHandler, SwingStoreExportOptions{})
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -216,7 +216,7 @@ func TestSwingStoreSnapshotterDiscard(t *testing.T) {
activeOperation.exportRetrieved = true
return nil
}
err := exportsHandler.InitiateExport(123, exportEventHandler)
err := exportsHandler.InitiateExport(123, exportEventHandler, SwingStoreExportOptions{})
if err != nil {
t.Fatal(err)
}
Expand All @@ -233,7 +233,7 @@ func TestSwingStoreSnapshotterDiscard(t *testing.T) {
exportEventHandler.onExportStarted = func(height uint64, retrieveExport func() error) error {
return nil
}
err = exportsHandler.InitiateExport(456, exportEventHandler)
err = exportsHandler.InitiateExport(456, exportEventHandler, SwingStoreExportOptions{})
if err != nil {
t.Fatal(err)
}
Expand Down
47 changes: 37 additions & 10 deletions packages/cosmic-swingset/src/chain-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,14 @@ import stringify from './helpers/json-stable-stringify.js';
import { launch } from './launch-chain.js';
import { getTelemetryProviders } from './kernel-stats.js';
import { makeProcessValue } from './helpers/process-value.js';
import { spawnSwingStoreExport } from './export-kernel-db.js';
import { performStateSyncImport } from './import-kernel-db.js';
import {
spawnSwingStoreExport,
validateExporterOptions,
} from './export-kernel-db.js';
import {
performStateSyncImport,
validateImporterOptions,
} from './import-kernel-db.js';

// eslint-disable-next-line no-unused-vars
let whenHellFreezesOver = null;
Expand Down Expand Up @@ -501,26 +507,44 @@ export default async function main(progname, args, { env, homedir, agcc }) {
await null;
switch (request) {
case 'restore': {
const exportDir = requestArgs[0];
if (typeof exportDir !== 'string') {
throw Fail`Invalid exportDir argument ${q(exportDir)}`;
}
const requestOptions =
typeof requestArgs[0] === 'string'
? { exportDir: requestArgs[0] }
: requestArgs[0] || {};
const options = {
...requestOptions,
stateDir: stateDBDir,
blockHeight,
};
validateImporterOptions(options);
!stateSyncExport ||
Fail`Snapshot already in progress for ${stateSyncExport.blockHeight}`;
!blockingSend || Fail`Cannot restore snapshot after init`;
console.info(
'Restoring SwingSet state from snapshot at block height',
blockHeight,
'with options',
JSON.stringify(requestOptions),
);
return performStateSyncImport(
{ exportDir, stateDir: stateDBDir, blockHeight },
{ fs: { ...fs, ...fsPromises }, pathResolve, log: null },
);
return performStateSyncImport(options, {
fs: { ...fs, ...fsPromises },
pathResolve,
log: null,
});
}
case 'initiate': {
!stateSyncExport ||
Fail`Snapshot already in progress for ${stateSyncExport.blockHeight}`;

const requestOptions = requestArgs[0] || {};

validateExporterOptions({
...requestOptions,
stateDir: stateDBDir,
exportDir: '',
blockHeight,
});

const exportData =
/** @type {Required<NonNullable<typeof stateSyncExport>>} */ ({
blockHeight,
Expand Down Expand Up @@ -563,9 +587,12 @@ export default async function main(progname, args, { env, homedir, agcc }) {
console.info(
'Initiating SwingSet state snapshot at block height',
blockHeight,
'with options',
JSON.stringify(requestOptions),
);
exportData.exporter = spawnSwingStoreExport(
{
...requestOptions,
stateDir: stateDBDir,
exportDir: exportData.exportDir,
blockHeight,
Expand Down
19 changes: 19 additions & 0 deletions packages/cosmic-swingset/src/export-kernel-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,25 @@ const checkExportMode = mode => {
* @property {boolean} [includeExportData] whether to include an artifact for the export data in the export
*/

/**
* @param {object} options
* @returns {asserts options is StateSyncExporterOptions}
*/
export const validateExporterOptions = options => {
typeof options === 'object' || Fail`options is not an object`;
typeof options.stateDir === 'string' ||
Fail`required stateDir option not a string`;
typeof options.exportDir === 'string' ||
Fail`required exportDir option not a string`;
options.blockHeight == null ||
typeof options.blockHeight === 'number' ||
Fail`optional blockHeight option not a number`;
checkExportMode(options.exportMode);
options.includeExportData == null ||
typeof options.includeExportData === 'boolean' ||
Fail`optional includeExportData option not a boolean`;
};

/**
* @param {StateSyncExporterOptions} options
* @param {object} powers
Expand Down
18 changes: 18 additions & 0 deletions packages/cosmic-swingset/src/import-kernel-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,24 @@ import { ExportManifestFileName } from './export-kernel-db.js';
* @property {boolean} [includeHistorical] whether to include historical artifacts in the export
*/

/**
* @param {object} options
* @returns {asserts options is StateSyncImporterOptions}
*/
export const validateImporterOptions = options => {
typeof options === 'object' || Fail`options is not an object`;
typeof options.stateDir === 'string' ||
Fail`required stateDir option not a string`;
typeof options.exportDir === 'string' ||
Fail`required exportDir option not a string`;
options.blockHeight == null ||
typeof options.blockHeight === 'number' ||
Fail`optional blockHeight option not a number`;
options.includeHistorical == null ||
typeof options.includeHistorical === 'boolean' ||
Fail`optional includeHistorical option not a boolean`;
};

/**
* @param {StateSyncImporterOptions} options
* @param {object} powers
Expand Down

0 comments on commit ead6730

Please sign in to comment.