@agoric/cosmic-swingset 0.42.0-upgrade-16-dev-12b78e3.0 → 0.42.0-upgrade-17-dev-a61cdab.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 +18 -12
- package/package.json +22 -21
- package/src/chain-main.js +130 -32
- package/src/export-kernel-db.js +1 -1
- package/src/export-storage.js +1 -1
- package/src/helpers/bufferedStorage.js +1 -1
- package/src/helpers/make-queue.js +1 -1
- package/src/import-kernel-db.js +1 -1
- package/src/kernel-stats.js +10 -10
- package/src/launch-chain.js +91 -58
- package/src/params.js +1 -1
- package/src/sim-chain.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,29 +3,25 @@
|
|
|
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.42.0-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
### Bug Fixes
|
|
10
|
-
|
|
11
|
-
* adopt `VTRANSFER_IBC_EVENT` as an action-type ([#9671](https://github.com/Agoric/agoric-sdk/issues/9671)) ([67569d4](https://github.com/Agoric/agoric-sdk/commit/67569d4a2461c5415b3cc33f5faee9070f8d3c2e)), closes [#9670](https://github.com/Agoric/agoric-sdk/issues/9670)
|
|
12
|
-
* **vm-config:** always use `init-localchain` and `init-transfer` ([1db4ed6](https://github.com/Agoric/agoric-sdk/commit/1db4ed635299cca315ff349ba8a0f3b26b605bf2))
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
## [0.42.0-u16.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/cosmic-swingset@0.41.3...@agoric/cosmic-swingset@0.42.0-u16.0) (2024-07-02)
|
|
6
|
+
## [0.42.0-u17.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/cosmic-swingset@0.41.3...@agoric/cosmic-swingset@0.42.0-u17.0) (2024-09-17)
|
|
17
7
|
|
|
18
8
|
|
|
19
9
|
### ⚠ BREAKING CHANGES
|
|
20
10
|
|
|
11
|
+
* **cosmic-swingset:** Exclude non-consensus configuration from bootstrap vat arguments
|
|
21
12
|
* **cosmos:** add required export-dir export cmd option
|
|
22
13
|
* remove deprecated `ag-cosmos-helper`
|
|
23
14
|
|
|
24
15
|
### Features
|
|
25
16
|
|
|
17
|
+
* Add consensus-independent vat snapshot archiving configuration to AG_COSMOS_INIT ([ffc594f](https://github.com/Agoric/agoric-sdk/commit/ffc594f9441a9374646c43b69d289cc560962f64)), closes [#10036](https://github.com/Agoric/agoric-sdk/issues/10036)
|
|
18
|
+
* Add consensus-independent vat snapshot retention configuration to AG_COSMOS_INIT ([a5311b5](https://github.com/Agoric/agoric-sdk/commit/a5311b5a9eb257d4dfb4f18272608f00c1616abb)), closes [#9386](https://github.com/Agoric/agoric-sdk/issues/9386)
|
|
19
|
+
* Add consensus-independent vat transcript archiving configuration to AG_COSMOS_INIT ([d2d5803](https://github.com/Agoric/agoric-sdk/commit/d2d5803baab6e6379d179723244b2e92aac6319a)), closes [#10036](https://github.com/Agoric/agoric-sdk/issues/10036)
|
|
20
|
+
* Add consensus-independent vat transcript span retention configuration to AG_COSMOS_INIT ([3cf6b57](https://github.com/Agoric/agoric-sdk/commit/3cf6b57d9e1968c6197147419d5d177b5c42e62b)), closes [#9174](https://github.com/Agoric/agoric-sdk/issues/9174) [#9386](https://github.com/Agoric/agoric-sdk/issues/9386)
|
|
26
21
|
* add exporter.getHostKV() API ([eb564f9](https://github.com/Agoric/agoric-sdk/commit/eb564f9635397c0706e1f8255b3e125681e2d031)), closes [#8523](https://github.com/Agoric/agoric-sdk/issues/8523)
|
|
27
22
|
* Add tooling for standalone performance benchmarks ([058e54a](https://github.com/Agoric/agoric-sdk/commit/058e54aad93c04b57dfb3a411bff85c223ab5dd7))
|
|
28
23
|
* **agd:** try harder to find cosmic-swingset ([dd547f0](https://github.com/Agoric/agoric-sdk/commit/dd547f0a8057109a0bbe27a814fb3fc403ad3fd1))
|
|
24
|
+
* **cosmic-swingset:** Accept slogfile configuration in AG_COSMOS_INIT messages ([1c72193](https://github.com/Agoric/agoric-sdk/commit/1c72193c54126cff8a35f36b094743a415ab19aa))
|
|
29
25
|
* **cosmic-swingset:** add begin block check and transaction ([#8432](https://github.com/Agoric/agoric-sdk/issues/8432)) ([a9d113a](https://github.com/Agoric/agoric-sdk/commit/a9d113a09dfd93889ae985533535df53fdc771e7))
|
|
30
26
|
* **cosmic-swingset:** add JS upgrade plan handler stub ([655133e](https://github.com/Agoric/agoric-sdk/commit/655133ed909b5d632dc033e992214a7b6a1b5ab1))
|
|
31
27
|
* **cosmic-swingset:** add repair-metadata snapshot restore option ([4fc0113](https://github.com/Agoric/agoric-sdk/commit/4fc01134fab9402d5916f0593728acce4697da9e))
|
|
@@ -37,6 +33,9 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|
|
37
33
|
* **cosmos:** support core proposals set by upgrade handler ([605eb4b](https://github.com/Agoric/agoric-sdk/commit/605eb4b8f33d7646c3a9084d43ecd51029e12b80))
|
|
38
34
|
* **cosmos:** wire new swingset port handler ([ea582bf](https://github.com/Agoric/agoric-sdk/commit/ea582bf7738f82d0abe5529ee1ac9f2e117c957a))
|
|
39
35
|
* new 'boot' package with bootstrap configs ([8e3173b](https://github.com/Agoric/agoric-sdk/commit/8e3173b0b86a3dc90b31164bc4272c54e46a6641))
|
|
36
|
+
* Plumb maxVatsOnline from cosmos-sdk config to JS side of swingset ([50b22be](https://github.com/Agoric/agoric-sdk/commit/50b22be79a2fe62a20666c30d86cc5bb8c4f41b7)), closes [#9574](https://github.com/Agoric/agoric-sdk/issues/9574)
|
|
37
|
+
* Share cosmos-sdk runtime [viper] configuration with the cosmic-swingset VM ([950511e](https://github.com/Agoric/agoric-sdk/commit/950511ef1b9b7520bd3eaf8e97cbc315a945b836)), closes [#9946](https://github.com/Agoric/agoric-sdk/issues/9946)
|
|
38
|
+
* Share cosmos-sdk runtime [viper] configuration with the cosmic-swingset VM ([f8c6d50](https://github.com/Agoric/agoric-sdk/commit/f8c6d50e0f20a523caf0366d0ec7ac8b0a731b8e)), closes [#9946](https://github.com/Agoric/agoric-sdk/issues/9946)
|
|
40
39
|
* Simple removal of lien primarilly through code search ([#8988](https://github.com/Agoric/agoric-sdk/issues/8988)) ([695c440](https://github.com/Agoric/agoric-sdk/commit/695c440c0f48a3591b15a43665682c5f1ebbad9d))
|
|
41
40
|
* support `coreProposals.steps` ([80fa3d1](https://github.com/Agoric/agoric-sdk/commit/80fa3d14494706d825f51ac22e1bbf4ec68ce404))
|
|
42
41
|
* **vat-transfer:** first cut at working proposal ([2864bd5](https://github.com/Agoric/agoric-sdk/commit/2864bd5c12300c3595df9676bcfde894dbe59b29))
|
|
@@ -45,17 +44,24 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|
|
45
44
|
|
|
46
45
|
### Bug Fixes
|
|
47
46
|
|
|
47
|
+
* adopt `VTRANSFER_IBC_EVENT` as an action-type ([#9671](https://github.com/Agoric/agoric-sdk/issues/9671)) ([217005a](https://github.com/Agoric/agoric-sdk/commit/217005a921dcac6928c999e6bfe06330a5947ac5)), closes [#9670](https://github.com/Agoric/agoric-sdk/issues/9670)
|
|
48
|
+
* **cosmic-swingset:** add exportCallback interlock ([6547c83](https://github.com/Agoric/agoric-sdk/commit/6547c8318d83ca58704a4c911608706c25795c68)), closes [#9655](https://github.com/Agoric/agoric-sdk/issues/9655)
|
|
49
|
+
* **cosmic-swingset:** add missing bits for maxVatsOnline ([8c0c177](https://github.com/Agoric/agoric-sdk/commit/8c0c17752f7439db6f7aee9f88be1dedce2a1bf1))
|
|
48
50
|
* **cosmic-swingset:** backwards param compat in import/export ([bd49484](https://github.com/Agoric/agoric-sdk/commit/bd49484e5777b8675ed3be5e78e46f6a5d89b7db))
|
|
51
|
+
* **cosmic-swingset:** call upgradeSwingset at startup ([c769606](https://github.com/Agoric/agoric-sdk/commit/c7696069d0bebaf039a2f3e1a45ebdd8dc5198a2))
|
|
52
|
+
* **cosmic-swingset:** Exclude non-consensus configuration from bootstrap vat arguments ([08b3abb](https://github.com/Agoric/agoric-sdk/commit/08b3abb4d5ba183a45e84353406e67bbcc00a076)), closes [#9946](https://github.com/Agoric/agoric-sdk/issues/9946)
|
|
49
53
|
* **cosmic-swingset:** log level for swing-store export ([33c4a51](https://github.com/Agoric/agoric-sdk/commit/33c4a517f079c4ad17c30f9d1d13f181b06f112f))
|
|
50
54
|
* **cosmic-swingset:** merge `coreProposals` from bootstrap and upgrade plan ([2b38ebc](https://github.com/Agoric/agoric-sdk/commit/2b38ebc378847a878725419db37580405df0a28e))
|
|
51
55
|
* **cosmic-swingset:** only require vatconfig if uninitialized ([cfb72f3](https://github.com/Agoric/agoric-sdk/commit/cfb72f337cf650f303adfebaeffb1ee9ad0c0a92))
|
|
52
56
|
* **cosmic-swingset:** only search for the `vatconfig` on init ([b14ca40](https://github.com/Agoric/agoric-sdk/commit/b14ca404ea5bc314f99372a3eba878926f94f679))
|
|
57
|
+
* **cosmic-swingset:** plumbing for maxVatsOnline ([45a759a](https://github.com/Agoric/agoric-sdk/commit/45a759a71c8abc724618a12dfd8ae72552b9783e))
|
|
53
58
|
* **cosmic-swingset:** send started event before beginning actual export ([3c94159](https://github.com/Agoric/agoric-sdk/commit/3c94159bbe4b27a14eeb27612c4a73afa556c472))
|
|
54
59
|
* DEBUG harmony ([#8136](https://github.com/Agoric/agoric-sdk/issues/8136)) ([d2ea4b4](https://github.com/Agoric/agoric-sdk/commit/d2ea4b46b9efa61e97eec8711830d9fdd741ca55))
|
|
55
|
-
* endow with original unstructured `assert` ([#9514](https://github.com/Agoric/agoric-sdk/issues/9514)) ([
|
|
60
|
+
* endow with original unstructured `assert` ([#9514](https://github.com/Agoric/agoric-sdk/issues/9514)) ([f908f89](https://github.com/Agoric/agoric-sdk/commit/f908f89186162df83b540f6aeb1f4c665c3a56b4)), closes [#9515](https://github.com/Agoric/agoric-sdk/issues/9515) [#5672](https://github.com/Agoric/agoric-sdk/issues/5672) [#8332](https://github.com/Agoric/agoric-sdk/issues/8332) [#9513](https://github.com/Agoric/agoric-sdk/issues/9513) [#5672](https://github.com/Agoric/agoric-sdk/issues/5672) [#8332](https://github.com/Agoric/agoric-sdk/issues/8332) [#9513](https://github.com/Agoric/agoric-sdk/issues/9513) [#9515](https://github.com/Agoric/agoric-sdk/issues/9515) [#5672](https://github.com/Agoric/agoric-sdk/issues/5672) [#5672](https://github.com/Agoric/agoric-sdk/issues/5672) [#9513](https://github.com/Agoric/agoric-sdk/issues/9513) [#9513](https://github.com/Agoric/agoric-sdk/issues/9513)
|
|
56
61
|
* export state-sync snapshot without a DB write-lock ([3bc3799](https://github.com/Agoric/agoric-sdk/commit/3bc37990fd813136dab33dd93a1dcec073b187f9)), closes [#8523](https://github.com/Agoric/agoric-sdk/issues/8523)
|
|
57
62
|
* **sim-params:** power_flag casing ([66955c1](https://github.com/Agoric/agoric-sdk/commit/66955c1e70b63e6525ea10bc946f7c1a84e1e869))
|
|
58
63
|
* update for `[@jessie](https://github.com/jessie).js/safe-await-separator` ([94c6b3c](https://github.com/Agoric/agoric-sdk/commit/94c6b3c83a5326594f1e2886ae01d6a703a7a68f))
|
|
64
|
+
* **vm-config:** always use `init-localchain` and `init-transfer` ([870d205](https://github.com/Agoric/agoric-sdk/commit/870d2052ce1ca6778f6afa4396e01d5833b7ef38))
|
|
59
65
|
* **x/swingset:** switch export/import to replay artifact level ([6ab24b2](https://github.com/Agoric/agoric-sdk/commit/6ab24b299f31affc0a638cc6352678a2c167044c))
|
|
60
66
|
|
|
61
67
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/cosmic-swingset",
|
|
3
|
-
"version": "0.42.0-upgrade-
|
|
3
|
+
"version": "0.42.0-upgrade-17-dev-a61cdab.0+a61cdab",
|
|
4
4
|
"description": "Agoric's Cosmos blockchain integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -22,24 +22,25 @@
|
|
|
22
22
|
"author": "Agoric",
|
|
23
23
|
"license": "Apache-2.0",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@agoric/
|
|
26
|
-
"@agoric/
|
|
27
|
-
"@agoric/
|
|
28
|
-
"@agoric/
|
|
29
|
-
"@agoric/
|
|
30
|
-
"@agoric/store": "0.9.
|
|
31
|
-
"@agoric/
|
|
32
|
-
"@agoric/
|
|
33
|
-
"@agoric/
|
|
34
|
-
"@
|
|
35
|
-
"@endo/
|
|
36
|
-
"@endo/
|
|
37
|
-
"@endo/far": "^1.1.
|
|
38
|
-
"@endo/import-bundle": "^1.
|
|
39
|
-
"@endo/init": "^1.1.
|
|
40
|
-
"@endo/marshal": "^1.5.
|
|
41
|
-
"@endo/nat": "^5.0.
|
|
42
|
-
"@endo/
|
|
25
|
+
"@agoric/builders": "0.2.0-upgrade-17-dev-a61cdab.0+a61cdab",
|
|
26
|
+
"@agoric/cosmos": "0.35.0-upgrade-17-dev-a61cdab.0+a61cdab",
|
|
27
|
+
"@agoric/deploy-script-support": "0.10.4-upgrade-17-dev-a61cdab.0+a61cdab",
|
|
28
|
+
"@agoric/internal": "0.4.0-upgrade-17-dev-a61cdab.0+a61cdab",
|
|
29
|
+
"@agoric/store": "0.9.3-upgrade-17-dev-a61cdab.0+a61cdab",
|
|
30
|
+
"@agoric/swing-store": "0.9.2-upgrade-17-dev-a61cdab.0+a61cdab",
|
|
31
|
+
"@agoric/swingset-vat": "0.33.0-upgrade-17-dev-a61cdab.0+a61cdab",
|
|
32
|
+
"@agoric/telemetry": "0.6.3-upgrade-17-dev-a61cdab.0+a61cdab",
|
|
33
|
+
"@agoric/vm-config": "0.1.1-upgrade-17-dev-a61cdab.0+a61cdab",
|
|
34
|
+
"@endo/bundle-source": "^3.4.0",
|
|
35
|
+
"@endo/env-options": "^1.1.6",
|
|
36
|
+
"@endo/errors": "^1.2.5",
|
|
37
|
+
"@endo/far": "^1.1.5",
|
|
38
|
+
"@endo/import-bundle": "^1.2.2",
|
|
39
|
+
"@endo/init": "^1.1.4",
|
|
40
|
+
"@endo/marshal": "^1.5.3",
|
|
41
|
+
"@endo/nat": "^5.0.10",
|
|
42
|
+
"@endo/patterns": "^1.4.3",
|
|
43
|
+
"@endo/promise-kit": "^1.1.5",
|
|
43
44
|
"@iarna/toml": "^2.2.3",
|
|
44
45
|
"@opentelemetry/api": "~1.3.0",
|
|
45
46
|
"@opentelemetry/sdk-metrics": "~1.9.0",
|
|
@@ -68,7 +69,7 @@
|
|
|
68
69
|
"timeout": "20m"
|
|
69
70
|
},
|
|
70
71
|
"typeCoverage": {
|
|
71
|
-
"atLeast": 80.
|
|
72
|
+
"atLeast": 80.53
|
|
72
73
|
},
|
|
73
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "a61cdabb23bd2c846e003dee7326018a7462a929"
|
|
74
75
|
}
|
package/src/chain-main.js
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
import v8 from 'node:v8';
|
|
5
5
|
import process from 'node:process';
|
|
6
6
|
import fs from 'node:fs';
|
|
7
7
|
import fsPromises from 'node:fs/promises';
|
|
8
|
-
import { performance } from 'perf_hooks';
|
|
9
|
-
import { resolve as importMetaResolve } from 'import-meta-resolve';
|
|
10
|
-
import tmpfs from 'tmp';
|
|
8
|
+
import { performance } from 'node:perf_hooks';
|
|
11
9
|
import { fork } from 'node:child_process';
|
|
10
|
+
import { resolve as importMetaResolve } from 'import-meta-resolve';
|
|
11
|
+
import tmp from 'tmp';
|
|
12
12
|
|
|
13
|
+
import { Fail, q } from '@endo/errors';
|
|
13
14
|
import { E } from '@endo/far';
|
|
15
|
+
import { makeMarshal } from '@endo/marshal';
|
|
16
|
+
import { isNat } from '@endo/nat';
|
|
17
|
+
import { M, mustMatch } from '@endo/patterns';
|
|
14
18
|
import engineGC from '@agoric/internal/src/lib-nodejs/engine-gc.js';
|
|
15
19
|
import { waitUntilQuiescent } from '@agoric/internal/src/lib-nodejs/waitUntilQuiescent.js';
|
|
16
20
|
import {
|
|
@@ -18,19 +22,21 @@ import {
|
|
|
18
22
|
exportMailbox,
|
|
19
23
|
} from '@agoric/swingset-vat/src/devices/mailbox/mailbox.js';
|
|
20
24
|
|
|
21
|
-
import { Fail, q } from '@agoric/assert';
|
|
22
25
|
import { makeSlogSender, tryFlushSlogSender } from '@agoric/telemetry';
|
|
23
26
|
|
|
24
27
|
import {
|
|
25
28
|
makeChainStorageRoot,
|
|
26
29
|
makeSerializeToStorage,
|
|
27
30
|
} from '@agoric/internal/src/lib-chainStorage.js';
|
|
28
|
-
import { makeMarshal } from '@endo/marshal';
|
|
29
31
|
import { makeShutdown } from '@agoric/internal/src/node/shutdown.js';
|
|
30
32
|
|
|
31
33
|
import * as STORAGE_PATH from '@agoric/internal/src/chain-storage-paths.js';
|
|
32
34
|
import * as ActionType from '@agoric/internal/src/action-types.js';
|
|
33
35
|
import { BridgeId, CosmosInitKeyToBridgeId } from '@agoric/internal';
|
|
36
|
+
import {
|
|
37
|
+
makeArchiveSnapshot,
|
|
38
|
+
makeArchiveTranscript,
|
|
39
|
+
} from '@agoric/swing-store';
|
|
34
40
|
import {
|
|
35
41
|
makeBufferedStorage,
|
|
36
42
|
makeReadCachingStorage,
|
|
@@ -48,6 +54,8 @@ import {
|
|
|
48
54
|
validateImporterOptions,
|
|
49
55
|
} from './import-kernel-db.js';
|
|
50
56
|
|
|
57
|
+
const ignore = () => {};
|
|
58
|
+
|
|
51
59
|
// eslint-disable-next-line no-unused-vars
|
|
52
60
|
let whenHellFreezesOver = null;
|
|
53
61
|
|
|
@@ -62,6 +70,66 @@ const toNumber = specimen => {
|
|
|
62
70
|
return number;
|
|
63
71
|
};
|
|
64
72
|
|
|
73
|
+
/**
|
|
74
|
+
* The swingset config object parsed and resolved by cosmos in
|
|
75
|
+
* `golang/cosmos/x/swingset/config.go`. The shape should be kept in sync
|
|
76
|
+
* with `SwingsetConfig` defined there.
|
|
77
|
+
*
|
|
78
|
+
* @typedef {object} CosmosSwingsetConfig
|
|
79
|
+
* @property {string} [slogfile]
|
|
80
|
+
* @property {number} [maxVatsOnline]
|
|
81
|
+
* @property {'debug' | 'operational'} [vatSnapshotRetention]
|
|
82
|
+
* @property {'archival' | 'operational'} [vatTranscriptRetention]
|
|
83
|
+
* @property {string} [vatSnapshotArchiveDir]
|
|
84
|
+
* @property {string} [vatTranscriptArchiveDir]
|
|
85
|
+
*/
|
|
86
|
+
const SwingsetConfigShape = M.splitRecord(
|
|
87
|
+
// All known properties are optional, but unknown properties are not allowed.
|
|
88
|
+
{},
|
|
89
|
+
{
|
|
90
|
+
slogfile: M.string(),
|
|
91
|
+
maxVatsOnline: M.number(),
|
|
92
|
+
vatSnapshotRetention: M.or('debug', 'operational'),
|
|
93
|
+
vatTranscriptRetention: M.or('archival', 'operational'),
|
|
94
|
+
vatSnapshotArchiveDir: M.string(),
|
|
95
|
+
vatTranscriptArchiveDir: M.string(),
|
|
96
|
+
},
|
|
97
|
+
{},
|
|
98
|
+
);
|
|
99
|
+
const validateSwingsetConfig = swingsetConfig => {
|
|
100
|
+
mustMatch(swingsetConfig, SwingsetConfigShape);
|
|
101
|
+
const { maxVatsOnline } = swingsetConfig;
|
|
102
|
+
maxVatsOnline === undefined ||
|
|
103
|
+
(isNat(maxVatsOnline) && maxVatsOnline > 0) ||
|
|
104
|
+
Fail`maxVatsOnline must be a positive integer`;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* A boot message consists of cosmosInitAction fields that are subject to
|
|
109
|
+
* consensus. See cosmosInitAction in {@link ../../../golang/cosmos/app/app.go}.
|
|
110
|
+
*
|
|
111
|
+
* @param {any} initAction
|
|
112
|
+
*/
|
|
113
|
+
const makeBootMsg = initAction => {
|
|
114
|
+
const {
|
|
115
|
+
type,
|
|
116
|
+
blockTime,
|
|
117
|
+
blockHeight,
|
|
118
|
+
chainID,
|
|
119
|
+
params,
|
|
120
|
+
// NB: resolvedConfig is independent of consensus and MUST NOT be included
|
|
121
|
+
supplyCoins,
|
|
122
|
+
} = initAction;
|
|
123
|
+
return {
|
|
124
|
+
type,
|
|
125
|
+
blockTime,
|
|
126
|
+
blockHeight,
|
|
127
|
+
chainID,
|
|
128
|
+
params,
|
|
129
|
+
supplyCoins,
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
|
|
65
133
|
/**
|
|
66
134
|
* @template {unknown} [T=unknown]
|
|
67
135
|
* @param {(req: string) => string} call
|
|
@@ -99,8 +167,8 @@ const makePrefixedBridgeStorage = (
|
|
|
99
167
|
return fromBridgeStringValue(ret);
|
|
100
168
|
},
|
|
101
169
|
set: (key, value) => {
|
|
102
|
-
const
|
|
103
|
-
const entry = [
|
|
170
|
+
const fullPath = `${prefix}${key}`;
|
|
171
|
+
const entry = [fullPath, toBridgeStringValue(value)];
|
|
104
172
|
call(
|
|
105
173
|
stringify({
|
|
106
174
|
method: setterMethod,
|
|
@@ -109,8 +177,8 @@ const makePrefixedBridgeStorage = (
|
|
|
109
177
|
);
|
|
110
178
|
},
|
|
111
179
|
delete: key => {
|
|
112
|
-
const
|
|
113
|
-
const entry = [
|
|
180
|
+
const fullPath = `${prefix}${key}`;
|
|
181
|
+
const entry = [fullPath];
|
|
114
182
|
call(
|
|
115
183
|
stringify({
|
|
116
184
|
method: setterMethod,
|
|
@@ -214,7 +282,7 @@ export default async function main(progname, args, { env, homedir, agcc }) {
|
|
|
214
282
|
|
|
215
283
|
const clearChainSends = async () => {
|
|
216
284
|
// Cosmos should have blocked before calling commit, but wait just in case
|
|
217
|
-
await stateSyncExport?.exporter?.onStarted().catch(
|
|
285
|
+
await stateSyncExport?.exporter?.onStarted().catch(ignore);
|
|
218
286
|
|
|
219
287
|
const chainSends = savedChainSends;
|
|
220
288
|
savedChainSends = [];
|
|
@@ -246,10 +314,33 @@ export default async function main(progname, args, { env, homedir, agcc }) {
|
|
|
246
314
|
/** @type {((obj: object) => void) | undefined} */
|
|
247
315
|
let writeSlogObject;
|
|
248
316
|
|
|
249
|
-
// the storagePort
|
|
317
|
+
// In the past, storagePort could change with every message. It's defined out
|
|
250
318
|
// here so 'sendToChainStorage' can close over the single mutable instance,
|
|
251
319
|
// when we updated the 'portNums.storage' value each time toSwingSet was called.
|
|
252
|
-
async function launchAndInitializeSwingSet(
|
|
320
|
+
async function launchAndInitializeSwingSet(initAction) {
|
|
321
|
+
const { XSNAP_KEEP_SNAPSHOTS, NODE_HEAP_SNAPSHOTS = -1 } = env;
|
|
322
|
+
|
|
323
|
+
/** @type {CosmosSwingsetConfig} */
|
|
324
|
+
const swingsetConfig = harden(initAction.resolvedConfig || {});
|
|
325
|
+
validateSwingsetConfig(swingsetConfig);
|
|
326
|
+
const {
|
|
327
|
+
slogfile,
|
|
328
|
+
vatSnapshotRetention,
|
|
329
|
+
vatTranscriptRetention,
|
|
330
|
+
vatSnapshotArchiveDir,
|
|
331
|
+
vatTranscriptArchiveDir,
|
|
332
|
+
} = swingsetConfig;
|
|
333
|
+
const keepSnapshots = vatSnapshotRetention
|
|
334
|
+
? vatSnapshotRetention !== 'operational'
|
|
335
|
+
: ['1', 'true'].includes(XSNAP_KEEP_SNAPSHOTS);
|
|
336
|
+
const keepTranscripts = vatTranscriptRetention
|
|
337
|
+
? vatTranscriptRetention !== 'operational'
|
|
338
|
+
: false;
|
|
339
|
+
|
|
340
|
+
// As a kludge, back-propagate selected configuration into environment variables.
|
|
341
|
+
// eslint-disable-next-line dot-notation
|
|
342
|
+
if (slogfile) env['SLOGFILE'] = slogfile;
|
|
343
|
+
|
|
253
344
|
const sendToChainStorage = msg => chainSend(portNums.storage, msg);
|
|
254
345
|
// this object is used to store the mailbox state.
|
|
255
346
|
const fromBridgeMailbox = data => {
|
|
@@ -363,7 +454,7 @@ export default async function main(progname, args, { env, homedir, agcc }) {
|
|
|
363
454
|
};
|
|
364
455
|
|
|
365
456
|
const argv = {
|
|
366
|
-
bootMsg,
|
|
457
|
+
bootMsg: makeBootMsg(initAction),
|
|
367
458
|
};
|
|
368
459
|
const getVatConfig = async () => {
|
|
369
460
|
const vatHref = await importMetaResolve(
|
|
@@ -384,7 +475,6 @@ export default async function main(progname, args, { env, homedir, agcc }) {
|
|
|
384
475
|
serviceName: TELEMETRY_SERVICE_NAME,
|
|
385
476
|
});
|
|
386
477
|
|
|
387
|
-
const { XSNAP_KEEP_SNAPSHOTS, NODE_HEAP_SNAPSHOTS = -1 } = env;
|
|
388
478
|
const slogSender = await makeSlogSender({
|
|
389
479
|
stateDir: stateDBDir,
|
|
390
480
|
env,
|
|
@@ -394,17 +484,14 @@ export default async function main(progname, args, { env, homedir, agcc }) {
|
|
|
394
484
|
const swingStoreTraceFile = processValue.getPath({
|
|
395
485
|
envName: 'SWING_STORE_TRACE',
|
|
396
486
|
flagName: 'trace-store',
|
|
397
|
-
trueValue:
|
|
487
|
+
trueValue: path.resolve(stateDBDir, 'store-trace.log'),
|
|
398
488
|
});
|
|
399
489
|
|
|
400
|
-
const keepSnapshots =
|
|
401
|
-
XSNAP_KEEP_SNAPSHOTS === '1' || XSNAP_KEEP_SNAPSHOTS === 'true';
|
|
402
|
-
|
|
403
490
|
const nodeHeapSnapshots = Number.parseInt(NODE_HEAP_SNAPSHOTS, 10);
|
|
404
491
|
|
|
405
492
|
let lastCommitTime = 0;
|
|
406
493
|
let commitCallsSinceLastSnapshot = NaN;
|
|
407
|
-
const snapshotBaseDir =
|
|
494
|
+
const snapshotBaseDir = path.resolve(stateDBDir, 'node-heap-snapshots');
|
|
408
495
|
|
|
409
496
|
if (nodeHeapSnapshots >= 0) {
|
|
410
497
|
fs.mkdirSync(snapshotBaseDir, { recursive: true });
|
|
@@ -440,7 +527,7 @@ export default async function main(progname, args, { env, homedir, agcc }) {
|
|
|
440
527
|
) {
|
|
441
528
|
commitCallsSinceLastSnapshot = 0;
|
|
442
529
|
heapSnapshot = `Heap-${process.pid}-${Date.now()}.heapsnapshot`;
|
|
443
|
-
const snapshotPath =
|
|
530
|
+
const snapshotPath = path.resolve(snapshotBaseDir, heapSnapshot);
|
|
444
531
|
v8.writeHeapSnapshot(snapshotPath);
|
|
445
532
|
heapSnapshotTime = performance.now() - t3;
|
|
446
533
|
}
|
|
@@ -463,6 +550,14 @@ export default async function main(progname, args, { env, homedir, agcc }) {
|
|
|
463
550
|
}
|
|
464
551
|
};
|
|
465
552
|
|
|
553
|
+
const fsPowers = { fs, path, tmp };
|
|
554
|
+
const archiveSnapshot = vatSnapshotArchiveDir
|
|
555
|
+
? makeArchiveSnapshot(vatSnapshotArchiveDir, fsPowers)
|
|
556
|
+
: undefined;
|
|
557
|
+
const archiveTranscript = vatTranscriptArchiveDir
|
|
558
|
+
? makeArchiveTranscript(vatTranscriptArchiveDir, fsPowers)
|
|
559
|
+
: undefined;
|
|
560
|
+
|
|
466
561
|
const s = await launch({
|
|
467
562
|
actionQueueStorage,
|
|
468
563
|
highPriorityQueueStorage,
|
|
@@ -481,7 +576,11 @@ export default async function main(progname, args, { env, homedir, agcc }) {
|
|
|
481
576
|
swingStoreExportCallback,
|
|
482
577
|
swingStoreTraceFile,
|
|
483
578
|
keepSnapshots,
|
|
579
|
+
keepTranscripts,
|
|
580
|
+
archiveSnapshot,
|
|
581
|
+
archiveTranscript,
|
|
484
582
|
afterCommitCallback,
|
|
583
|
+
swingsetConfig,
|
|
485
584
|
});
|
|
486
585
|
|
|
487
586
|
const { blockingSend, shutdown } = s;
|
|
@@ -489,21 +588,19 @@ export default async function main(progname, args, { env, homedir, agcc }) {
|
|
|
489
588
|
|
|
490
589
|
let pendingBlockingSend = Promise.resolve();
|
|
491
590
|
|
|
492
|
-
registerShutdown(async interrupted =>
|
|
493
|
-
Promise.all([
|
|
591
|
+
registerShutdown(async interrupted => {
|
|
592
|
+
await Promise.all([
|
|
494
593
|
interrupted && pendingBlockingSend.then(shutdown),
|
|
495
594
|
discardStateSyncExport(),
|
|
496
|
-
])
|
|
497
|
-
);
|
|
595
|
+
]);
|
|
596
|
+
});
|
|
498
597
|
|
|
499
|
-
|
|
598
|
+
const blockingSendSpy = async action => {
|
|
500
599
|
const result = blockingSend(action);
|
|
501
|
-
pendingBlockingSend = Promise.resolve(result).then(
|
|
502
|
-
() => {},
|
|
503
|
-
() => {},
|
|
504
|
-
);
|
|
600
|
+
pendingBlockingSend = Promise.resolve(result).then(ignore, ignore);
|
|
505
601
|
return result;
|
|
506
602
|
};
|
|
603
|
+
return blockingSendSpy;
|
|
507
604
|
}
|
|
508
605
|
|
|
509
606
|
/** @type {Awaited<ReturnType<typeof launch>>['blockingSend'] | undefined} */
|
|
@@ -534,7 +631,7 @@ export default async function main(progname, args, { env, homedir, agcc }) {
|
|
|
534
631
|
);
|
|
535
632
|
return performStateSyncImport(options, {
|
|
536
633
|
fs: { ...fs, ...fsPromises },
|
|
537
|
-
pathResolve,
|
|
634
|
+
pathResolve: path.resolve,
|
|
538
635
|
log: null,
|
|
539
636
|
});
|
|
540
637
|
}
|
|
@@ -558,7 +655,7 @@ export default async function main(progname, args, { env, homedir, agcc }) {
|
|
|
558
655
|
stateSyncExport = exportData;
|
|
559
656
|
|
|
560
657
|
await new Promise((resolve, reject) => {
|
|
561
|
-
|
|
658
|
+
tmp.dir(
|
|
562
659
|
{
|
|
563
660
|
prefix: `agd-state-sync-${blockHeight}-`,
|
|
564
661
|
unsafeCleanup: true,
|
|
@@ -658,6 +755,7 @@ export default async function main(progname, args, { env, homedir, agcc }) {
|
|
|
658
755
|
|
|
659
756
|
!blockingSend || Fail`Swingset already initialized`;
|
|
660
757
|
|
|
758
|
+
// Capture "port numbers" for communicating with cosmos modules.
|
|
661
759
|
for (const [key, value] of Object.entries(action)) {
|
|
662
760
|
const portAlias = CosmosInitKeyToBridgeId[key];
|
|
663
761
|
if (portAlias) {
|
package/src/export-kernel-db.js
CHANGED
|
@@ -10,8 +10,8 @@ import fsPower from 'fs/promises';
|
|
|
10
10
|
import pathPower from 'path';
|
|
11
11
|
import { fileURLToPath } from 'url';
|
|
12
12
|
|
|
13
|
+
import { Fail, q } from '@endo/errors';
|
|
13
14
|
import { makePromiseKit } from '@endo/promise-kit';
|
|
14
|
-
import { Fail, q } from '@agoric/assert';
|
|
15
15
|
import { makeShutdown } from '@agoric/internal/src/node/shutdown.js';
|
|
16
16
|
import { waitUntilQuiescent } from '@agoric/internal/src/lib-nodejs/waitUntilQuiescent.js';
|
|
17
17
|
import { makeSwingStoreExporter } from '@agoric/swing-store';
|
package/src/export-storage.js
CHANGED
package/src/import-kernel-db.js
CHANGED
|
@@ -11,8 +11,8 @@ import fsPower from 'fs';
|
|
|
11
11
|
import fsPromisesPower from 'fs/promises';
|
|
12
12
|
import pathPower from 'path';
|
|
13
13
|
|
|
14
|
+
import { Fail, q } from '@endo/errors';
|
|
14
15
|
import BufferLineTransform from '@agoric/internal/src/node/buffer-line-transform.js';
|
|
15
|
-
import { Fail, q } from '@agoric/assert';
|
|
16
16
|
import { importSwingStore, openSwingStore } from '@agoric/swing-store';
|
|
17
17
|
|
|
18
18
|
import { isEntrypoint } from './helpers/is-entrypoint.js';
|
package/src/kernel-stats.js
CHANGED
|
@@ -316,13 +316,13 @@ export function exportKernelStats({
|
|
|
316
316
|
}
|
|
317
317
|
kernelStatsLast = now;
|
|
318
318
|
kernelStatsCache = controller.getStats();
|
|
319
|
-
Object.keys(kernelStatsCache)
|
|
319
|
+
for (const key of Object.keys(kernelStatsCache)) {
|
|
320
320
|
warnUnexpectedKernelStat(key);
|
|
321
|
-
}
|
|
321
|
+
}
|
|
322
322
|
return kernelStatsCache;
|
|
323
323
|
};
|
|
324
324
|
|
|
325
|
-
|
|
325
|
+
for (const { key, name, sub, ...options } of KERNEL_STATS_SUM_METRICS) {
|
|
326
326
|
expectedKernelStats.add(key);
|
|
327
327
|
let counter = kernelStatsCounters.get(name);
|
|
328
328
|
if (!counter) {
|
|
@@ -337,9 +337,9 @@ export function exportKernelStats({
|
|
|
337
337
|
observableResult.observe(getKernelStats()[key], reportedAttributes);
|
|
338
338
|
});
|
|
339
339
|
kernelStatsMetrics.add(key);
|
|
340
|
-
}
|
|
340
|
+
}
|
|
341
341
|
|
|
342
|
-
|
|
342
|
+
for (const { key, name, sub, ...options } of KERNEL_STATS_UPDOWN_METRICS) {
|
|
343
343
|
expectedKernelStats.add(key);
|
|
344
344
|
expectedKernelStats.add(`${key}Up`);
|
|
345
345
|
expectedKernelStats.add(`${key}Down`);
|
|
@@ -357,7 +357,7 @@ export function exportKernelStats({
|
|
|
357
357
|
observableResult.observe(getKernelStats()[key], reportedAttributes);
|
|
358
358
|
});
|
|
359
359
|
kernelStatsMetrics.add(key);
|
|
360
|
-
}
|
|
360
|
+
}
|
|
361
361
|
|
|
362
362
|
if (inboundQueueMetrics) {
|
|
363
363
|
// These are not kernelStatsMetrics, they're outside the kernel.
|
|
@@ -425,13 +425,13 @@ export function exportKernelStats({
|
|
|
425
425
|
|
|
426
426
|
function checkKernelStats(stats) {
|
|
427
427
|
const notYetFoundKernelStats = new Set(kernelStatsMetrics.keys());
|
|
428
|
-
Object.keys(stats)
|
|
428
|
+
for (const key of Object.keys(stats)) {
|
|
429
429
|
notYetFoundKernelStats.delete(key);
|
|
430
430
|
warnUnexpectedKernelStat(key);
|
|
431
|
-
}
|
|
432
|
-
|
|
431
|
+
}
|
|
432
|
+
for (const key of notYetFoundKernelStats) {
|
|
433
433
|
log.warn(`Expected SwingSet kernel statistic`, key, `not found`);
|
|
434
|
-
}
|
|
434
|
+
}
|
|
435
435
|
}
|
|
436
436
|
|
|
437
437
|
// We check everything on initialization. Other checks happen when scraping.
|
package/src/launch-chain.js
CHANGED
|
@@ -7,11 +7,10 @@ import '@agoric/builders';
|
|
|
7
7
|
|
|
8
8
|
import anylogger from 'anylogger';
|
|
9
9
|
|
|
10
|
+
import { assert, Fail } from '@endo/errors';
|
|
10
11
|
import { E } from '@endo/far';
|
|
11
12
|
import bundleSource from '@endo/bundle-source';
|
|
12
13
|
|
|
13
|
-
/** @import {RunPolicy} from '@agoric/swingset-vat' */
|
|
14
|
-
|
|
15
14
|
import {
|
|
16
15
|
buildMailbox,
|
|
17
16
|
buildMailboxStateMap,
|
|
@@ -22,9 +21,9 @@ import {
|
|
|
22
21
|
makeSwingsetController,
|
|
23
22
|
loadBasedir,
|
|
24
23
|
loadSwingsetConfigFile,
|
|
24
|
+
upgradeSwingset,
|
|
25
25
|
} from '@agoric/swingset-vat';
|
|
26
26
|
import { waitUntilQuiescent } from '@agoric/internal/src/lib-nodejs/waitUntilQuiescent.js';
|
|
27
|
-
import { assert, Fail } from '@agoric/assert';
|
|
28
27
|
import { openSwingStore } from '@agoric/swing-store';
|
|
29
28
|
import { BridgeId as BRIDGE_ID } from '@agoric/internal';
|
|
30
29
|
import { makeWithQueue } from '@agoric/internal/src/queue.js';
|
|
@@ -53,6 +52,8 @@ import { makeQueue, makeQueueStorageMock } from './helpers/make-queue.js';
|
|
|
53
52
|
import { exportStorage } from './export-storage.js';
|
|
54
53
|
import { parseLocatedJson } from './helpers/json.js';
|
|
55
54
|
|
|
55
|
+
/** @import {RunPolicy} from '@agoric/swingset-vat' */
|
|
56
|
+
|
|
56
57
|
const console = anylogger('launch-chain');
|
|
57
58
|
const blockManagerConsole = anylogger('block-manager');
|
|
58
59
|
|
|
@@ -96,7 +97,7 @@ const getHostKey = path => `host.${path}`;
|
|
|
96
97
|
|
|
97
98
|
/**
|
|
98
99
|
* @param {Map<*, *>} mailboxStorage
|
|
99
|
-
* @param {
|
|
100
|
+
* @param {((dstID: string, obj: any) => any)} bridgeOutbound
|
|
100
101
|
* @param {SwingStoreKernelStorage} kernelStorage
|
|
101
102
|
* @param {string | (() => string | Promise<string>)} vatconfig absolute path or thunk
|
|
102
103
|
* @param {unknown} bootstrapArgs JSON-serializable data
|
|
@@ -118,22 +119,21 @@ export async function buildSwingset(
|
|
|
118
119
|
verbose,
|
|
119
120
|
profileVats,
|
|
120
121
|
debugVats,
|
|
122
|
+
warehousePolicy,
|
|
121
123
|
},
|
|
122
124
|
) {
|
|
123
125
|
const debugPrefix = debugName === undefined ? '' : `${debugName}:`;
|
|
124
126
|
const mbs = buildMailboxStateMap(mailboxStorage);
|
|
125
127
|
|
|
126
|
-
const bridgeDevice =
|
|
128
|
+
const bridgeDevice = buildBridge(bridgeOutbound);
|
|
127
129
|
const mailboxDevice = buildMailbox(mbs);
|
|
128
130
|
const timerDevice = buildTimer();
|
|
129
131
|
|
|
130
132
|
const deviceEndowments = {
|
|
131
133
|
mailbox: { ...mailboxDevice.endowments },
|
|
132
134
|
timer: { ...timerDevice.endowments },
|
|
135
|
+
bridge: { ...bridgeDevice.endowments },
|
|
133
136
|
};
|
|
134
|
-
if (bridgeDevice) {
|
|
135
|
-
deviceEndowments.bridge = { ...bridgeDevice.endowments };
|
|
136
|
-
}
|
|
137
137
|
|
|
138
138
|
async function ensureSwingsetInitialized() {
|
|
139
139
|
if (swingsetIsInitialized(kernelStorage)) {
|
|
@@ -175,18 +175,16 @@ export async function buildSwingset(
|
|
|
175
175
|
const bootVat =
|
|
176
176
|
swingsetConfig.vats[swingsetConfig.bootstrap || 'bootstrap'];
|
|
177
177
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
bridgeOutbound(BRIDGE_ID.STORAGE, { method, args });
|
|
178
|
+
const batchChainStorage = (method, args) =>
|
|
179
|
+
bridgeOutbound(BRIDGE_ID.STORAGE, { method, args });
|
|
181
180
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
181
|
+
// Extract data from chain storage as [path, value?] pairs.
|
|
182
|
+
const chainStorageEntries = exportStorage(
|
|
183
|
+
batchChainStorage,
|
|
184
|
+
exportStorageSubtrees,
|
|
185
|
+
clearStorageSubtrees,
|
|
186
|
+
);
|
|
187
|
+
bootVat.parameters = { ...bootVat.parameters, chainStorageEntries };
|
|
190
188
|
|
|
191
189
|
// Since only on-chain swingsets like `agd` have a bridge (and thereby
|
|
192
190
|
// `CORE_EVAL` support), things like `ag-solo` will need to do the
|
|
@@ -217,7 +215,8 @@ export async function buildSwingset(
|
|
|
217
215
|
return bridgedCoreProposals;
|
|
218
216
|
}
|
|
219
217
|
|
|
220
|
-
const
|
|
218
|
+
const pendingCoreProposals = await ensureSwingsetInitialized();
|
|
219
|
+
upgradeSwingset(kernelStorage);
|
|
221
220
|
const controller = await makeSwingsetController(
|
|
222
221
|
kernelStorage,
|
|
223
222
|
deviceEndowments,
|
|
@@ -228,6 +227,7 @@ export async function buildSwingset(
|
|
|
228
227
|
verbose,
|
|
229
228
|
profileVats,
|
|
230
229
|
debugVats,
|
|
230
|
+
warehousePolicy,
|
|
231
231
|
},
|
|
232
232
|
);
|
|
233
233
|
|
|
@@ -235,10 +235,10 @@ export async function buildSwingset(
|
|
|
235
235
|
// (either on bootstrap block (0) or in endBlock).
|
|
236
236
|
|
|
237
237
|
return {
|
|
238
|
-
coreProposals,
|
|
238
|
+
coreProposals: pendingCoreProposals,
|
|
239
239
|
controller,
|
|
240
240
|
mb: mailboxDevice,
|
|
241
|
-
bridgeInbound: bridgeDevice
|
|
241
|
+
bridgeInbound: bridgeDevice.deliverInbound,
|
|
242
242
|
timer: timerDevice,
|
|
243
243
|
};
|
|
244
244
|
}
|
|
@@ -331,10 +331,33 @@ export async function launch({
|
|
|
331
331
|
swingStoreTraceFile,
|
|
332
332
|
swingStoreExportCallback,
|
|
333
333
|
keepSnapshots,
|
|
334
|
+
keepTranscripts,
|
|
335
|
+
archiveSnapshot,
|
|
336
|
+
archiveTranscript,
|
|
334
337
|
afterCommitCallback = async () => ({}),
|
|
338
|
+
swingsetConfig,
|
|
335
339
|
}) {
|
|
336
340
|
console.info('Launching SwingSet kernel');
|
|
337
341
|
|
|
342
|
+
// The swingstore export-data callback gives us export-data records,
|
|
343
|
+
// which must be written into IAVL by sending them over to the
|
|
344
|
+
// golang side with swingStoreExportCallback . However, that
|
|
345
|
+
// callback isn't ready right away, so if e.g. openSwingStore() were
|
|
346
|
+
// to invoke it, we might lose those records. Likewise
|
|
347
|
+
// saveOutsideState() gathers the chainSends just before calling
|
|
348
|
+
// commit, so if the callback were invoked during commit(), those
|
|
349
|
+
// records would be left for a subsequent block, which would break
|
|
350
|
+
// consensus if the node crashed before the next commit. So this
|
|
351
|
+
// `allowExportCallback` flag serves to catch these two cases.
|
|
352
|
+
//
|
|
353
|
+
// Note that swingstore is within its rights to call exportCallback
|
|
354
|
+
// during openSwingStore() or commit(), it just happens to not do so
|
|
355
|
+
// right now. If that changes under maintenance, this guard should
|
|
356
|
+
// turn a corruption bug into a crash bug. See
|
|
357
|
+
// https://github.com/Agoric/agoric-sdk/issues/9655 for details
|
|
358
|
+
|
|
359
|
+
let allowExportCallback = false;
|
|
360
|
+
|
|
338
361
|
// The swingStore's exportCallback is synchronous, however we allow the
|
|
339
362
|
// callback provided to launch-chain to be asynchronous. The callbacks are
|
|
340
363
|
// invoked sequentially like if they were awaited, and the block manager
|
|
@@ -345,6 +368,7 @@ export async function launch({
|
|
|
345
368
|
const swingStoreExportSyncCallback =
|
|
346
369
|
swingStoreExportCallback &&
|
|
347
370
|
(updates => {
|
|
371
|
+
assert(allowExportCallback, 'export-data callback called at bad time');
|
|
348
372
|
pendingSwingStoreExport = swingStoreExportCallbackWithQueue(updates);
|
|
349
373
|
});
|
|
350
374
|
|
|
@@ -352,6 +376,9 @@ export async function launch({
|
|
|
352
376
|
traceFile: swingStoreTraceFile,
|
|
353
377
|
exportCallback: swingStoreExportSyncCallback,
|
|
354
378
|
keepSnapshots,
|
|
379
|
+
keepTranscripts,
|
|
380
|
+
archiveSnapshot,
|
|
381
|
+
archiveTranscript,
|
|
355
382
|
});
|
|
356
383
|
const { kvStore, commit } = hostStorage;
|
|
357
384
|
|
|
@@ -376,6 +403,9 @@ export async function launch({
|
|
|
376
403
|
});
|
|
377
404
|
|
|
378
405
|
console.debug(`buildSwingset`);
|
|
406
|
+
const warehousePolicy = {
|
|
407
|
+
maxVatsOnline: swingsetConfig.maxVatsOnline,
|
|
408
|
+
};
|
|
379
409
|
const {
|
|
380
410
|
coreProposals: bootstrapCoreProposals,
|
|
381
411
|
controller,
|
|
@@ -393,6 +423,7 @@ export async function launch({
|
|
|
393
423
|
debugName,
|
|
394
424
|
slogCallbacks,
|
|
395
425
|
slogSender,
|
|
426
|
+
warehousePolicy,
|
|
396
427
|
},
|
|
397
428
|
);
|
|
398
429
|
|
|
@@ -472,6 +503,7 @@ export async function launch({
|
|
|
472
503
|
}
|
|
473
504
|
|
|
474
505
|
async function saveOutsideState(blockHeight) {
|
|
506
|
+
allowExportCallback = false;
|
|
475
507
|
const chainSends = await clearChainSends();
|
|
476
508
|
kvStore.set(getHostKey('height'), `${blockHeight}`);
|
|
477
509
|
kvStore.set(getHostKey('chainSends'), JSON.stringify(chainSends));
|
|
@@ -549,8 +581,15 @@ export async function launch({
|
|
|
549
581
|
let savedBeginHeight = Number(
|
|
550
582
|
kvStore.get(getHostKey('beginHeight')) || savedHeight,
|
|
551
583
|
);
|
|
584
|
+
/**
|
|
585
|
+
* duration of the latest swingset execution in either END_BLOCK or
|
|
586
|
+
* once-per-chain bootstrap (the latter excluding "bridged" core proposals
|
|
587
|
+
* that run outside the bootstrap vat)
|
|
588
|
+
*/
|
|
552
589
|
let runTime = 0;
|
|
590
|
+
/** duration of the latest saveChainState(), which commits mailbox data to chain storage */
|
|
553
591
|
let chainTime;
|
|
592
|
+
/** duration of the latest saveOutsideState(), which commits to swing-store host storage */
|
|
554
593
|
let saveTime = 0;
|
|
555
594
|
let endBlockFinish = 0;
|
|
556
595
|
let blockParams;
|
|
@@ -705,33 +744,16 @@ export async function launch({
|
|
|
705
744
|
|
|
706
745
|
/**
|
|
707
746
|
* @template T
|
|
708
|
-
* @param {string}
|
|
747
|
+
* @param {string} label
|
|
709
748
|
* @param {() => Promise<T>} fn
|
|
749
|
+
* @param {() => void} onSettled
|
|
710
750
|
*/
|
|
711
|
-
|
|
712
|
-
const start = Date.now();
|
|
713
|
-
const finish = res => {
|
|
714
|
-
// blockManagerConsole.error(
|
|
715
|
-
// 'Action',
|
|
716
|
-
// action.type,
|
|
717
|
-
// action.blockHeight,
|
|
718
|
-
// 'is done!',
|
|
719
|
-
// );
|
|
720
|
-
runTime += Date.now() - start;
|
|
721
|
-
return res;
|
|
722
|
-
};
|
|
723
|
-
|
|
751
|
+
function withErrorLogging(label, fn, onSettled) {
|
|
724
752
|
const p = fn();
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
// None of these must fail, and if they do, log them verbosely before
|
|
729
|
-
// returning to the chain.
|
|
730
|
-
blockManagerConsole.error(type, 'error:', e);
|
|
731
|
-
finish();
|
|
753
|
+
void E.when(p, onSettled, err => {
|
|
754
|
+
blockManagerConsole.error(label, 'error:', err);
|
|
755
|
+
onSettled();
|
|
732
756
|
});
|
|
733
|
-
// Return the original promise so that the caller gets the original
|
|
734
|
-
// resolution or rejection.
|
|
735
757
|
return p;
|
|
736
758
|
}
|
|
737
759
|
|
|
@@ -802,8 +824,13 @@ export async function launch({
|
|
|
802
824
|
// Start a block transaction, but without changing state
|
|
803
825
|
// for the upcoming begin block check
|
|
804
826
|
saveBeginHeight(savedBeginHeight);
|
|
805
|
-
|
|
806
|
-
|
|
827
|
+
const start = Date.now();
|
|
828
|
+
await withErrorLogging(
|
|
829
|
+
action.type,
|
|
830
|
+
() => bootstrapBlock(blockHeight, blockTime, bootstrapBlockParams),
|
|
831
|
+
() => {
|
|
832
|
+
runTime += Date.now() - start;
|
|
833
|
+
},
|
|
807
834
|
);
|
|
808
835
|
} finally {
|
|
809
836
|
controller.writeSlogObject({
|
|
@@ -891,6 +918,7 @@ export async function launch({
|
|
|
891
918
|
// );
|
|
892
919
|
switch (action.type) {
|
|
893
920
|
case ActionType.AG_COSMOS_INIT: {
|
|
921
|
+
allowExportCallback = true; // cleared by saveOutsideState in COMMIT_BLOCK
|
|
894
922
|
const { blockHeight, isBootstrap, upgradeDetails } = action;
|
|
895
923
|
|
|
896
924
|
if (!blockNeedsExecution(blockHeight)) {
|
|
@@ -907,17 +935,16 @@ export async function launch({
|
|
|
907
935
|
await doBootstrap(action);
|
|
908
936
|
}
|
|
909
937
|
|
|
910
|
-
//
|
|
911
|
-
//
|
|
938
|
+
// Concatenate together any pending core proposals from chain bootstrap
|
|
939
|
+
// with any from this inbound init action, then execute them all.
|
|
912
940
|
const coreProposals = mergeCoreProposals(
|
|
913
941
|
bootstrapCoreProposals,
|
|
914
942
|
softwareUpgradeCoreProposals,
|
|
915
943
|
upgradeInfoCoreProposals,
|
|
916
944
|
);
|
|
917
|
-
|
|
918
945
|
if (coreProposals.steps.length) {
|
|
919
|
-
|
|
920
|
-
|
|
946
|
+
isBootstrap ||
|
|
947
|
+
upgradeDetails ||
|
|
921
948
|
Fail`Unexpected core proposals outside of consensus start`;
|
|
922
949
|
await doCoreProposals(action, coreProposals);
|
|
923
950
|
}
|
|
@@ -944,9 +971,9 @@ export async function launch({
|
|
|
944
971
|
});
|
|
945
972
|
|
|
946
973
|
// Save the kernel's computed state just before the chain commits.
|
|
947
|
-
const
|
|
974
|
+
const start = Date.now();
|
|
948
975
|
await saveOutsideState(savedHeight);
|
|
949
|
-
saveTime = Date.now() -
|
|
976
|
+
saveTime = Date.now() - start;
|
|
950
977
|
|
|
951
978
|
blockParams = undefined;
|
|
952
979
|
|
|
@@ -977,6 +1004,7 @@ export async function launch({
|
|
|
977
1004
|
}
|
|
978
1005
|
|
|
979
1006
|
case ActionType.BEGIN_BLOCK: {
|
|
1007
|
+
allowExportCallback = true; // cleared by saveOutsideState in COMMIT_BLOCK
|
|
980
1008
|
const { blockHeight, blockTime, params } = action;
|
|
981
1009
|
blockParams = parseParams(params);
|
|
982
1010
|
verboseBlocks &&
|
|
@@ -1043,14 +1071,19 @@ export async function launch({
|
|
|
1043
1071
|
|
|
1044
1072
|
provideInstallationPublisher();
|
|
1045
1073
|
|
|
1046
|
-
|
|
1047
|
-
|
|
1074
|
+
const start = Date.now();
|
|
1075
|
+
await withErrorLogging(
|
|
1076
|
+
action.type,
|
|
1077
|
+
() => endBlock(blockHeight, blockTime, blockParams),
|
|
1078
|
+
() => {
|
|
1079
|
+
runTime += Date.now() - start;
|
|
1080
|
+
},
|
|
1048
1081
|
);
|
|
1049
1082
|
|
|
1050
1083
|
// We write out our on-chain state as a number of chainSends.
|
|
1051
|
-
const
|
|
1084
|
+
const start2 = Date.now();
|
|
1052
1085
|
await saveChainState();
|
|
1053
|
-
chainTime = Date.now() -
|
|
1086
|
+
chainTime = Date.now() - start2;
|
|
1054
1087
|
|
|
1055
1088
|
// Advance our saved state variables.
|
|
1056
1089
|
savedHeight = blockHeight;
|
package/src/params.js
CHANGED
package/src/sim-chain.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* global process setTimeout clearTimeout */
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import fs from 'fs';
|
|
4
|
+
import { Fail } from '@endo/errors';
|
|
4
5
|
import {
|
|
5
6
|
importMailbox,
|
|
6
7
|
exportMailbox,
|
|
@@ -11,7 +12,6 @@ import anylogger from 'anylogger';
|
|
|
11
12
|
import { makeSlogSender } from '@agoric/telemetry';
|
|
12
13
|
|
|
13
14
|
import { resolve as importMetaResolve } from 'import-meta-resolve';
|
|
14
|
-
import { Fail } from '@agoric/assert';
|
|
15
15
|
import { makeWithQueue } from '@agoric/internal/src/queue.js';
|
|
16
16
|
import { makeBatchedDeliver } from '@agoric/internal/src/batched-deliver.js';
|
|
17
17
|
import stringify from './helpers/json-stable-stringify.js';
|