@acala-network/chopsticks-core 0.8.3 → 0.8.5-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.
Files changed (40) hide show
  1. package/lib/blockchain/block-builder.js +0 -3
  2. package/lib/blockchain/block.d.ts +1 -1
  3. package/lib/blockchain/block.js +4 -4
  4. package/lib/blockchain/head-state.d.ts +1 -1
  5. package/lib/blockchain/head-state.js +2 -2
  6. package/lib/blockchain/index.d.ts +2 -2
  7. package/lib/blockchain/index.js +5 -2
  8. package/lib/blockchain/inherent/parachain/validation-data.js +5 -5
  9. package/lib/chopsticks-provider.d.ts +31 -0
  10. package/lib/chopsticks-provider.js +169 -0
  11. package/lib/genesis-provider.d.ts +1 -1
  12. package/lib/genesis-provider.js +3 -3
  13. package/lib/index.d.ts +3 -1
  14. package/lib/index.js +3 -1
  15. package/lib/rpc/index.d.ts +5 -0
  16. package/lib/rpc/index.js +26 -0
  17. package/lib/rpc/shared.d.ts +27 -0
  18. package/lib/rpc/shared.js +19 -0
  19. package/lib/rpc/substrate/author.d.ts +28 -0
  20. package/lib/rpc/substrate/author.js +101 -0
  21. package/lib/rpc/substrate/chain.d.ts +45 -0
  22. package/lib/rpc/substrate/chain.js +103 -0
  23. package/lib/rpc/substrate/index.d.ts +66 -0
  24. package/lib/rpc/substrate/index.js +38 -0
  25. package/lib/rpc/substrate/payment.d.ts +16 -0
  26. package/lib/rpc/substrate/payment.js +54 -0
  27. package/lib/rpc/substrate/state.d.ts +97 -0
  28. package/lib/rpc/substrate/state.js +188 -0
  29. package/lib/rpc/substrate/system.d.ts +28 -0
  30. package/lib/rpc/substrate/system.js +71 -0
  31. package/lib/utils/time-travel.js +2 -2
  32. package/lib/wasm-executor/browser-wasm-executor.mjs +37 -0
  33. package/lib/wasm-executor/browser-worker.d.ts +5 -0
  34. package/lib/wasm-executor/browser-worker.js +28 -0
  35. package/lib/{executor.d.ts → wasm-executor/index.d.ts} +19 -2
  36. package/lib/{executor.js → wasm-executor/index.js} +61 -18
  37. package/lib/wasm-executor/node-wasm-executor.mjs +34 -0
  38. package/lib/wasm-executor/node-worker.d.ts +5 -0
  39. package/lib/wasm-executor/node-worker.js +31 -0
  40. package/package.json +10 -4
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.childstate_getKeysPaged = exports.childstate_getStorage = exports.state_unsubscribeStorage = exports.state_subscribeStorage = exports.state_unsubscribeRuntimeVersion = exports.state_subscribeRuntimeVersion = exports.state_call = exports.state_queryStorageAt = exports.state_getKeysPaged = exports.state_getStorage = exports.state_getMetadata = exports.state_getRuntimeVersion = void 0;
13
+ const shared_1 = require("../shared");
14
+ const logger_1 = require("../../logger");
15
+ const utils_1 = require("../../utils");
16
+ const logger = logger_1.defaultLogger.child({ name: 'rpc-state' });
17
+ /**
18
+ * @param context
19
+ * @param params - [`blockhash`]
20
+ *
21
+ * @return runtime version
22
+ */
23
+ const state_getRuntimeVersion = (context, [hash]) => __awaiter(void 0, void 0, void 0, function* () {
24
+ const block = yield context.chain.getBlock(hash);
25
+ return (block === null || block === void 0 ? void 0 : block.runtimeVersion) || null;
26
+ });
27
+ exports.state_getRuntimeVersion = state_getRuntimeVersion;
28
+ /**
29
+ * @param context
30
+ * @param params - [`blockhash`]
31
+ *
32
+ * @return metadata
33
+ */
34
+ const state_getMetadata = (context, [hash]) => __awaiter(void 0, void 0, void 0, function* () {
35
+ const block = yield context.chain.getBlock(hash);
36
+ return (block === null || block === void 0 ? void 0 : block.metadata) || null;
37
+ });
38
+ exports.state_getMetadata = state_getMetadata;
39
+ /**
40
+ * @param context
41
+ * @param params - [`key`, `blockhash`]
42
+ *
43
+ * @return storage value
44
+ */
45
+ const state_getStorage = (context, [key, hash]) => __awaiter(void 0, void 0, void 0, function* () {
46
+ const block = yield context.chain.getBlock(hash);
47
+ const value = (yield (block === null || block === void 0 ? void 0 : block.get(key))) || null;
48
+ return value || null;
49
+ });
50
+ exports.state_getStorage = state_getStorage;
51
+ /**
52
+ * @param context
53
+ * @param params - [`prefix`, `pageSize`, `startKey`, `blockhash`]
54
+ *
55
+ * @return paged keys
56
+ */
57
+ const state_getKeysPaged = (context, [prefix, pageSize, startKey, hash]) => __awaiter(void 0, void 0, void 0, function* () {
58
+ const block = yield context.chain.getBlock(hash);
59
+ return block === null || block === void 0 ? void 0 : block.getKeysPaged({ prefix, pageSize, startKey });
60
+ });
61
+ exports.state_getKeysPaged = state_getKeysPaged;
62
+ /**
63
+ * @param context
64
+ * @param params - [`keys`, `blockhash`]
65
+ *
66
+ * @return storage values
67
+ */
68
+ const state_queryStorageAt = (context, [keys, hash]) => __awaiter(void 0, void 0, void 0, function* () {
69
+ const block = yield context.chain.getBlock(hash);
70
+ if (!block) {
71
+ return [];
72
+ }
73
+ const values = yield Promise.all(keys.map((key) => __awaiter(void 0, void 0, void 0, function* () { return [key, yield block.get(key).then((val) => val || null)]; })));
74
+ return [
75
+ {
76
+ block: block.hash,
77
+ changes: values,
78
+ },
79
+ ];
80
+ });
81
+ exports.state_queryStorageAt = state_queryStorageAt;
82
+ /**
83
+ * @param context
84
+ * @param params - [`method`, `data`, `blockhash`]
85
+ *
86
+ * @return result in hash
87
+ */
88
+ const state_call = (context, [method, data, hash]) => __awaiter(void 0, void 0, void 0, function* () {
89
+ const block = yield context.chain.getBlock(hash);
90
+ if (!block) {
91
+ throw new shared_1.ResponseError(1, `Block ${hash} not found`);
92
+ }
93
+ const resp = yield block.call(method, [data]);
94
+ return resp.result;
95
+ });
96
+ exports.state_call = state_call;
97
+ /**
98
+ * @return subscription id
99
+ */
100
+ const state_subscribeRuntimeVersion = (context, _params, { subscribe }) => __awaiter(void 0, void 0, void 0, function* () {
101
+ let update = (_block) => { };
102
+ const id = yield context.chain.headState.subscrubeRuntimeVersion((block) => update(block));
103
+ const callback = subscribe('state_runtimeVersion', id);
104
+ update = (block) => __awaiter(void 0, void 0, void 0, function* () { return callback(yield block.runtimeVersion); });
105
+ setTimeout(() => {
106
+ context.chain.head.runtimeVersion.then(callback);
107
+ }, 50);
108
+ return id;
109
+ });
110
+ exports.state_subscribeRuntimeVersion = state_subscribeRuntimeVersion;
111
+ /**
112
+ * @param context
113
+ * @param params - [`subid`]
114
+ * @param subscriptionManager
115
+ */
116
+ const state_unsubscribeRuntimeVersion = (_context, [subid], { unsubscribe }) => __awaiter(void 0, void 0, void 0, function* () {
117
+ unsubscribe(subid);
118
+ });
119
+ exports.state_unsubscribeRuntimeVersion = state_unsubscribeRuntimeVersion;
120
+ /**
121
+ * @param context
122
+ * @param params - [`keys`]
123
+ * @param subscriptionManager
124
+ *
125
+ * @return subscription id
126
+ */
127
+ const state_subscribeStorage = (context, [keys], { subscribe }) => __awaiter(void 0, void 0, void 0, function* () {
128
+ let update = (_block, _pairs) => { };
129
+ const id = yield context.chain.headState.subscribeStorage(keys, (block, pairs) => update(block, pairs));
130
+ const callback = subscribe('state_storage', id, () => context.chain.headState.unsubscribeStorage(id));
131
+ update = (block, pairs) => __awaiter(void 0, void 0, void 0, function* () {
132
+ logger.trace({ hash: block.hash }, 'state_subscribeStorage');
133
+ callback({
134
+ block: block.hash,
135
+ changes: pairs,
136
+ });
137
+ });
138
+ (() => __awaiter(void 0, void 0, void 0, function* () {
139
+ const pairs = yield Promise.all(keys.map((key) => __awaiter(void 0, void 0, void 0, function* () {
140
+ const val = yield context.chain.head.get(key);
141
+ return [key, val || null];
142
+ })));
143
+ callback({
144
+ block: context.chain.head.hash,
145
+ changes: pairs,
146
+ });
147
+ }))();
148
+ return id;
149
+ });
150
+ exports.state_subscribeStorage = state_subscribeStorage;
151
+ /**
152
+ * @param context
153
+ * @param params - [`subid`]
154
+ * @param subscriptionManager
155
+ */
156
+ const state_unsubscribeStorage = (_context, [subid], { unsubscribe }) => __awaiter(void 0, void 0, void 0, function* () {
157
+ unsubscribe(subid);
158
+ });
159
+ exports.state_unsubscribeStorage = state_unsubscribeStorage;
160
+ /**
161
+ * @param context
162
+ * @param params - [`child`, `key`, `blockhash`]
163
+ *
164
+ * @return storage valuse
165
+ */
166
+ const childstate_getStorage = (context, [child, key, hash]) => __awaiter(void 0, void 0, void 0, function* () {
167
+ if (!(0, utils_1.isPrefixedChildKey)(child)) {
168
+ throw new shared_1.ResponseError(-32000, 'Client error: Invalid child storage key');
169
+ }
170
+ const block = yield context.chain.getBlock(hash);
171
+ const value = yield (block === null || block === void 0 ? void 0 : block.get((0, utils_1.prefixedChildKey)(child, key)));
172
+ return value || null;
173
+ });
174
+ exports.childstate_getStorage = childstate_getStorage;
175
+ /**
176
+ * @param context
177
+ * @param params - [`child`, `prefix`, `pageSize`, `startKey`, `blockhash`]
178
+ *
179
+ * @return paged keys
180
+ */
181
+ const childstate_getKeysPaged = (context, [child, prefix, pageSize, startKey, hash]) => __awaiter(void 0, void 0, void 0, function* () {
182
+ if (!(0, utils_1.isPrefixedChildKey)(child)) {
183
+ throw new shared_1.ResponseError(-32000, 'Client error: Invalid child storage key');
184
+ }
185
+ const block = yield context.chain.getBlock(hash);
186
+ return block === null || block === void 0 ? void 0 : block.getKeysPaged({ prefix: (0, utils_1.prefixedChildKey)(child, prefix), pageSize, startKey: (0, utils_1.prefixedChildKey)(child, startKey) }).then((keys) => keys.map(utils_1.stripChildPrefix));
187
+ });
188
+ exports.childstate_getKeysPaged = childstate_getKeysPaged;
@@ -0,0 +1,28 @@
1
+ import { HexString } from '@polkadot/util/types';
2
+ import { ChainProperties } from '../../api';
3
+ import { Handler } from '../shared';
4
+ export declare const system_localPeerId: () => Promise<string>;
5
+ export declare const system_nodeRoles: () => Promise<string[]>;
6
+ export declare const system_localListenAddresses: () => Promise<never[]>;
7
+ export declare const system_chain: Handler<void, string>;
8
+ export declare const system_properties: Handler<void, ChainProperties>;
9
+ export declare const system_name: Handler<void, string>;
10
+ export declare const system_version: Handler<void, string>;
11
+ export declare const system_chainType: Handler<void, string>;
12
+ export declare const system_health: () => Promise<{
13
+ peers: number;
14
+ isSyncing: boolean;
15
+ shouldHavePeers: boolean;
16
+ }>;
17
+ /**
18
+ * @param context
19
+ * @param params - [`extrinsic`, `at`]
20
+ *
21
+ * @return ApplyExtrinsicResult (see `@polkadot/types/interfaces`) in hash
22
+ */
23
+ export declare const system_dryRun: Handler<[HexString, HexString], string>;
24
+ /**
25
+ * @param context
26
+ * @param params - [`address`]
27
+ */
28
+ export declare const system_accountNextIndex: Handler<[HexString], number>;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.system_accountNextIndex = exports.system_dryRun = exports.system_health = exports.system_chainType = exports.system_version = exports.system_name = exports.system_properties = exports.system_chain = exports.system_localListenAddresses = exports.system_nodeRoles = exports.system_localPeerId = void 0;
13
+ const util_1 = require("@polkadot/util");
14
+ const system_localPeerId = () => __awaiter(void 0, void 0, void 0, function* () { return '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'; });
15
+ exports.system_localPeerId = system_localPeerId;
16
+ const system_nodeRoles = () => __awaiter(void 0, void 0, void 0, function* () { return ['Full']; });
17
+ exports.system_nodeRoles = system_nodeRoles;
18
+ const system_localListenAddresses = () => __awaiter(void 0, void 0, void 0, function* () { return []; });
19
+ exports.system_localListenAddresses = system_localListenAddresses;
20
+ const system_chain = (context) => __awaiter(void 0, void 0, void 0, function* () {
21
+ return context.chain.api.getSystemChain();
22
+ });
23
+ exports.system_chain = system_chain;
24
+ const system_properties = (context) => __awaiter(void 0, void 0, void 0, function* () {
25
+ return context.chain.api.getSystemProperties();
26
+ });
27
+ exports.system_properties = system_properties;
28
+ const system_name = (context) => __awaiter(void 0, void 0, void 0, function* () {
29
+ return context.chain.api.getSystemName();
30
+ });
31
+ exports.system_name = system_name;
32
+ const system_version = (_context) => __awaiter(void 0, void 0, void 0, function* () {
33
+ return 'chopsticks-v1';
34
+ });
35
+ exports.system_version = system_version;
36
+ const system_chainType = (_context) => __awaiter(void 0, void 0, void 0, function* () {
37
+ return 'Development';
38
+ });
39
+ exports.system_chainType = system_chainType;
40
+ const system_health = () => __awaiter(void 0, void 0, void 0, function* () {
41
+ return {
42
+ peers: 0,
43
+ isSyncing: false,
44
+ shouldHavePeers: false,
45
+ };
46
+ });
47
+ exports.system_health = system_health;
48
+ /**
49
+ * @param context
50
+ * @param params - [`extrinsic`, `at`]
51
+ *
52
+ * @return ApplyExtrinsicResult (see `@polkadot/types/interfaces`) in hash
53
+ */
54
+ const system_dryRun = (context, [extrinsic, at]) => __awaiter(void 0, void 0, void 0, function* () {
55
+ const { outcome } = yield context.chain.dryRunExtrinsic(extrinsic, at);
56
+ return outcome.toHex();
57
+ });
58
+ exports.system_dryRun = system_dryRun;
59
+ /**
60
+ * @param context
61
+ * @param params - [`address`]
62
+ */
63
+ const system_accountNextIndex = (context, [address]) => __awaiter(void 0, void 0, void 0, function* () {
64
+ const head = context.chain.head;
65
+ const registry = yield head.registry;
66
+ const account = registry.createType('AccountId', address);
67
+ const result = yield head.call('AccountNonceApi_account_nonce', [account.toHex()]);
68
+ const nonce = registry.createType('Index', (0, util_1.hexToU8a)(result.result)).toNumber();
69
+ return nonce + context.chain.txPool.pendingExtrinsicsBy(address).length;
70
+ });
71
+ exports.system_accountNextIndex = system_accountNextIndex;
@@ -12,7 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.timeTravel = exports.getSlotDuration = exports.getCurrentTimestamp = exports.getCurrentSlot = void 0;
13
13
  const util_1 = require("@polkadot/util");
