From 631dab7c7d025bd6a6d9327774ec7cd176d56313 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Thu, 5 Sep 2024 14:41:22 -0400 Subject: [PATCH] feat: Add consensus-independent vat snapshot retention configuration to AG_COSMOS_INIT Fixes #9386 --- golang/cosmos/x/swingset/config.go | 40 ++++++++++++++++++++-- packages/cosmic-swingset/src/chain-main.js | 15 ++++---- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/golang/cosmos/x/swingset/config.go b/golang/cosmos/x/swingset/config.go index 3ebe9551cda6..1f8a8b063426 100644 --- a/golang/cosmos/x/swingset/config.go +++ b/golang/cosmos/x/swingset/config.go @@ -18,10 +18,18 @@ const ( ConfigPrefix = "swingset" FlagSlogfile = ConfigPrefix + ".slogfile" + SnapshotRetentionOptionDebug = "debug" + SnapshotRetentionOptionOperational = "operational" + TranscriptRetentionOptionArchival = "archival" TranscriptRetentionOptionOperational = "operational" ) +var snapshotRetentionValues []string = []string{ + SnapshotRetentionOptionDebug, + SnapshotRetentionOptionOperational, +} + var transcriptRetentionValues []string = []string{ TranscriptRetentionOptionArchival, TranscriptRetentionOptionOperational, @@ -49,9 +57,16 @@ slogfile = "{{ .Swingset.SlogFile }}" # be frequently paged out to remain under this limit. max-vats-online = {{ .Swingset.MaxVatsOnline }} +# Retention of vat snapshots, with values analogous to those of export +# ` + "`artifactMode`" + ` (cf. +# https://github.com/Agoric/agoric-sdk/blob/master/packages/swing-store/docs/data-export.md#optional--historical-data ). +# * "debug": keep all snapshots +# * "operational": keep only the last snapshot +vat-snapshot-retention = "{{ .Swingset.VatSnapshotRetention }}" + # Retention of vat transcript spans, with values analogous to those of export # ` + "`artifactMode`" + ` (cf. -# https://github.com/Agoric/agoric-sdk/blob/master/packages/swing-store/docs/data-export.md#optional--historical-data +# https://github.com/Agoric/agoric-sdk/blob/master/packages/swing-store/docs/data-export.md#optional--historical-data ). # * "archival": keep all transcript spans # * "operational": keep only necessary transcript spans (i.e., since the # last snapshot of their vat) @@ -70,9 +85,18 @@ type SwingsetConfig struct { // SlogFile is the path at which a SwingSet log "slog" file should be written. // If relative, it is interpreted against the application home directory SlogFile string `mapstructure:"slogfile" json:"slogfile,omitempty"` + // MaxVatsOnline is the maximum number of vats that the SwingSet kernel will have online // at any given time. MaxVatsOnline int `mapstructure:"max-vats-online" json:"maxVatsOnline,omitempty"` + + // VatSnapshotRetention controls retention of vat snapshots, + // and has values analogous to those of export `artifactMode` (cf. + // ../../../../packages/swing-store/docs/data-export.md#optional--historical-data ). + // * "debug": keep all snapshots + // * "operational": keep only the last snapshot + VatSnapshotRetention string `mapstructure:"vat-snapshot-retention" json:"vatSnapshotRetention,omitempty"` + // VatTranscriptRetention controls retention of vat transcript spans, // and has values analogous to those of export `artifactMode` (cf. // ../../../../packages/swing-store/docs/data-export.md#optional--historical-data ). @@ -87,6 +111,7 @@ type SwingsetConfig struct { var DefaultSwingsetConfig = SwingsetConfig{ SlogFile: "", MaxVatsOnline: 50, + VatSnapshotRetention: "operational", VatTranscriptRetention: "default", } @@ -114,7 +139,18 @@ func SwingsetConfigFromViper(resolvedConfig servertypes.AppOptions) (*SwingsetCo } ssConfig := &extendedConfig.Swingset - // Default/validate transcript retention. + if ssConfig.VatSnapshotRetention != "" { + // Validate vat snapshot retention. + if util.IndexOf(snapshotRetentionValues, ssConfig.VatSnapshotRetention) == -1 { + err := fmt.Errorf( + "value for vat-snapshot-retention must be in %q", + snapshotRetentionValues, + ) + return nil, err + } + } + + // Default/validate vat transcript retention. if ssConfig.VatTranscriptRetention == "" || ssConfig.VatTranscriptRetention == "default" { if extendedConfig.Pruning == pruningtypes.PruningOptionNothing { ssConfig.VatTranscriptRetention = TranscriptRetentionOptionArchival diff --git a/packages/cosmic-swingset/src/chain-main.js b/packages/cosmic-swingset/src/chain-main.js index bb32233e176d..dff36fe872fb 100644 --- a/packages/cosmic-swingset/src/chain-main.js +++ b/packages/cosmic-swingset/src/chain-main.js @@ -74,6 +74,7 @@ const toNumber = specimen => { * @typedef {object} CosmosSwingsetConfig * @property {string} [slogfile] * @property {number} [maxVatsOnline] + * @property {'debug' | 'operational'} [vatSnapshotRetention] * @property {'archival' | 'operational'} [vatTranscriptRetention] */ const SwingsetConfigShape = M.splitRecord( @@ -81,6 +82,7 @@ const SwingsetConfigShape = M.splitRecord( { slogfile: M.string(), maxVatsOnline: M.number(), + vatSnapshotRetention: M.or('debug', 'operational'), vatTranscriptRetention: M.or('archival', 'operational'), }, M.any(), @@ -307,10 +309,16 @@ export default async function main(progname, args, { env, homedir, agcc }) { // here so 'sendToChainStorage' can close over the single mutable instance, // when we updated the 'portNums.storage' value each time toSwingSet was called. async function launchAndInitializeSwingSet(initAction) { + const { XSNAP_KEEP_SNAPSHOTS, NODE_HEAP_SNAPSHOTS = -1 } = env; + /** @type {CosmosSwingsetConfig} */ const swingsetConfig = harden(initAction.resolvedConfig || {}); validateSwingsetConfig(swingsetConfig); - const { slogfile, vatTranscriptRetention } = swingsetConfig; + const { slogfile, vatSnapshotRetention, vatTranscriptRetention } = + swingsetConfig; + const keepSnapshots = + vatSnapshotRetention === 'debug' || + (!vatSnapshotRetention && ['1', 'true'].includes(XSNAP_KEEP_SNAPSHOTS)); const keepTranscripts = vatTranscriptRetention === 'archival'; // As a kludge, back-propagate selected configuration into environment variables. @@ -451,7 +459,6 @@ export default async function main(progname, args, { env, homedir, agcc }) { serviceName: TELEMETRY_SERVICE_NAME, }); - const { XSNAP_KEEP_SNAPSHOTS, NODE_HEAP_SNAPSHOTS = -1 } = env; const slogSender = await makeSlogSender({ stateDir: stateDBDir, env, @@ -464,10 +471,6 @@ export default async function main(progname, args, { env, homedir, agcc }) { trueValue: pathResolve(stateDBDir, 'store-trace.log'), }); - // TODO: Add to SwingsetConfig (#9386) - const keepSnapshots = - XSNAP_KEEP_SNAPSHOTS === '1' || XSNAP_KEEP_SNAPSHOTS === 'true'; - const nodeHeapSnapshots = Number.parseInt(NODE_HEAP_SNAPSHOTS, 10); let lastCommitTime = 0;