@acala-network/chopsticks 0.7.2 → 0.8.0-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/lib/cli-options.d.ts +40 -0
- package/lib/cli-options.js +43 -0
- package/lib/cli.d.ts +1 -2
- package/lib/cli.js +20 -183
- package/lib/context.d.ts +5 -0
- package/lib/context.js +37 -0
- package/lib/index.d.ts +2 -7
- package/lib/index.js +4 -15
- package/lib/logger.d.ts +1 -7
- package/lib/logger.js +3 -38
- package/lib/plugins/decode-key/index.d.ts +2 -0
- package/lib/plugins/decode-key/index.js +27 -0
- package/lib/plugins/dry-run/cli.d.ts +2 -0
- package/lib/plugins/dry-run/cli.js +46 -0
- package/lib/plugins/dry-run/dry-run-extrinsic.d.ts +2 -0
- package/lib/{dry-run.js → plugins/dry-run/dry-run-extrinsic.js} +8 -8
- package/lib/{dry-run-preimage.d.ts → plugins/dry-run/dry-run-preimage.d.ts} +1 -1
- package/lib/{dry-run-preimage.js → plugins/dry-run/dry-run-preimage.js} +10 -12
- package/lib/plugins/dry-run/index.d.ts +2 -0
- package/lib/plugins/dry-run/index.js +18 -0
- package/lib/plugins/dry-run/rpc.d.ts +3 -0
- package/lib/{rpc/dev/dry-run.js → plugins/dry-run/rpc.js} +10 -7
- package/lib/plugins/index.d.ts +4 -0
- package/lib/plugins/index.js +52 -0
- package/lib/plugins/new-block/index.d.ts +2 -0
- package/lib/plugins/new-block/index.js +28 -0
- package/lib/plugins/run-block/index.d.ts +2 -0
- package/lib/plugins/run-block/index.js +67 -0
- package/lib/plugins/set-block-build-mode/index.d.ts +2 -0
- package/lib/plugins/set-block-build-mode/index.js +14 -0
- package/lib/plugins/set-head/index.d.ts +2 -0
- package/lib/plugins/set-head/index.js +20 -0
- package/lib/plugins/set-storage/index.d.ts +2 -0
- package/lib/plugins/set-storage/index.js +18 -0
- package/lib/plugins/time-travel/index.d.ts +2 -0
- package/lib/plugins/time-travel/index.js +13 -0
- package/lib/plugins/try-runtime/index.d.ts +2 -0
- package/lib/plugins/try-runtime/index.js +58 -0
- package/lib/rpc/index.d.ts +1 -1
- package/lib/rpc/index.js +11 -4
- package/lib/rpc/shared.d.ts +1 -1
- package/lib/rpc/shared.js +1 -1
- package/lib/rpc/substrate/author.js +3 -3
- package/lib/schema/index.d.ts +9 -66
- package/lib/schema/index.js +41 -14
- package/lib/server.js +2 -1
- package/lib/setup-with-server.d.ts +1 -3
- package/lib/setup-with-server.js +2 -2
- package/lib/utils/decoder.d.ts +1 -1
- package/lib/utils/generate-html-diff.d.ts +1 -1
- package/lib/utils/override.d.ts +4 -0
- package/lib/utils/{import-storage.js → override.js} +6 -6
- package/package.json +13 -16
- package/lib/api.d.ts +0 -43
- package/lib/api.js +0 -79
- package/lib/blockchain/block-builder.d.ts +0 -10
- package/lib/blockchain/block-builder.js +0 -297
- package/lib/blockchain/block.d.ts +0 -45
- package/lib/blockchain/block.js +0 -194
- package/lib/blockchain/head-state.d.ts +0 -15
- package/lib/blockchain/head-state.js +0 -71
- package/lib/blockchain/index.d.ts +0 -64
- package/lib/blockchain/index.js +0 -243
- package/lib/blockchain/inherent/index.d.ts +0 -19
- package/lib/blockchain/inherent/index.js +0 -36
- package/lib/blockchain/inherent/para-enter.d.ts +0 -7
- package/lib/blockchain/inherent/para-enter.js +0 -33
- package/lib/blockchain/inherent/parachain/babe-randomness.d.ts +0 -7
- package/lib/blockchain/inherent/parachain/babe-randomness.js +0 -15
- package/lib/blockchain/inherent/parachain/nimbus-author-inherent.d.ts +0 -7
- package/lib/blockchain/inherent/parachain/nimbus-author-inherent.js +0 -15
- package/lib/blockchain/inherent/parachain/validation-data.d.ts +0 -19
- package/lib/blockchain/inherent/parachain/validation-data.js +0 -172
- package/lib/blockchain/storage-layer.d.ts +0 -32
- package/lib/blockchain/storage-layer.js +0 -200
- package/lib/blockchain/txpool.d.ts +0 -45
- package/lib/blockchain/txpool.js +0 -184
- package/lib/db/entities.d.ts +0 -5
- package/lib/db/entities.js +0 -33
- package/lib/db/index.d.ts +0 -3
- package/lib/db/index.js +0 -41
- package/lib/dry-run.d.ts +0 -2
- package/lib/executor.d.ts +0 -40
- package/lib/executor.js +0 -131
- package/lib/genesis-provider.d.ts +0 -44
- package/lib/genesis-provider.js +0 -155
- package/lib/offchain.d.ts +0 -10
- package/lib/offchain.js +0 -37
- package/lib/rpc/dev/dry-run.d.ts +0 -2
- package/lib/rpc/dev/index.d.ts +0 -3
- package/lib/rpc/dev/index.js +0 -75
- package/lib/run-block.d.ts +0 -2
- package/lib/run-block.js +0 -51
- package/lib/setup.d.ts +0 -11
- package/lib/setup.js +0 -86
- package/lib/try-runtime.d.ts +0 -2
- package/lib/try-runtime.js +0 -36
- package/lib/utils/import-storage.d.ts +0 -5
- package/lib/utils/index.d.ts +0 -16
- package/lib/utils/index.js +0 -59
- package/lib/utils/key-cache.d.ts +0 -10
- package/lib/utils/key-cache.js +0 -66
- package/lib/utils/proof.d.ts +0 -15
- package/lib/utils/proof.js +0 -41
- package/lib/utils/set-storage.d.ts +0 -7
- package/lib/utils/set-storage.js +0 -59
- package/lib/utils/time-travel.d.ts +0 -5
- package/lib/utils/time-travel.js +0 -65
- package/lib/xcm/downward.d.ts +0 -2
- package/lib/xcm/downward.js +0 -29
- package/lib/xcm/horizontal.d.ts +0 -2
- package/lib/xcm/horizontal.js +0 -29
- package/lib/xcm/index.d.ts +0 -9
- package/lib/xcm/index.js +0 -25
- package/lib/xcm/upward.d.ts +0 -2
- package/lib/xcm/upward.js +0 -21
package/lib/schema/index.js
CHANGED
|
@@ -1,32 +1,59 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const
|
|
6
|
+
exports.fetchConfig = exports.configSchema = void 0;
|
|
7
|
+
const chopsticks_core_1 = require("@acala-network/chopsticks-core");
|
|
8
|
+
const node_path_1 = require("node:path");
|
|
9
|
+
const node_fs_1 = require("node:fs");
|
|
5
10
|
const zod_1 = require("zod");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
properties: zod_1.z.object({
|
|
10
|
-
ss58Format: zod_1.z.number().optional(),
|
|
11
|
-
tokenDecimals: zod_1.z.union([zod_1.z.number(), zod_1.z.array(zod_1.z.number())]).optional(),
|
|
12
|
-
tokenSymbol: zod_1.z.union([zod_1.z.string(), zod_1.z.array(zod_1.z.string())]).optional(),
|
|
13
|
-
}),
|
|
14
|
-
genesis: zod_1.z.object({ raw: zod_1.z.object({ top: zod_1.z.record(zod_1.z.string()) }) }),
|
|
15
|
-
});
|
|
11
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
12
|
+
const axios_1 = __importDefault(require("axios"));
|
|
13
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
16
14
|
exports.configSchema = zod_1.z
|
|
17
15
|
.object({
|
|
18
16
|
port: zod_1.z.number().optional(),
|
|
19
17
|
endpoint: zod_1.z.string().optional(),
|
|
20
18
|
block: zod_1.z.union([zod_1.z.string().length(66).startsWith('0x'), zod_1.z.number(), zod_1.z.null()]).optional(),
|
|
21
|
-
'build-block-mode': zod_1.z.nativeEnum(
|
|
19
|
+
'build-block-mode': zod_1.z.nativeEnum(chopsticks_core_1.BuildBlockMode).optional(),
|
|
22
20
|
'import-storage': zod_1.z.any().optional(),
|
|
23
21
|
'mock-signature-host': zod_1.z.boolean().optional(),
|
|
22
|
+
'max-memory-block-count': zod_1.z.number().optional(),
|
|
24
23
|
db: zod_1.z.string().optional(),
|
|
25
24
|
'wasm-override': zod_1.z.string().optional(),
|
|
26
|
-
genesis: zod_1.z.union([zod_1.z.string(),
|
|
25
|
+
genesis: zod_1.z.union([zod_1.z.string(), chopsticks_core_1.genesisSchema]).optional(),
|
|
27
26
|
timestamp: zod_1.z.number().optional(),
|
|
28
27
|
'registered-types': zod_1.z.any().optional(),
|
|
29
28
|
'runtime-log-level': zod_1.z.number().min(0).max(5).optional(),
|
|
30
29
|
'offchain-worker': zod_1.z.boolean().optional(),
|
|
31
30
|
})
|
|
32
31
|
.strict();
|
|
32
|
+
const CONFIGS_BASE_URL = 'https://raw.githubusercontent.com/AcalaNetwork/chopsticks/master/configs/';
|
|
33
|
+
const fetchConfig = async (path) => {
|
|
34
|
+
let file;
|
|
35
|
+
if ((0, chopsticks_core_1.isUrl)(path)) {
|
|
36
|
+
file = await axios_1.default.get(path).then((x) => x.data);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
try {
|
|
40
|
+
file = (0, node_fs_1.readFileSync)(path, 'utf8');
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if ((0, node_path_1.basename)(path) === path && ['', '.yml', '.yaml', '.json'].includes((0, node_path_1.extname)(path))) {
|
|
44
|
+
if ((0, node_path_1.extname)(path) === '') {
|
|
45
|
+
path += '.yml';
|
|
46
|
+
}
|
|
47
|
+
const url = CONFIGS_BASE_URL + path;
|
|
48
|
+
chopsticks_core_1.defaultLogger.info(`Loading config file ${url}`);
|
|
49
|
+
file = await axios_1.default.get(url).then((x) => x.data);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
throw err;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const config = js_yaml_1.default.load(lodash_1.default.template(file, { variable: 'env' })(process.env));
|
|
57
|
+
return exports.configSchema.parse(config);
|
|
58
|
+
};
|
|
59
|
+
exports.fetchConfig = fetchConfig;
|
package/lib/server.js
CHANGED
|
@@ -25,6 +25,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.createServer = void 0;
|
|
27
27
|
const ws_1 = __importStar(require("ws"));
|
|
28
|
+
const shared_1 = require("./rpc/shared");
|
|
28
29
|
const logger_1 = require("./logger");
|
|
29
30
|
const logger = logger_1.defaultLogger.child({ name: 'ws' });
|
|
30
31
|
const parseRequest = (request) => {
|
|
@@ -145,7 +146,7 @@ const createServer = async (handler, port) => {
|
|
|
145
146
|
send({
|
|
146
147
|
id: req.id,
|
|
147
148
|
jsonrpc: '2.0',
|
|
148
|
-
error: e,
|
|
149
|
+
error: e instanceof shared_1.ResponseError ? e : { code: -32603, message: `Internal ${e}` },
|
|
149
150
|
});
|
|
150
151
|
}
|
|
151
152
|
});
|
|
@@ -2,7 +2,5 @@ import { Config } from './schema';
|
|
|
2
2
|
export declare const setupWithServer: (argv: Config) => Promise<{
|
|
3
3
|
close: () => Promise<void>;
|
|
4
4
|
listenPort: number;
|
|
5
|
-
chain: import("
|
|
6
|
-
api: import("./api").Api;
|
|
7
|
-
ws: import("@polkadot/rpc-provider/types").ProviderInterface;
|
|
5
|
+
chain: import("@acala-network/chopsticks-core").Blockchain;
|
|
8
6
|
}>;
|
package/lib/setup-with-server.js
CHANGED
|
@@ -4,9 +4,9 @@ exports.setupWithServer = void 0;
|
|
|
4
4
|
const server_1 = require("./server");
|
|
5
5
|
const rpc_1 = require("./rpc");
|
|
6
6
|
const shared_1 = require("./rpc/shared");
|
|
7
|
-
const
|
|
7
|
+
const context_1 = require("./context");
|
|
8
8
|
const setupWithServer = async (argv) => {
|
|
9
|
-
const context = await (0,
|
|
9
|
+
const context = await (0, context_1.setupContext)(argv);
|
|
10
10
|
const port = argv.port ?? 8000;
|
|
11
11
|
if (argv.genesis) {
|
|
12
12
|
// mine 1st block when starting from genesis to set some mock validation data
|
package/lib/utils/decoder.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '@polkadot/types-codec';
|
|
2
|
-
import { Block } from '
|
|
2
|
+
import { Block } from '@acala-network/chopsticks-core';
|
|
3
3
|
import { DecoratedMeta } from '@polkadot/types/metadata/decorate/types';
|
|
4
4
|
import { HexString } from '@polkadot/util/types';
|
|
5
5
|
import { StorageEntry } from '@polkadot/types/primitive/types';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Block } from '
|
|
1
|
+
import { Block } from '@acala-network/chopsticks-core';
|
|
2
2
|
import { HexString } from '@polkadot/util/types';
|
|
3
3
|
export declare const generateHtmlDiff: (block: Block, diff: [HexString, HexString | null][]) => Promise<string>;
|
|
4
4
|
export declare const generateHtmlDiffPreviewFile: (block: Block, diff: [HexString, HexString | null][], filename: string) => Promise<string>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Blockchain, StorageValues } from '@acala-network/chopsticks-core';
|
|
2
|
+
import { HexString } from '@polkadot/util/types';
|
|
3
|
+
export declare const overrideStorage: (chain: Blockchain, storage?: string | StorageValues, at?: HexString) => Promise<void>;
|
|
4
|
+
export declare const overrideWasm: (chain: Blockchain, wasmPath?: string, at?: HexString) => Promise<void>;
|
|
@@ -3,12 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.overrideWasm = exports.
|
|
6
|
+
exports.overrideWasm = exports.overrideStorage = void 0;
|
|
7
|
+
const chopsticks_core_1 = require("@acala-network/chopsticks-core");
|
|
7
8
|
const node_fs_1 = require("node:fs");
|
|
8
9
|
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
9
|
-
const set_storage_1 = require("./set-storage");
|
|
10
10
|
const logger_1 = require("../logger");
|
|
11
|
-
const
|
|
11
|
+
const overrideStorage = async (chain, storage, at) => {
|
|
12
12
|
if (storage == null) {
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
@@ -21,10 +21,10 @@ const importStorage = async (chain, storage, at) => {
|
|
|
21
21
|
else {
|
|
22
22
|
storageValue = storage;
|
|
23
23
|
}
|
|
24
|
-
const blockHash = await (0,
|
|
25
|
-
logger_1.defaultLogger.trace({ blockHash, storage }, '
|
|
24
|
+
const blockHash = await (0, chopsticks_core_1.setStorage)(chain, storageValue, at);
|
|
25
|
+
logger_1.defaultLogger.trace({ blockHash, storage }, 'OverrideStorage');
|
|
26
26
|
};
|
|
27
|
-
exports.
|
|
27
|
+
exports.overrideStorage = overrideStorage;
|
|
28
28
|
const overrideWasm = async (chain, wasmPath, at) => {
|
|
29
29
|
if (wasmPath == null) {
|
|
30
30
|
return;
|
package/package.json
CHANGED
|
@@ -1,34 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acala-network/chopsticks",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0-0",
|
|
4
4
|
"author": "Bryan Chen <xlchen1291@gmail.com>",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"bin": "./chopsticks.js",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"clean": "rm -rf lib tsconfig.tsbuildinfo",
|
|
9
9
|
"build": "tsc -p ./tsconfig.json",
|
|
10
|
-
"script:start": "cd ../..; ts-node --transpile-only packages/chopsticks/src/cli.ts",
|
|
11
|
-
"script:run": "cd ../..; LOG_LEVEL=trace ts-node-dev --transpile-only --inspect --notify=false packages/chopsticks/src/cli.ts -- --config=configs/dev.yml",
|
|
12
|
-
"dev:karura": "cd ../..; ts-node-dev --transpile-only --inspect --notify=false packages/chopsticks/src/cli.ts -- --config=configs/karura.yml",
|
|
13
|
-
"dev:acala": "cd ../..; ts-node-dev --transpile-only --inspect --notify=false packages/chopsticks/src/cli.ts -- --config=configs/acala.yml",
|
|
14
|
-
"dev:polkadot": "cd ../..; ts-node-dev --transpile-only --inspect --notify=false packages/chopsticks/src/cli.ts -- --config=configs/polkadot.yml",
|
|
15
|
-
"dev:moonriver": "cd ../..; ts-node-dev --transpile-only --inspect --notify=false packages/chopsticks/src/cli.ts -- --config=configs/moonriver.yml",
|
|
16
|
-
"dev:moonbeam": "cd ../..; ts-node-dev --transpile-only --inspect --notify=false packages/chopsticks/src/cli.ts -- --config=configs/moonbeam.yml"
|
|
10
|
+
"script:start": "cd ../..; ts-node --transpile-only -r tsconfig-paths/register packages/chopsticks/src/cli.ts",
|
|
11
|
+
"script:run": "cd ../..; LOG_LEVEL=trace ts-node-dev --transpile-only -r tsconfig-paths/register --inspect --notify=false packages/chopsticks/src/cli.ts -- --config=configs/dev.yml",
|
|
12
|
+
"dev:karura": "cd ../..; ts-node-dev --transpile-only --inspect -r tsconfig-paths/register --notify=false packages/chopsticks/src/cli.ts -- --config=configs/karura.yml",
|
|
13
|
+
"dev:acala": "cd ../..; ts-node-dev --transpile-only --inspect -r tsconfig-paths/register --notify=false packages/chopsticks/src/cli.ts -- --config=configs/acala.yml",
|
|
14
|
+
"dev:polkadot": "cd ../..; ts-node-dev --transpile-only --inspect -r tsconfig-paths/register --notify=false packages/chopsticks/src/cli.ts -- --config=configs/polkadot.yml",
|
|
15
|
+
"dev:moonriver": "cd ../..; ts-node-dev --transpile-only --inspect -r tsconfig-paths/register --notify=false packages/chopsticks/src/cli.ts -- --config=configs/moonriver.yml",
|
|
16
|
+
"dev:moonbeam": "cd ../..; ts-node-dev --transpile-only --inspect -r tsconfig-paths/register --notify=false packages/chopsticks/src/cli.ts -- --config=configs/moonbeam.yml"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@acala-network/chopsticks-
|
|
19
|
+
"@acala-network/chopsticks-core": "0.8.0-0",
|
|
20
20
|
"@pnpm/npm-conf": "^2.2.2",
|
|
21
21
|
"@polkadot/api": "^10.9.1",
|
|
22
22
|
"axios": "^1.4.0",
|
|
23
|
+
"dotenv": "^16.3.1",
|
|
23
24
|
"global-agent": "^3.0.0",
|
|
24
25
|
"js-yaml": "^4.1.0",
|
|
25
26
|
"jsondiffpatch": "^0.4.1",
|
|
26
27
|
"lodash": "^4.17.21",
|
|
27
|
-
"pino": "^8.14.1",
|
|
28
|
-
"pino-pretty": "^10.0.1",
|
|
29
|
-
"reflect-metadata": "^0.1.13",
|
|
30
|
-
"sqlite3": "^5.1.6",
|
|
31
|
-
"typeorm": "^0.3.17",
|
|
32
28
|
"ws": "^8.13.0",
|
|
33
29
|
"yargs": "^17.7.2",
|
|
34
30
|
"zod": "^3.21.4"
|
|
@@ -37,7 +33,7 @@
|
|
|
37
33
|
"@types/global-agent": "^2.1.1",
|
|
38
34
|
"@types/js-yaml": "^4.0.5",
|
|
39
35
|
"@types/lodash": "^4.14.195",
|
|
40
|
-
"@types/node": "^20.4.
|
|
36
|
+
"@types/node": "^20.4.5",
|
|
41
37
|
"@types/ws": "^8.5.5",
|
|
42
38
|
"@types/yargs": "^17.0.24",
|
|
43
39
|
"ts-node": "^10.9.1",
|
|
@@ -61,5 +57,6 @@
|
|
|
61
57
|
"default": "./lib/*.js"
|
|
62
58
|
},
|
|
63
59
|
"./package.json": "./package.json"
|
|
64
|
-
}
|
|
60
|
+
},
|
|
61
|
+
"stableVersion": "0.7.3"
|
|
65
62
|
}
|
package/lib/api.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { ExtDef } from '@polkadot/types/extrinsic/signedExtensions/types';
|
|
2
|
-
import { HexString } from '@polkadot/util/types';
|
|
3
|
-
import { ProviderInterface } from '@polkadot/rpc-provider/types';
|
|
4
|
-
type ChainProperties = {
|
|
5
|
-
ss58Format?: number;
|
|
6
|
-
tokenDecimals?: number[];
|
|
7
|
-
tokenSymbol?: string[];
|
|
8
|
-
};
|
|
9
|
-
type Header = {
|
|
10
|
-
parentHash: HexString;
|
|
11
|
-
number: HexString;
|
|
12
|
-
stateRoot: HexString;
|
|
13
|
-
extrinsicsRoot: HexString;
|
|
14
|
-
digest: {
|
|
15
|
-
logs: HexString[];
|
|
16
|
-
};
|
|
17
|
-
};
|
|
18
|
-
type SignedBlock = {
|
|
19
|
-
block: {
|
|
20
|
-
header: Header;
|
|
21
|
-
extrinsics: HexString[];
|
|
22
|
-
};
|
|
23
|
-
justifications?: HexString[];
|
|
24
|
-
};
|
|
25
|
-
export declare class Api {
|
|
26
|
-
#private;
|
|
27
|
-
readonly signedExtensions: ExtDef;
|
|
28
|
-
constructor(provider: ProviderInterface, signedExtensions?: ExtDef);
|
|
29
|
-
disconnect(): Promise<void>;
|
|
30
|
-
get isReady(): Promise<void> | undefined;
|
|
31
|
-
get chain(): Promise<string>;
|
|
32
|
-
get chainProperties(): Promise<ChainProperties>;
|
|
33
|
-
getSystemName(): Promise<string>;
|
|
34
|
-
getSystemProperties(): Promise<ChainProperties>;
|
|
35
|
-
getSystemChain(): Promise<string>;
|
|
36
|
-
getMetadata(hash?: string): Promise<string>;
|
|
37
|
-
getBlockHash(blockNumber?: number): Promise<`0x${string}`>;
|
|
38
|
-
getHeader(hash?: string): Promise<Header>;
|
|
39
|
-
getBlock(hash?: string): Promise<SignedBlock>;
|
|
40
|
-
getStorage(key: string, hash?: string): Promise<string>;
|
|
41
|
-
getKeysPaged(prefix: string, pageSize: number, startKey: string, hash?: string): Promise<string[]>;
|
|
42
|
-
}
|
|
43
|
-
export {};
|
package/lib/api.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Api = void 0;
|
|
4
|
-
class Api {
|
|
5
|
-
#provider;
|
|
6
|
-
#ready;
|
|
7
|
-
#chain;
|
|
8
|
-
#chainProperties;
|
|
9
|
-
signedExtensions;
|
|
10
|
-
constructor(provider, signedExtensions) {
|
|
11
|
-
this.#provider = provider;
|
|
12
|
-
this.signedExtensions = signedExtensions || {};
|
|
13
|
-
}
|
|
14
|
-
async disconnect() {
|
|
15
|
-
return this.#provider.disconnect();
|
|
16
|
-
}
|
|
17
|
-
get isReady() {
|
|
18
|
-
if (!this.#ready) {
|
|
19
|
-
if (this.#provider['isReady']) {
|
|
20
|
-
this.#ready = this.#provider['isReady'];
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
this.#ready = new Promise((resolve) => {
|
|
24
|
-
this.#provider.on('connected', () => {
|
|
25
|
-
resolve();
|
|
26
|
-
});
|
|
27
|
-
this.#provider.connect();
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return this.#ready;
|
|
32
|
-
}
|
|
33
|
-
get chain() {
|
|
34
|
-
if (!this.#chain) {
|
|
35
|
-
this.#chain = this.getSystemChain();
|
|
36
|
-
}
|
|
37
|
-
return this.#chain;
|
|
38
|
-
}
|
|
39
|
-
get chainProperties() {
|
|
40
|
-
if (!this.#chainProperties) {
|
|
41
|
-
this.#chainProperties = this.getSystemProperties();
|
|
42
|
-
}
|
|
43
|
-
return this.#chainProperties;
|
|
44
|
-
}
|
|
45
|
-
async getSystemName() {
|
|
46
|
-
return this.#provider.send('system_name', []);
|
|
47
|
-
}
|
|
48
|
-
async getSystemProperties() {
|
|
49
|
-
return this.#provider.send('system_properties', []);
|
|
50
|
-
}
|
|
51
|
-
async getSystemChain() {
|
|
52
|
-
return this.#provider.send('system_chain', []);
|
|
53
|
-
}
|
|
54
|
-
async getMetadata(hash) {
|
|
55
|
-
return this.#provider.send('state_getMetadata', hash ? [hash] : []);
|
|
56
|
-
}
|
|
57
|
-
async getBlockHash(blockNumber) {
|
|
58
|
-
return this.#provider.send('chain_getBlockHash', Number.isInteger(blockNumber) ? [blockNumber] : []);
|
|
59
|
-
}
|
|
60
|
-
async getHeader(hash) {
|
|
61
|
-
return this.#provider.send('chain_getHeader', hash ? [hash] : []);
|
|
62
|
-
}
|
|
63
|
-
async getBlock(hash) {
|
|
64
|
-
return this.#provider.send('chain_getBlock', hash ? [hash] : []);
|
|
65
|
-
}
|
|
66
|
-
async getStorage(key, hash) {
|
|
67
|
-
if (hash) {
|
|
68
|
-
return this.#provider.send('state_getStorageAt', [key, hash]);
|
|
69
|
-
}
|
|
70
|
-
return this.#provider.send('state_getStorage', [key]);
|
|
71
|
-
}
|
|
72
|
-
async getKeysPaged(prefix, pageSize, startKey, hash) {
|
|
73
|
-
if (hash) {
|
|
74
|
-
return this.#provider.send('state_getKeysPagedAt', [prefix, pageSize, startKey, hash]);
|
|
75
|
-
}
|
|
76
|
-
return this.#provider.send('state_getKeysPaged', [prefix, pageSize, startKey]);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
exports.Api = Api;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Header, TransactionValidityError } from '@polkadot/types/interfaces';
|
|
2
|
-
import { Block, TaskCallResponse } from './block';
|
|
3
|
-
import { HexString } from '@polkadot/util/types';
|
|
4
|
-
export declare const newHeader: (head: Block) => Promise<Header>;
|
|
5
|
-
export declare const buildBlock: (head: Block, inherents: HexString[], extrinsics: HexString[], ump: Record<number, HexString[]>, onApplyExtrinsicError: (extrinsic: HexString, error: TransactionValidityError) => void) => Promise<[Block, HexString[]]>;
|
|
6
|
-
export declare const dryRunExtrinsic: (head: Block, inherents: HexString[], extrinsic: HexString | {
|
|
7
|
-
call: HexString;
|
|
8
|
-
address: string;
|
|
9
|
-
}) => Promise<TaskCallResponse>;
|
|
10
|
-
export declare const dryRunInherents: (head: Block, inherents: HexString[]) => Promise<[HexString, HexString | null][]>;
|
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.dryRunInherents = exports.dryRunExtrinsic = exports.buildBlock = exports.newHeader = void 0;
|
|
4
|
-
const block_1 = require("./block");
|
|
5
|
-
const storage_layer_1 = require("./storage-layer");
|
|
6
|
-
const util_1 = require("@polkadot/util");
|
|
7
|
-
const utils_1 = require("../utils");
|
|
8
|
-
const logger_1 = require("../logger");
|
|
9
|
-
const time_travel_1 = require("../utils/time-travel");
|
|
10
|
-
const logger = logger_1.defaultLogger.child({ name: 'block-builder' });
|
|
11
|
-
const getConsensus = (header) => {
|
|
12
|
-
if (header.digest.logs.length === 0)
|
|
13
|
-
return;
|
|
14
|
-
const preRuntime = header.digest.logs[0].asPreRuntime;
|
|
15
|
-
const [consensusEngine, slot] = preRuntime;
|
|
16
|
-
return { consensusEngine, slot, rest: header.digest.logs.slice(1) };
|
|
17
|
-
};
|
|
18
|
-
const getNewSlot = (digest, slotNumber) => {
|
|
19
|
-
if (digest.isPrimary) {
|
|
20
|
-
return {
|
|
21
|
-
primary: {
|
|
22
|
-
...digest.asPrimary.toJSON(),
|
|
23
|
-
slotNumber,
|
|
24
|
-
},
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
if (digest.isSecondaryPlain) {
|
|
28
|
-
return {
|
|
29
|
-
secondaryPlain: {
|
|
30
|
-
...digest.asSecondaryPlain.toJSON(),
|
|
31
|
-
slotNumber,
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
if (digest.isSecondaryVRF) {
|
|
36
|
-
return {
|
|
37
|
-
secondaryVRF: {
|
|
38
|
-
...digest.asSecondaryVRF.toJSON(),
|
|
39
|
-
slotNumber,
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
return digest.toJSON();
|
|
44
|
-
};
|
|
45
|
-
const newHeader = async (head) => {
|
|
46
|
-
const meta = await head.meta;
|
|
47
|
-
const parentHeader = await head.header;
|
|
48
|
-
let newLogs = parentHeader.digest.logs;
|
|
49
|
-
const consensus = getConsensus(parentHeader);
|
|
50
|
-
if (consensus?.consensusEngine.isAura) {
|
|
51
|
-
const slot = await (0, time_travel_1.getCurrentSlot)(head.chain);
|
|
52
|
-
const newSlot = (0, util_1.compactAddLength)(meta.registry.createType('Slot', slot + 1).toU8a());
|
|
53
|
-
newLogs = [{ PreRuntime: [consensus.consensusEngine, newSlot] }, ...consensus.rest];
|
|
54
|
-
}
|
|
55
|
-
else if (consensus?.consensusEngine.isBabe) {
|
|
56
|
-
const slot = await (0, time_travel_1.getCurrentSlot)(head.chain);
|
|
57
|
-
const digest = meta.registry.createType('RawBabePreDigest', consensus.slot);
|
|
58
|
-
const newSlot = (0, util_1.compactAddLength)(meta.registry.createType('RawBabePreDigest', getNewSlot(digest, slot + 1)).toU8a());
|
|
59
|
-
newLogs = [{ PreRuntime: [consensus.consensusEngine, newSlot] }, ...consensus.rest];
|
|
60
|
-
}
|
|
61
|
-
else if (consensus?.consensusEngine?.toString() == 'nmbs') {
|
|
62
|
-
const nmbsKey = (0, util_1.stringToHex)('nmbs');
|
|
63
|
-
newLogs = [
|
|
64
|
-
{
|
|
65
|
-
// Using previous block author
|
|
66
|
-
PreRuntime: [
|
|
67
|
-
consensus.consensusEngine,
|
|
68
|
-
parentHeader.digest.logs
|
|
69
|
-
.find((log) => log.isPreRuntime && log.asPreRuntime[0].toHex() == nmbsKey)
|
|
70
|
-
?.asPreRuntime[1].toHex(),
|
|
71
|
-
],
|
|
72
|
-
},
|
|
73
|
-
...consensus.rest,
|
|
74
|
-
];
|
|
75
|
-
if (meta.query.randomness) {
|
|
76
|
-
// TODO: shouldn't modify existing head
|
|
77
|
-
// reset notFirstBlock so randomness will skip validation
|
|
78
|
-
head.pushStorageLayer().set((0, utils_1.compactHex)(meta.query.randomness.notFirstBlock()), "Deleted" /* StorageValueKind.Deleted */);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
const header = meta.registry.createType('Header', {
|
|
82
|
-
parentHash: head.hash,
|
|
83
|
-
number: head.number + 1,
|
|
84
|
-
stateRoot: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
85
|
-
extrinsicsRoot: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
86
|
-
digest: {
|
|
87
|
-
logs: newLogs,
|
|
88
|
-
},
|
|
89
|
-
});
|
|
90
|
-
return header;
|
|
91
|
-
};
|
|
92
|
-
exports.newHeader = newHeader;
|
|
93
|
-
const initNewBlock = async (head, header, inherents, storageLayer) => {
|
|
94
|
-
const blockNumber = header.number.toNumber();
|
|
95
|
-
const hash = `0x${Math.round(Math.random() * 100000000)
|
|
96
|
-
.toString(16)
|
|
97
|
-
.padEnd(64, '0')}`;
|
|
98
|
-
const newBlock = new block_1.Block(head.chain, blockNumber, hash, head, {
|
|
99
|
-
header,
|
|
100
|
-
extrinsics: [],
|
|
101
|
-
storage: storageLayer ?? head.storage,
|
|
102
|
-
});
|
|
103
|
-
{
|
|
104
|
-
// initialize block
|
|
105
|
-
const { storageDiff } = await newBlock.call('Core_initialize_block', [header.toHex()]);
|
|
106
|
-
newBlock.pushStorageLayer().setAll(storageDiff);
|
|
107
|
-
logger.trace((0, logger_1.truncate)(storageDiff), 'Initialize block');
|
|
108
|
-
}
|
|
109
|
-
const layers = [];
|
|
110
|
-
// apply inherents
|
|
111
|
-
for (const extrinsic of inherents) {
|
|
112
|
-
try {
|
|
113
|
-
const { storageDiff } = await newBlock.call('BlockBuilder_apply_extrinsic', [extrinsic]);
|
|
114
|
-
const layer = newBlock.pushStorageLayer();
|
|
115
|
-
layer.setAll(storageDiff);
|
|
116
|
-
layers.push(layer);
|
|
117
|
-
logger.trace((0, logger_1.truncate)(storageDiff), 'Applied inherent');
|
|
118
|
-
}
|
|
119
|
-
catch (e) {
|
|
120
|
-
logger.warn('Failed to apply inherents %o %s', e, e);
|
|
121
|
-
throw new Error('Failed to apply inherents');
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return {
|
|
125
|
-
block: newBlock,
|
|
126
|
-
layers: layers,
|
|
127
|
-
};
|
|
128
|
-
};
|
|
129
|
-
const buildBlock = async (head, inherents, extrinsics, ump, onApplyExtrinsicError) => {
|
|
130
|
-
const registry = await head.registry;
|
|
131
|
-
const header = await (0, exports.newHeader)(head);
|
|
132
|
-
logger.info({
|
|
133
|
-
number: head.number + 1,
|
|
134
|
-
extrinsicsCount: extrinsics.length,
|
|
135
|
-
umpCount: Object.keys(ump).length,
|
|
136
|
-
}, `Try building block #${(head.number + 1).toLocaleString()}`);
|
|
137
|
-
let layer;
|
|
138
|
-
// apply ump via storage override hack
|
|
139
|
-
if (Object.keys(ump).length > 0) {
|
|
140
|
-
const meta = await head.meta;
|
|
141
|
-
layer = new storage_layer_1.StorageLayer(head.storage);
|
|
142
|
-
for (const [paraId, upwardMessages] of Object.entries(ump)) {
|
|
143
|
-
const upwardMessagesU8a = upwardMessages.map((x) => (0, util_1.hexToU8a)(x));
|
|
144
|
-
const messagesCount = upwardMessages.length;
|
|
145
|
-
const messagesSize = upwardMessagesU8a.map((x) => x.length).reduce((s, i) => s + i, 0);
|
|
146
|
-
if (meta.query.ump) {
|
|
147
|
-
const queueSize = meta.registry.createType('(u32, u32)', [messagesCount, messagesSize]);
|
|
148
|
-
const messages = meta.registry.createType('Vec<Bytes>', upwardMessages);
|
|
149
|
-
// TODO: make sure we append instead of replace
|
|
150
|
-
layer.setAll([
|
|
151
|
-
[(0, utils_1.compactHex)(meta.query.ump.relayDispatchQueues(paraId)), messages.toHex()],
|
|
152
|
-
[(0, utils_1.compactHex)(meta.query.ump.relayDispatchQueueSize(paraId)), queueSize.toHex()],
|
|
153
|
-
]);
|
|
154
|
-
}
|
|
155
|
-
else if (meta.query.messageQueue) {
|
|
156
|
-
// TODO: make sure we append instead of replace
|
|
157
|
-
const origin = { ump: { para: paraId } };
|
|
158
|
-
let last = 0;
|
|
159
|
-
let heap = new Uint8Array(0);
|
|
160
|
-
for (const message of upwardMessagesU8a) {
|
|
161
|
-
const payloadLen = message.length;
|
|
162
|
-
const header = meta.registry.createType('(u32, bool)', [payloadLen, false]);
|
|
163
|
-
last = heap.length;
|
|
164
|
-
heap = (0, util_1.u8aConcat)(heap, header.toU8a(), message);
|
|
165
|
-
}
|
|
166
|
-
layer.setAll([
|
|
167
|
-
[
|
|
168
|
-
(0, utils_1.compactHex)(meta.query.messageQueue.bookStateFor(origin)),
|
|
169
|
-
meta.registry
|
|
170
|
-
.createType('PalletMessageQueueBookState', {
|
|
171
|
-
begin: 0,
|
|
172
|
-
end: 1,
|
|
173
|
-
count: 1,
|
|
174
|
-
readyNeighbours: { prev: origin, next: origin },
|
|
175
|
-
messageCount: messagesCount,
|
|
176
|
-
size_: messagesSize,
|
|
177
|
-
})
|
|
178
|
-
.toHex(),
|
|
179
|
-
],
|
|
180
|
-
[
|
|
181
|
-
(0, utils_1.compactHex)(meta.query.messageQueue.serviceHead(origin)),
|
|
182
|
-
meta.registry.createType('PolkadotRuntimeParachainsInclusionAggregateMessageOrigin', origin).toHex(),
|
|
183
|
-
],
|
|
184
|
-
[
|
|
185
|
-
(0, utils_1.compactHex)(meta.query.messageQueue.pages(origin, 0)),
|
|
186
|
-
meta.registry
|
|
187
|
-
.createType('PalletMessageQueuePage', {
|
|
188
|
-
remaining: messagesCount,
|
|
189
|
-
remaining_size: messagesSize,
|
|
190
|
-
first_index: 0,
|
|
191
|
-
first: 0,
|
|
192
|
-
last,
|
|
193
|
-
heap: (0, util_1.compactAddLength)(heap),
|
|
194
|
-
})
|
|
195
|
-
.toHex(),
|
|
196
|
-
],
|
|
197
|
-
]);
|
|
198
|
-
}
|
|
199
|
-
else {
|
|
200
|
-
throw new Error('Unknown ump storage');
|
|
201
|
-
}
|
|
202
|
-
logger.trace({ paraId, upwardMessages: (0, logger_1.truncate)(upwardMessages) }, 'Pushed UMP');
|
|
203
|
-
}
|
|
204
|
-
if (meta.query.ump) {
|
|
205
|
-
const needsDispatch = meta.registry.createType('Vec<u32>', Object.keys(ump));
|
|
206
|
-
layer.set((0, utils_1.compactHex)(meta.query.ump.needsDispatch()), needsDispatch.toHex());
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
const { block: newBlock } = await initNewBlock(head, header, inherents, layer);
|
|
210
|
-
const pendingExtrinsics = [];
|
|
211
|
-
const includedExtrinsic = [];
|
|
212
|
-
// apply extrinsics
|
|
213
|
-
for (const extrinsic of extrinsics) {
|
|
214
|
-
try {
|
|
215
|
-
const { result, storageDiff } = await newBlock.call('BlockBuilder_apply_extrinsic', [extrinsic]);
|
|
216
|
-
const outcome = registry.createType('ApplyExtrinsicResult', result);
|
|
217
|
-
if (outcome.isErr) {
|
|
218
|
-
onApplyExtrinsicError(extrinsic, outcome.asErr);
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
|
-
newBlock.pushStorageLayer().setAll(storageDiff);
|
|
222
|
-
logger.trace((0, logger_1.truncate)(storageDiff), 'Applied extrinsic');
|
|
223
|
-
includedExtrinsic.push(extrinsic);
|
|
224
|
-
}
|
|
225
|
-
catch (e) {
|
|
226
|
-
logger.info('Failed to apply extrinsic %o %s', e, e);
|
|
227
|
-
pendingExtrinsics.push(extrinsic);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
{
|
|
231
|
-
// finalize block
|
|
232
|
-
const { storageDiff } = await newBlock.call('BlockBuilder_finalize_block', []);
|
|
233
|
-
newBlock.pushStorageLayer().setAll(storageDiff);
|
|
234
|
-
logger.trace((0, logger_1.truncate)(storageDiff), 'Finalize block');
|
|
235
|
-
}
|
|
236
|
-
const blockData = registry.createType('Block', {
|
|
237
|
-
header,
|
|
238
|
-
extrinsics: includedExtrinsic,
|
|
239
|
-
});
|
|
240
|
-
const storageDiff = await newBlock.storageDiff();
|
|
241
|
-
logger.trace(Object.entries(storageDiff).map(([key, value]) => [key, (0, logger_1.truncate)(value)]), 'Final block');
|
|
242
|
-
const finalBlock = new block_1.Block(head.chain, newBlock.number, blockData.hash.toHex(), head, {
|
|
243
|
-
header,
|
|
244
|
-
extrinsics: [...inherents, ...includedExtrinsic],
|
|
245
|
-
storage: head.storage,
|
|
246
|
-
storageDiff,
|
|
247
|
-
});
|
|
248
|
-
logger.info({
|
|
249
|
-
number: newBlock.number,
|
|
250
|
-
hash: finalBlock.hash,
|
|
251
|
-
extrinsics: (0, logger_1.truncate)(includedExtrinsic),
|
|
252
|
-
pendingExtrinsicsCount: pendingExtrinsics.length,
|
|
253
|
-
ump: (0, logger_1.truncate)(ump),
|
|
254
|
-
}, 'Block built');
|
|
255
|
-
return [finalBlock, pendingExtrinsics];
|
|
256
|
-
};
|
|
257
|
-
exports.buildBlock = buildBlock;
|
|
258
|
-
const dryRunExtrinsic = async (head, inherents, extrinsic) => {
|
|
259
|
-
const registry = await head.registry;
|
|
260
|
-
const header = await (0, exports.newHeader)(head);
|
|
261
|
-
const { block: newBlock } = await initNewBlock(head, header, inherents);
|
|
262
|
-
if (typeof extrinsic !== 'string') {
|
|
263
|
-
if (!head.chain.mockSignatureHost) {
|
|
264
|
-
throw new Error('Cannot fake signature because mock signature host is not enabled. Start chain with `mockSignatureHost: true`');
|
|
265
|
-
}
|
|
266
|
-
const meta = await head.meta;
|
|
267
|
-
const call = registry.createType('Call', (0, util_1.hexToU8a)(extrinsic.call));
|
|
268
|
-
const generic = registry.createType('GenericExtrinsic', call);
|
|
269
|
-
const accountRaw = await head.get((0, utils_1.compactHex)(meta.query.system.account(extrinsic.address)));
|
|
270
|
-
const account = registry.createType('AccountInfo', (0, util_1.hexToU8a)(accountRaw));
|
|
271
|
-
generic.signFake(extrinsic.address, {
|
|
272
|
-
blockHash: head.hash,
|
|
273
|
-
genesisHash: head.hash,
|
|
274
|
-
runtimeVersion: await head.runtimeVersion,
|
|
275
|
-
nonce: account.nonce,
|
|
276
|
-
});
|
|
277
|
-
const mockSignature = new Uint8Array(64);
|
|
278
|
-
mockSignature.fill(0xcd);
|
|
279
|
-
mockSignature.set([0xde, 0xad, 0xbe, 0xef]);
|
|
280
|
-
generic.signature.set(mockSignature);
|
|
281
|
-
logger_1.defaultLogger.info({ call: call.toHuman() }, 'dry_run_call');
|
|
282
|
-
return newBlock.call('BlockBuilder_apply_extrinsic', [generic.toHex()]);
|
|
283
|
-
}
|
|
284
|
-
logger_1.defaultLogger.info({ call: registry.createType('GenericExtrinsic', (0, util_1.hexToU8a)(extrinsic)).toHuman() }, 'dry_run_extrinsic');
|
|
285
|
-
return newBlock.call('BlockBuilder_apply_extrinsic', [extrinsic]);
|
|
286
|
-
};
|
|
287
|
-
exports.dryRunExtrinsic = dryRunExtrinsic;
|
|
288
|
-
const dryRunInherents = async (head, inherents) => {
|
|
289
|
-
const header = await (0, exports.newHeader)(head);
|
|
290
|
-
const { layers } = await initNewBlock(head, header, inherents);
|
|
291
|
-
const stoarge = {};
|
|
292
|
-
for (const layer of layers) {
|
|
293
|
-
await layer.mergeInto(stoarge);
|
|
294
|
-
}
|
|
295
|
-
return Object.entries(stoarge);
|
|
296
|
-
};
|
|
297
|
-
exports.dryRunInherents = dryRunInherents;
|