14
14
  const _1 = require(".");
15
- const executor_1 = require("../executor");
15
+ const wasm_executor_1 = require("../wasm-executor");
16
16
  const set_storage_1 = require("./set-storage");
17
17
  const getCurrentSlot = (chain) => __awaiter(void 0, void 0, void 0, function* () {
18
18
  const meta = yield chain.head.meta;
@@ -36,7 +36,7 @@ const getSlotDuration = (chain) => __awaiter(void 0, void 0, void 0, function* (
36
36
  return meta.consts.babe
37
37
  ? meta.consts.babe.expectedBlockTime.toNumber()
38
38
  : meta.query.aura
39
- ? (0, executor_1.getAuraSlotDuration)(yield chain.head.wasm, meta.registry)
39
+ ? (0, wasm_executor_1.getAuraSlotDuration)(yield chain.head.wasm, meta.registry)
40
40
  : 12000;
41
41
  });
42
42
  exports.getSlotDuration = getSlotDuration;
@@ -0,0 +1,37 @@
1
+ import * as Comlink from 'comlink'
2
+ import * as pkg from '@acala-network/chopsticks-executor'
3
+
4
+ const getRuntimeVersion = async (code) => {
5
+ await pkg.wasmReady
6
+ return pkg.get_runtime_version(code)
7
+ }
8
+
9
+ // trie_version: 0 for old trie, 1 for new trie
10
+ const calculateStateRoot = async (entries, trie_version) => {
11
+ await pkg.wasmReady
12
+ return pkg.calculate_state_root(entries, trie_version)
13
+ }
14
+
15
+ const decodeProof = async (trieRootHash, keys, nodes) => {
16
+ await pkg.wasmReady
17
+ const decoded = await pkg.decode_proof(trieRootHash, keys, nodes)
18
+ return decoded.reduce((accum, [key, value]) => {
19
+ accum[key] = value
20
+ return accum
21
+ }, {})
22
+ }
23
+
24
+ const createProof = async (nodes, entries) => {
25
+ await pkg.wasmReady
26
+ const result = await pkg.create_proof(nodes, entries)
27
+ return { trieRootHash: result[0], nodes: result[1] }
28
+ }
29
+
30
+ const runTask = async (task, callback) => {
31
+ await pkg.wasmReady
32
+ return pkg.run_task(task, callback, 'info')
33
+ }
34
+
35
+ const wasmExecutor = { runTask, getRuntimeVersion, calculateStateRoot, createProof, decodeProof }
36
+
37
+ Comlink.expose(wasmExecutor)
@@ -0,0 +1,5 @@
1
+ import type { WasmExecutor } from '.';
2
+ export declare const startWorker: () => Promise<{
3
+ remote: import("comlink").Remote<WasmExecutor>;
4
+ terminate: () => Promise<void>;
5
+ }>;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.startWorker = void 0;
13
+ const comlink_1 = require("comlink");
14
+ const startWorker = () => __awaiter(void 0, void 0, void 0, function* () {
15
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
16
+ // @ts-ignore
17
+ const worker = new Worker(new URL('browser-wasm-executor.mjs', import.meta.url), {
18
+ type: 'module',
19
+ name: 'chopsticks-wasm-executor',
20
+ });
21
+ return {
22
+ remote: (0, comlink_1.wrap)(worker),
23
+ terminate: () => __awaiter(void 0, void 0, void 0, function* () {
24
+ worker.terminate();
25
+ }),
26
+ };
27
+ });
28
+ exports.startWorker = startWorker;
@@ -1,7 +1,7 @@
1
1
  import { HexString } from '@polkadot/util/types';
2
- import { Block } from './blockchain/block';
3
2
  import { Registry } from '@polkadot/types-codec/types';
4
3
  import _ from 'lodash';
4
+ import { Block } from '../blockchain/block';
5
5
  import type { JsCallback } from '@acala-network/chopsticks-executor';
6
6
  export { JsCallback };
7
7
  export type RuntimeVersion = {
@@ -14,7 +14,23 @@ export type RuntimeVersion = {
14
14
  transactionVersion: number;
15
15
  stateVersion: number;
16
16
  };
17
- export declare const getRuntimeVersion: (code: HexString) => Promise<RuntimeVersion>;
17
+ export interface WasmExecutor {
18
+ getRuntimeVersion: (code: HexString) => Promise<RuntimeVersion>;
19
+ calculateStateRoot: (entries: [HexString, HexString][], trie_version: number) => Promise<HexString>;
20
+ createProof: (nodes: HexString[], entries: [HexString, HexString | null][]) => Promise<{
21
+ trieRootHash: `0x${string}`;
22
+ nodes: `0x${string}`[];
23
+ }>;
24
+ decodeProof: (trieRootHash: HexString, keys: HexString[], nodes: HexString[]) => Promise<Record<`0x${string}`, `0x${string}` | null>>;
25
+ runTask: (task: {
26
+ wasm: HexString;
27
+ calls: [string, HexString[]][];
28
+ mockSignatureHost: boolean;
29
+ allowUnresolvedImports: boolean;
30
+ runtimeLogLevel: number;
31
+ }, callback?: JsCallback) => Promise<any>;
32
+ }
33
+ export declare const getRuntimeVersion: ((code: HexString) => Promise<RuntimeVersion>) & _.MemoizedFunction;
18
34
  export declare const calculateStateRoot: (entries: [HexString, HexString][], trie_version: number) => Promise<HexString>;
19
35
  export declare const decodeProof: (trieRootHash: HexString, keys: HexString[], nodes: HexString[]) => Promise<Record<`0x${string}`, `0x${string}` | null>>;
20
36
  export declare const createProof: (nodes: HexString[], entries: [HexString, HexString | null][]) => Promise<{
@@ -39,3 +55,4 @@ export declare const emptyTaskHandler: {
39
55
  offchainSubmitTransaction: (_tx: HexString) => Promise<never>;
40
56
  };
41
57
  export declare const getAuraSlotDuration: ((wasm: HexString, registry: Registry) => Promise<number>) & _.MemoizedFunction;
58
+ export declare const releaseWorker: () => Promise<void>;
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
26
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
27
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -12,44 +35,55 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
35
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
36
  };
14
37
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.getAuraSlotDuration = exports.emptyTaskHandler = exports.taskHandler = exports.runTask = exports.createProof = exports.decodeProof = exports.calculateStateRoot = exports.getRuntimeVersion = void 0;
38
+ exports.releaseWorker = exports.getAuraSlotDuration = exports.emptyTaskHandler = exports.taskHandler = exports.runTask = exports.createProof = exports.decodeProof = exports.calculateStateRoot = exports.getRuntimeVersion = void 0;
39
+ const Comlink = __importStar(require("comlink"));
16
40
  const util_1 = require("@polkadot/util");
17
41
  const util_crypto_1 = require("@polkadot/util-crypto");
18
- const key_cache_1 = require("./utils/key-cache");
19
- const chopsticks_executor_1 = require("@acala-network/chopsticks-executor");
20
- const logger_1 = require("./logger");
21
- const utils_1 = require("./utils");
22
42
  const lodash_1 = __importDefault(require("lodash"));
43
+ const key_cache_1 = require("../utils/key-cache");
44
+ const logger_1 = require("../logger");
45
+ const utils_1 = require("../utils");
23
46
  const logger = logger_1.defaultLogger.child({ name: 'executor' });
24
- const getRuntimeVersion = (code) => __awaiter(void 0, void 0, void 0, function* () {
25
- return (0, chopsticks_executor_1.get_runtime_version)(code).then((version) => {
47
+ let __executor_worker;
48
+ const getWorker = () => __awaiter(void 0, void 0, void 0, function* () {
49
+ if (__executor_worker)
50
+ return __executor_worker;
51
+ if (typeof Worker !== 'undefined') {
52
+ __executor_worker = Promise.resolve().then(() => __importStar(require('./browser-worker'))).then(({ startWorker }) => startWorker());
53
+ }
54
+ else {
55
+ __executor_worker = Promise.resolve().then(() => __importStar(require('./node-worker'))).then(({ startWorker }) => startWorker());
56
+ }
57
+ return __executor_worker;
58
+ });
59
+ exports.getRuntimeVersion = lodash_1.default.memoize((code) => __awaiter(void 0, void 0, void 0, function* () {
60
+ const worker = yield getWorker();
61
+ return worker.remote.getRuntimeVersion(code).then((version) => {
26
62
  version.specName = (0, util_1.hexToString)(version.specName);
27
63
  version.implName = (0, util_1.hexToString)(version.implName);
28
64
  return version;
29
65
  });
30
- });
31
- exports.getRuntimeVersion = getRuntimeVersion;
66
+ }));
32
67
  // trie_version: 0 for old trie, 1 for new trie
33
68
  const calculateStateRoot = (entries, trie_version) => __awaiter(void 0, void 0, void 0, function* () {
34
- return (0, chopsticks_executor_1.calculate_state_root)(entries, trie_version);
69
+ const worker = yield getWorker();
70
+ return worker.remote.calculateStateRoot(entries, trie_version);
35
71
  });
36
72
  exports.calculateStateRoot = calculateStateRoot;
37
73
  const decodeProof = (trieRootHash, keys, nodes) => __awaiter(void 0, void 0, void 0, function* () {
38
- const decoded = yield (0, chopsticks_executor_1.decode_proof)(trieRootHash, keys, nodes);
39
- return decoded.reduce((accum, [key, value]) => {
40
- accum[key] = value;
41
- return accum;
42
- }, {});
74
+ const worker = yield getWorker();
75
+ return worker.remote.decodeProof(trieRootHash, keys, nodes);
43
76
  });
44
77
  exports.decodeProof = decodeProof;
45
78
  const createProof = (nodes, entries) => __awaiter(void 0, void 0, void 0, function* () {
46
- const result = yield (0, chopsticks_executor_1.create_proof)(nodes, entries);
47
- return { trieRootHash: result[0], nodes: result[1] };
79
+ const worker = yield getWorker();
80
+ return worker.remote.createProof(nodes, entries);
48
81
  });
49
82
  exports.createProof = createProof;
50
83
  const runTask = (task, callback = exports.emptyTaskHandler) => __awaiter(void 0, void 0, void 0, function* () {
84
+ const worker = yield getWorker();
51
85
  logger.trace((0, logger_1.truncate)(task), 'taskRun');
52
- const response = yield (0, chopsticks_executor_1.run_task)(task, callback, typeof process === 'object' ? process.env.RUST_LOG : 'info');
86
+ const response = yield worker.remote.runTask(task, Comlink.proxy(callback));
53
87
  if (response.Call) {
54
88
  logger.trace((0, logger_1.truncate)(response.Call), 'taskResponse');
55
89
  }
@@ -167,3 +201,12 @@ exports.getAuraSlotDuration = lodash_1.default.memoize((wasm, registry) => __awa
167
201
  const slotDuration = registry.createType('u64', (0, util_1.hexToU8a)(result.Call.result)).toNumber();
168
202
  return slotDuration;
169
203
  }));
204
+ const releaseWorker = () => __awaiter(void 0, void 0, void 0, function* () {
205
+ if (!__executor_worker)
206
+ return;
207
+ const executor = yield __executor_worker;
208
+ executor.remote[Comlink.releaseProxy]();
209
+ yield executor.terminate();
210
+ __executor_worker = undefined;
211
+ });
212
+ exports.releaseWorker = releaseWorker;
@@ -0,0 +1,34 @@
1
+ import * as Comlink from 'comlink'
2
+ import * as pkg from '@acala-network/chopsticks-executor'
3
+ import { parentPort } from 'node:worker_threads'
4
+ import nodeEndpoint from 'comlink/dist/umd/node-adapter.js'
5
+
6
+ const getRuntimeVersion = async (code) => {
7
+ return pkg.get_runtime_version(code)
8
+ }
9
+
10
+ // trie_version: 0 for old trie, 1 for new trie
11
+ const calculateStateRoot = async (entries, trie_version) => {
12
+ return pkg.calculate_state_root(entries, trie_version)
13
+ }
14
+
15
+ const decodeProof = async (trieRootHash, keys, nodes) => {
16
+ const decoded = await pkg.decode_proof(trieRootHash, keys, nodes)
17
+ return decoded.reduce((accum, [key, value]) => {
18
+ accum[key] = value
19
+ return accum
20
+ }, {})
21
+ }
22
+
23
+ const createProof = async (nodes, entries) => {
24
+ const result = await pkg.create_proof(nodes, entries)
25
+ return { trieRootHash: result[0], nodes: result[1] }
26
+ }
27
+
28
+ const runTask = async (task, callback) => {
29
+ return pkg.run_task(task, callback, process.env.RUST_LOG)
30
+ }
31
+
32
+ const wasmExecutor = { runTask, getRuntimeVersion, calculateStateRoot, createProof, decodeProof }
33
+
34
+ Comlink.expose(wasmExecutor, nodeEndpoint(parentPort))
@@ -0,0 +1,5 @@
1
+ import type { WasmExecutor } from '.';
2
+ export declare const startWorker: () => Promise<{
3
+ remote: import("comlink").Remote<WasmExecutor>;
4
+ terminate: () => Promise<void>;
5
+ }>;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.startWorker = void 0;
16
+ const comlink_1 = require("comlink");
17
+ const node_adapter_js_1 = __importDefault(require("comlink/dist/umd/node-adapter.js"));
18
+ const node_worker_threads_1 = __importDefault(require("node:worker_threads"));
19
+ const node_url_1 = __importDefault(require("node:url"));
20
+ const startWorker = () => __awaiter(void 0, void 0, void 0, function* () {
21
+ const worker = new node_worker_threads_1.default.Worker(node_url_1.default.resolve(__filename, 'node-wasm-executor.mjs'), {
22
+ name: 'chopsticks-wasm-executor',
23
+ });
24
+ return {
25
+ remote: (0, comlink_1.wrap)((0, node_adapter_js_1.default)(worker)),
26
+ terminate: () => __awaiter(void 0, void 0, void 0, function* () {
27
+ yield worker.terminate();
28
+ }),
29
+ };
30
+ });
31
+ exports.startWorker = startWorker;
package/package.json CHANGED
@@ -1,19 +1,21 @@
1
1
  {
2
2
  "name": "@acala-network/chopsticks-core",
3
- "version": "0.8.3",
3
+ "version": "0.8.5-0",
4
4
  "author": "Acala Developers <hello@acala.network>",
5
5
  "license": "Apache-2.0",
6
6
  "scripts": {
7
7
  "clean": "rm -rf lib tsconfig.tsbuildinfo",
8
- "pack-wasm": "scripts/pack-wasm.js",
9
- "build": "yarn pack-wasm; tsc -p ./tsconfig.json",
8
+ "pack-wasm": "scripts/pack-wasm.cjs",
9
+ "build": "yarn pack-wasm; tsc -p ./tsconfig.json; yarn copyfiles",
10
+ "copyfiles": "cp -r src/wasm-executor/*.mjs lib/wasm-executor/",
10
11
  "docs:prep": "typedoc"
11
12
  },
12
13
  "dependencies": {
13
- "@acala-network/chopsticks-executor": "0.8.3",
14
+ "@acala-network/chopsticks-executor": "0.8.5-0",
14
15
  "@polkadot/api": "^10.9.1",
15
16
  "@polkadot/util-crypto": "^12.3.2",
16
17
  "axios": "^1.5.1",
18
+ "comlink": "^4.4.1",
17
19
  "eventemitter3": "^5.0.1",
18
20
  "localforage": "^1.10.0",
19
21
  "lodash": "^4.17.21",
@@ -45,5 +47,9 @@
45
47
  "default": "./lib/*.js"
46
48
  },
47
49
  "./package.json": "./package.json"
50
+ },
51
+ "browser": {
52
+ "./lib/wasm-executor/node-wasm-executor.mjs": "./lib/wasm-executor/browser-wasm-executor.mjs",
53
+ "./lib/wasm-executor/node-worker.js": "./lib/wasm-executor/browser-worker.js"
48
54
  }
49
55
  }