@agoric/swing-store 0.9.2-dev-eb7e9eb.0 → 0.9.2-u11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,21 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ### [0.9.2-u11.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/swing-store@0.9.1...@agoric/swing-store@0.9.2-u11.0) (2023-08-24)
7
+
8
+
9
+ ### Features
10
+
11
+ * **swingstore:** add repairMetadata() ([5b2d19d](https://github.com/Agoric/agoric-sdk/commit/5b2d19d1153a23c118afb14ca4ed80e175640f62)), closes [#8025](https://github.com/Agoric/agoric-sdk/issues/8025) [#8025](https://github.com/Agoric/agoric-sdk/issues/8025)
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * **swing-store:** add 'replay' artifactMode, make export more strict ([d46c8e2](https://github.com/Agoric/agoric-sdk/commit/d46c8e2d270999ccba552e0072cb5e0926922f28)), closes [#8105](https://github.com/Agoric/agoric-sdk/issues/8105)
17
+ * rewrite importSwingStore to preserve metadata properly ([03e323a](https://github.com/Agoric/agoric-sdk/commit/03e323a55ffeb98dcc84a57050a5d3fc881899b8)), closes [#8025](https://github.com/Agoric/agoric-sdk/issues/8025)
18
+
19
+
20
+
6
21
  ### [0.9.1](https://github.com/Agoric/agoric-sdk/compare/@agoric/swing-store@0.9.0...@agoric/swing-store@0.9.1) (2023-06-02)
7
22
 
8
23
  **Note:** Version bump only for package @agoric/swing-store
@@ -1,10 +1,6 @@
1
1
  // This file can contain .js-specific Typescript compiler config.
2
2
  {
3
3
  "extends": "../../tsconfig.json",
4
- "compilerOptions": {
5
- "allowSyntheticDefaultImports": true,
6
- "maxNodeModuleJsDepth": 1,
7
- },
8
4
  "include": [
9
5
  "src/**/*.js",
10
6
  "test/**/*.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/swing-store",
3
- "version": "0.9.2-dev-eb7e9eb.0+eb7e9eb",
3
+ "version": "0.9.2-u11.0",
4
4
  "description": "Persistent storage for SwingSet",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -17,22 +17,22 @@
17
17
  "test:xs": "exit 0",
18
18
  "lint-fix": "yarn lint:eslint --fix",
19
19
  "lint": "run-s --continue-on-error lint:*",
20
- "lint:types": "tsc",
20
+ "lint:types": "tsc -p jsconfig.json",
21
21
  "lint:eslint": "eslint ."
22
22
  },
23
23
  "dependencies": {
24
- "@agoric/assert": "0.6.1-dev-eb7e9eb.0+eb7e9eb",
25
- "@agoric/internal": "0.3.3-dev-eb7e9eb.0+eb7e9eb",
26
- "@endo/base64": "^0.2.32",
27
- "@endo/bundle-source": "^2.5.2",
28
- "@endo/check-bundle": "^0.2.19",
29
- "@endo/nat": "^4.1.28",
24
+ "@agoric/assert": "^0.6.0",
25
+ "@agoric/internal": "^0.3.3-u11.0",
26
+ "@endo/base64": "^0.2.31",
27
+ "@endo/bundle-source": "^2.5.1",
28
+ "@endo/check-bundle": "^0.2.18",
29
+ "@endo/nat": "^4.1.27",
30
30
  "better-sqlite3": "^8.2.0"
31
31
  },
32
32
  "devDependencies": {
33
- "@endo/init": "^0.5.57",
33
+ "@endo/init": "^0.5.56",
34
34
  "@types/better-sqlite3": "^7.5.0",
35
- "ava": "^5.3.0",
35
+ "ava": "^5.2.0",
36
36
  "c8": "^7.13.0",
37
37
  "tmp": "^0.2.1"
38
38
  },
@@ -45,5 +45,5 @@
45
45
  ],
46
46
  "timeout": "2m"
47
47
  },
48
- "gitHead": "eb7e9ebe52e78052e5ded601b6658896d257cab4"
48
+ "gitHead": "92b6cd72484079b0349d8ccfa4510aeb820e8d67"
49
49
  }
@@ -328,6 +328,7 @@ export function makeBundleStore(db, ensureTxn, noteExport = () => {}) {
328
328
  endoZipBase64: encodeBase64(data),
329
329
  });
330
330
  // Assert that the bundle contents match the ID and hash
331
+ // eslint-disable-next-line @jessie.js/no-nested-await
331
332
  await checkBundle(bundle, computeSha512, bundleID);
332
333
  populateBundle(bundleID, serializeBundle(bundleID, bundle));
333
334
  } else {
package/src/snapStore.js CHANGED
@@ -333,11 +333,11 @@ export function makeSnapStore(
333
333
  snapReader.pipe(hashStream);
334
334
  snapReader.pipe(output);
335
335
 
336
- await null;
337
336
  try {
338
337
  yield* output;
339
338
  } finally {
340
339
  gzReader.destroy();
340
+ // eslint-disable-next-line @jessie.js/no-nested-await
341
341
  await finished(gzReader);
342
342
  const hash = hashStream.digest('hex');
343
343
  hash === snapshotID ||
package/src/swingStore.js CHANGED
@@ -515,10 +515,6 @@ export function makeSwingStore(dirPath, forceReset, options = {}) {
515
515
  });
516
516
  }
517
517
 
518
- function getDatabase() {
519
- return db;
520
- }
521
-
522
518
  const transcriptStorePublic = {
523
519
  initTranscript: transcriptStore.initTranscript,
524
520
  rolloverSpan: transcriptStore.rolloverSpan,
@@ -568,7 +564,6 @@ export function makeSwingStore(dirPath, forceReset, options = {}) {
568
564
  const debug = {
569
565
  serialize,
570
566
  dump,
571
- getDatabase,
572
567
  };
573
568
 
574
569
  return harden({
@@ -3,7 +3,9 @@
3
3
  import '@endo/init/debug.js';
4
4
  import { Buffer } from 'node:buffer';
5
5
 
6
+ // eslint-disable-next-line import/no-extraneous-dependencies
6
7
  import test from 'ava';
8
+ // eslint-disable-next-line import/no-extraneous-dependencies
7
9
  import tmp from 'tmp';
8
10
  import bundleSource from '@endo/bundle-source';
9
11
 
@@ -120,6 +122,7 @@ test('crank abort leaves no debris in export log', async t => {
120
122
  crankNum % 3 === 0,
121
123
  );
122
124
  }
125
+ // eslint-disable-next-line no-await-in-loop
123
126
  await ssOut.hostStorage.commit();
124
127
  }
125
128
 
@@ -215,8 +218,10 @@ async function testExportImport(
215
218
  actLikeAVatRunningACrank(vat, kernelStorage, crankNum);
216
219
  }
217
220
  if (block < 3) {
221
+ // eslint-disable-next-line no-await-in-loop
218
222
  await fakeAVatSnapshot(vats[block % 2], kernelStorage);
219
223
  }
224
+ // eslint-disable-next-line no-await-in-loop
220
225
  await ssOut.hostStorage.commit();
221
226
  }
222
227
 
@@ -14,15 +14,7 @@ import { decodeBase64 } from '@endo/base64';
14
14
  import { buffer } from '../src/util.js';
15
15
  import { importSwingStore, makeSwingStoreExporter } from '../src/index.js';
16
16
 
17
- import { tmpDir } from './util.js';
18
- import {
19
- buildData,
20
- bundle0,
21
- bundle0ID,
22
- makeExporter,
23
- snapHash,
24
- snapshotData,
25
- } from './exports.js';
17
+ import { tmpDir, makeB0ID } from './util.js';
26
18
 
27
19
  const rank = {
28
20
  operational: 1,
@@ -31,6 +23,15 @@ const rank = {
31
23
  debug: 4,
32
24
  };
33
25
 
26
+ const snapshotData = 'snapshot data';
27
+ // this snapHash was computed manually
28
+ const snapHash =
29
+ 'e7dee7266896538616b630a5da40a90e007726a383e005a9c9c5dd0c2daf9329';
30
+
31
+ /** @type {import('../src/bundleStore.js').Bundle} */
32
+ const bundle0 = { moduleFormat: 'nestedEvaluate', source: '1+1' };
33
+ const bundle0ID = makeB0ID(bundle0);
34
+
34
35
  function convert(orig) {
35
36
  const bundles = Object.fromEntries(
36
37
  Object.entries(orig.bundles).map(([bundleID, encBundle]) => {
@@ -43,6 +44,38 @@ function convert(orig) {
43
44
  return { ...orig, bundles };
44
45
  }
45
46
 
47
+ /**
48
+ * @typedef { import('../src/exporter').KVPair } KVPair
49
+ */
50
+
51
+ /**
52
+ * @param { Map<string, string | null> } exportData
53
+ * @param { Map<string, string> } artifacts
54
+ */
55
+ export function makeExporter(exportData, artifacts) {
56
+ return {
57
+ async *getExportData() {
58
+ for (const [key, value] of exportData.entries()) {
59
+ /** @type { KVPair } */
60
+ const pair = [key, value];
61
+ yield pair;
62
+ }
63
+ },
64
+ async *getArtifactNames() {
65
+ for (const name of artifacts.keys()) {
66
+ yield name;
67
+ }
68
+ },
69
+ async *getArtifact(name) {
70
+ const data = artifacts.get(name);
71
+ assert(data, `missing artifact ${name}`);
72
+ yield Buffer.from(data);
73
+ },
74
+ // eslint-disable-next-line no-empty-function
75
+ async close() {},
76
+ };
77
+ }
78
+
46
79
  test('import empty', async t => {
47
80
  const [dbDir, cleanup] = await tmpDir('testdb');
48
81
  t.teardown(cleanup);
@@ -58,6 +91,66 @@ test('import empty', async t => {
58
91
  });
59
92
  });
60
93
 
94
+ export function buildData() {
95
+ // build an export manually
96
+ const exportData = new Map();
97
+ const artifacts = new Map();
98
+
99
+ // shadow kvStore
100
+ exportData.set('kv.key1', 'value1');
101
+
102
+ // now add artifacts and metadata in pairs
103
+
104
+ artifacts.set(`bundle.${bundle0ID}`, JSON.stringify(bundle0));
105
+ exportData.set(`bundle.${bundle0ID}`, bundle0ID);
106
+
107
+ const sbase = { vatID: 'v1', hash: snapHash, inUse: 0 };
108
+ const tbase = { vatID: 'v1', startPos: 0, isCurrent: 0, incarnation: 1 };
109
+ const addTS = (key, obj) =>
110
+ exportData.set(key, JSON.stringify({ ...tbase, ...obj }));
111
+ const t0hash =
112
+ '5bee0f44eca02f23eab03703e84ed2647d5d117fed99e1c30a3b424b7f082ab9';
113
+ const t2hash =
114
+ '57152efdd7fdf75c03371d2b4f1088d5bf3eae7fe643babce527ff81df38998c';
115
+ const t5hash =
116
+ '1947001e78e01bd1e773feb22b4ffc530447373b9de9274d5d5fbda3f23dbf2b';
117
+ const t8hash =
118
+ 'e6b42c6a3fb94285a93162f25a9fc0145fd4c5bb144917dc572c50ae2d02ee69';
119
+
120
+ addTS(`transcript.v1.0`, { incarnation: 0, endPos: 2, hash: t0hash });
121
+ artifacts.set(`transcript.v1.0.2`, 'start-worker\nshutdown-worker\n');
122
+
123
+ addTS(`transcript.v1.2`, { startPos: 2, endPos: 5, hash: t2hash });
124
+ artifacts.set(
125
+ `transcript.v1.2.5`,
126
+ 'start-worker\ndelivery1\nsave-snapshot\n',
127
+ );
128
+ exportData.set(`snapshot.v1.4`, JSON.stringify({ ...sbase, snapPos: 4 }));
129
+ artifacts.set(`snapshot.v1.4`, snapshotData);
130
+
131
+ addTS(`transcript.v1.5`, { startPos: 5, endPos: 8, hash: t5hash });
132
+ artifacts.set(
133
+ 'transcript.v1.5.8',
134
+ 'load-snapshot\ndelivery2\nsave-snapshot\n',
135
+ );
136
+ exportData.set(
137
+ `snapshot.v1.7`,
138
+ JSON.stringify({ ...sbase, snapPos: 7, inUse: 1 }),
139
+ );
140
+ artifacts.set(`snapshot.v1.7`, snapshotData);
141
+
142
+ artifacts.set('transcript.v1.8.10', 'load-snapshot\ndelivery3\n');
143
+ exportData.set(`snapshot.v1.current`, 'snapshot.v1.7');
144
+ addTS(`transcript.v1.current`, {
145
+ startPos: 8,
146
+ endPos: 10,
147
+ isCurrent: 1,
148
+ hash: t8hash,
149
+ });
150
+
151
+ return { exportData, artifacts, t0hash, t2hash, t5hash, t8hash };
152
+ }
153
+
61
154
  const importTest = test.macro(async (t, mode) => {
62
155
  /** @typedef {import('../src/internal.js').ArtifactMode} ArtifactMode */
63
156
  const artifactMode = /** @type {ArtifactMode} */ (mode);
@@ -8,7 +8,7 @@ import sqlite3 from 'better-sqlite3';
8
8
 
9
9
  import { importSwingStore } from '../src/index.js';
10
10
 
11
- import { makeExporter, buildData } from './exports.js';
11
+ import { makeExporter, buildData } from './test-import.js';
12
12
  import { tmpDir } from './util.js';
13
13
 
14
14
  test('repair metadata', async t => {
@@ -5,7 +5,9 @@ import { Buffer } from 'node:buffer';
5
5
  import zlib from 'zlib';
6
6
  import sqlite3 from 'better-sqlite3';
7
7
 
8
+ // eslint-disable-next-line import/no-extraneous-dependencies
8
9
  import test from 'ava';
10
+ // eslint-disable-next-line import/no-extraneous-dependencies
9
11
  import { makeMeasureSeconds } from '@agoric/internal';
10
12
  import { makeSnapStore } from '../src/snapStore.js';
11
13
 
@@ -101,6 +103,7 @@ test('snapStore prepare / commit delete is robust', async t => {
101
103
 
102
104
  const hashes = [];
103
105
  for (let i = 0; i < 5; i += 1) {
106
+ // eslint-disable-next-line no-await-in-loop
104
107
  const { hash } = await store.saveSnapshot(
105
108
  'fakeVatID2',
106
109
  i,
@@ -130,6 +133,7 @@ test('snapStore prepare / commit delete is robust', async t => {
130
133
  t.is(sqlCountSnapshots.get(), 0);
131
134
 
132
135
  for (let i = 0; i < 5; i += 1) {
136
+ // eslint-disable-next-line no-await-in-loop
133
137
  const { hash } = await store.saveSnapshot(
134
138
  'fakeVatID4',
135
139
  i,
package/test/exports.js DELETED
@@ -1,99 +0,0 @@
1
- import { Buffer } from 'buffer';
2
- import { makeB0ID } from './util.js';
3
-
4
- export const snapshotData = 'snapshot data';
5
- // this snapHash was computed manually
6
- export const snapHash =
7
- 'e7dee7266896538616b630a5da40a90e007726a383e005a9c9c5dd0c2daf9329';
8
-
9
- /** @type {import('../src/bundleStore.js').Bundle} */
10
- export const bundle0 = { moduleFormat: 'nestedEvaluate', source: '1+1' };
11
- export const bundle0ID = makeB0ID(bundle0);
12
-
13
- export function buildData() {
14
- // build an export manually
15
- const exportData = new Map();
16
- const artifacts = new Map();
17
-
18
- // shadow kvStore
19
- exportData.set('kv.key1', 'value1');
20
-
21
- // now add artifacts and metadata in pairs
22
-
23
- artifacts.set(`bundle.${bundle0ID}`, JSON.stringify(bundle0));
24
- exportData.set(`bundle.${bundle0ID}`, bundle0ID);
25
-
26
- const sbase = { vatID: 'v1', hash: snapHash, inUse: 0 };
27
- const tbase = { vatID: 'v1', startPos: 0, isCurrent: 0, incarnation: 1 };
28
- const addTS = (key, obj) =>
29
- exportData.set(key, JSON.stringify({ ...tbase, ...obj }));
30
- const t0hash =
31
- '5bee0f44eca02f23eab03703e84ed2647d5d117fed99e1c30a3b424b7f082ab9';
32
- const t2hash =
33
- '57152efdd7fdf75c03371d2b4f1088d5bf3eae7fe643babce527ff81df38998c';
34
- const t5hash =
35
- '1947001e78e01bd1e773feb22b4ffc530447373b9de9274d5d5fbda3f23dbf2b';
36
- const t8hash =
37
- 'e6b42c6a3fb94285a93162f25a9fc0145fd4c5bb144917dc572c50ae2d02ee69';
38
-
39
- addTS(`transcript.v1.0`, { incarnation: 0, endPos: 2, hash: t0hash });
40
- artifacts.set(`transcript.v1.0.2`, 'start-worker\nshutdown-worker\n');
41
-
42
- addTS(`transcript.v1.2`, { startPos: 2, endPos: 5, hash: t2hash });
43
- artifacts.set(
44
- `transcript.v1.2.5`,
45
- 'start-worker\ndelivery1\nsave-snapshot\n',
46
- );
47
- exportData.set(`snapshot.v1.4`, JSON.stringify({ ...sbase, snapPos: 4 }));
48
- artifacts.set(`snapshot.v1.4`, snapshotData);
49
-
50
- addTS(`transcript.v1.5`, { startPos: 5, endPos: 8, hash: t5hash });
51
- artifacts.set(
52
- 'transcript.v1.5.8',
53
- 'load-snapshot\ndelivery2\nsave-snapshot\n',
54
- );
55
- exportData.set(
56
- `snapshot.v1.7`,
57
- JSON.stringify({ ...sbase, snapPos: 7, inUse: 1 }),
58
- );
59
- artifacts.set(`snapshot.v1.7`, snapshotData);
60
-
61
- artifacts.set('transcript.v1.8.10', 'load-snapshot\ndelivery3\n');
62
- exportData.set(`snapshot.v1.current`, 'snapshot.v1.7');
63
- addTS(`transcript.v1.current`, {
64
- startPos: 8,
65
- endPos: 10,
66
- isCurrent: 1,
67
- hash: t8hash,
68
- });
69
-
70
- return { exportData, artifacts, t0hash, t2hash, t5hash, t8hash };
71
- }
72
-
73
- /**
74
- * @param { Map<string, string | null> } exportData
75
- * @param { Map<string, string> } artifacts
76
- */
77
- export function makeExporter(exportData, artifacts) {
78
- return {
79
- async *getExportData() {
80
- for (const [key, value] of exportData.entries()) {
81
- /** @type { import('../src/exporter.js').KVPair } */
82
- const pair = [key, value];
83
- yield pair;
84
- }
85
- },
86
- async *getArtifactNames() {
87
- for (const name of artifacts.keys()) {
88
- yield name;
89
- }
90
- },
91
- async *getArtifact(name) {
92
- const data = artifacts.get(name);
93
- assert(data, `missing artifact ${name}`);
94
- yield Buffer.from(data);
95
- },
96
- // eslint-disable-next-line no-empty-function
97
- async close() {},
98
- };
99
- }