@acala-network/chopsticks-core 0.8.3 → 0.8.4
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/blockchain/block-builder.js +0 -3
- package/lib/blockchain/block.d.ts +1 -1
- package/lib/blockchain/block.js +4 -4
- package/lib/blockchain/index.d.ts +2 -2
- package/lib/blockchain/index.js +4 -2
- package/lib/blockchain/inherent/parachain/validation-data.js +5 -5
- package/lib/chopsticks-provider.d.ts +0 -0
- package/lib/chopsticks-provider.js +249 -0
- package/lib/chopsticks-worker.d.ts +1 -0
- package/lib/chopsticks-worker.js +101 -0
- package/lib/genesis-provider.d.ts +1 -1
- package/lib/genesis-provider.js +3 -3
- package/lib/index.d.ts +2 -1
- package/lib/index.js +3 -1
- package/lib/rpc/index.d.ts +5 -0
- package/lib/rpc/index.js +26 -0
- package/lib/rpc/shared.d.ts +27 -0
- package/lib/rpc/shared.js +19 -0
- package/lib/rpc/substrate/author.d.ts +28 -0
- package/lib/rpc/substrate/author.js +98 -0
- package/lib/rpc/substrate/chain.d.ts +45 -0
- package/lib/rpc/substrate/chain.js +103 -0
- package/lib/rpc/substrate/index.d.ts +66 -0
- package/lib/rpc/substrate/index.js +38 -0
- package/lib/rpc/substrate/payment.d.ts +16 -0
- package/lib/rpc/substrate/payment.js +54 -0
- package/lib/rpc/substrate/state.d.ts +97 -0
- package/lib/rpc/substrate/state.js +184 -0
- package/lib/rpc/substrate/system.d.ts +28 -0
- package/lib/rpc/substrate/system.js +71 -0
- package/lib/utils/time-travel.js +2 -2
- package/lib/wasm-executor/browser-wasm-executor.mjs +37 -0
- package/lib/wasm-executor/browser-worker.d.ts +5 -0
- package/lib/wasm-executor/browser-worker.js +28 -0
- package/lib/{executor.d.ts → wasm-executor/index.d.ts} +18 -1
- package/lib/{executor.js → wasm-executor/index.js} +59 -15
- package/lib/wasm-executor/node-wasm-executor.mjs +34 -0
- package/lib/wasm-executor/node-worker.d.ts +5 -0
- package/lib/wasm-executor/node-worker.js +31 -0
- package/package.json +6 -4
|
@@ -132,9 +132,6 @@ const buildBlock = (head, inherents, extrinsics, ump, callbacks, unsafeBlockHeig
|
|
|
132
132
|
const registry = yield head.registry;
|
|
133
133
|
const header = yield (0, exports.newHeader)(head, unsafeBlockHeight);
|
|
134
134
|
const newBlockNumber = header.number.toNumber();
|
|
135
|
-
if (newBlockNumber < head.number) {
|
|
136
|
-
throw new Error('unsafeBlockHeight is not allowed to be less than current block number');
|
|
137
|
-
}
|
|
138
135
|
logger.info({
|
|
139
136
|
number: newBlockNumber,
|
|
140
137
|
extrinsicsCount: extrinsics.length,
|
|
@@ -4,7 +4,7 @@ import { TypeRegistry } from '@polkadot/types';
|
|
|
4
4
|
import type { HexString } from '@polkadot/util/types';
|
|
5
5
|
import { Blockchain } from '.';
|
|
6
6
|
import { StorageLayer, StorageLayerProvider, StorageValue } from './storage-layer';
|
|
7
|
-
import type { RuntimeVersion } from '../executor';
|
|
7
|
+
import type { RuntimeVersion } from '../wasm-executor';
|
|
8
8
|
export type TaskCallResponse = {
|
|
9
9
|
result: HexString;
|
|
10
10
|
storageDiff: [HexString, HexString | null][];
|
package/lib/blockchain/block.js
CHANGED
|
@@ -29,7 +29,7 @@ const util_2 = require("@polkadot/util");
|
|
|
29
29
|
const storage_layer_1 = require("./storage-layer");
|
|
30
30
|
const utils_1 = require("../utils");
|
|
31
31
|
const logger_1 = require("../logger");
|
|
32
|
-
const
|
|
32
|
+
const wasm_executor_1 = require("../wasm-executor");
|
|
33
33
|
/**
|
|
34
34
|
* Block class.
|
|
35
35
|
*
|
|
@@ -223,7 +223,7 @@ class Block {
|
|
|
223
223
|
}
|
|
224
224
|
get runtimeVersion() {
|
|
225
225
|
if (!__classPrivateFieldGet(this, _Block_runtimeVersion, "f")) {
|
|
226
|
-
__classPrivateFieldSet(this, _Block_runtimeVersion, this.wasm.then(
|
|
226
|
+
__classPrivateFieldSet(this, _Block_runtimeVersion, this.wasm.then(wasm_executor_1.getRuntimeVersion), "f");
|
|
227
227
|
}
|
|
228
228
|
return __classPrivateFieldGet(this, _Block_runtimeVersion, "f");
|
|
229
229
|
}
|
|
@@ -248,13 +248,13 @@ class Block {
|
|
|
248
248
|
call(method, args) {
|
|
249
249
|
return __awaiter(this, void 0, void 0, function* () {
|
|
250
250
|
const wasm = yield this.wasm;
|
|
251
|
-
const response = yield (0,
|
|
251
|
+
const response = yield (0, wasm_executor_1.runTask)({
|
|
252
252
|
wasm,
|
|
253
253
|
calls: [[method, args]],
|
|
254
254
|
mockSignatureHost: __classPrivateFieldGet(this, _Block_chain, "f").mockSignatureHost,
|
|
255
255
|
allowUnresolvedImports: __classPrivateFieldGet(this, _Block_chain, "f").allowUnresolvedImports,
|
|
256
256
|
runtimeLogLevel: __classPrivateFieldGet(this, _Block_chain, "f").runtimeLogLevel,
|
|
257
|
-
}, (0,
|
|
257
|
+
}, (0, wasm_executor_1.taskHandler)(this));
|
|
258
258
|
if (response.Call) {
|
|
259
259
|
for (const log of response.Call.runtimeLogs) {
|
|
260
260
|
logger_1.defaultLogger.info(`RuntimeLogs:\n${log}`);
|
|
@@ -92,7 +92,7 @@ export declare class Blockchain {
|
|
|
92
92
|
/**
|
|
93
93
|
* Get block by number.
|
|
94
94
|
*/
|
|
95
|
-
getBlockAt(number?: number): Promise<Block | undefined>;
|
|
95
|
+
getBlockAt(number?: number | null): Promise<Block | undefined>;
|
|
96
96
|
/**
|
|
97
97
|
* Get block by hash.
|
|
98
98
|
*/
|
|
@@ -163,7 +163,7 @@ export declare class Blockchain {
|
|
|
163
163
|
*/
|
|
164
164
|
getInherents(): Promise<HexString[]>;
|
|
165
165
|
/**
|
|
166
|
-
* Close the db.
|
|
166
|
+
* Close the db and release worker.
|
|
167
167
|
*/
|
|
168
168
|
close(): Promise<void>;
|
|
169
169
|
}
|
package/lib/blockchain/index.js
CHANGED
|
@@ -32,6 +32,7 @@ const offchain_1 = require("../offchain");
|
|
|
32
32
|
const utils_1 = require("../utils");
|
|
33
33
|
const logger_1 = require("../logger");
|
|
34
34
|
const block_builder_1 = require("./block-builder");
|
|
35
|
+
const wasm_executor_1 = require("../wasm-executor");
|
|
35
36
|
const logger = logger_1.defaultLogger.child({ name: 'blockchain' });
|
|
36
37
|
/**
|
|
37
38
|
* Local blockchain which provides access to blocks, txpool and methods
|
|
@@ -160,7 +161,7 @@ class Blockchain {
|
|
|
160
161
|
*/
|
|
161
162
|
getBlockAt(number) {
|
|
162
163
|
return __awaiter(this, void 0, void 0, function* () {
|
|
163
|
-
if (number === undefined) {
|
|
164
|
+
if (number === null || number === undefined) {
|
|
164
165
|
return this.head;
|
|
165
166
|
}
|
|
166
167
|
if (number > __classPrivateFieldGet(this, _Blockchain_head, "f").number) {
|
|
@@ -445,11 +446,12 @@ class Blockchain {
|
|
|
445
446
|
});
|
|
446
447
|
}
|
|
447
448
|
/**
|
|
448
|
-
* Close the db.
|
|
449
|
+
* Close the db and release worker.
|
|
449
450
|
*/
|
|
450
451
|
close() {
|
|
451
452
|
var _a;
|
|
452
453
|
return __awaiter(this, void 0, void 0, function* () {
|
|
454
|
+
yield (0, wasm_executor_1.releaseWorker)();
|
|
453
455
|
yield ((_a = this.db) === null || _a === void 0 ? void 0 : _a.destroy());
|
|
454
456
|
});
|
|
455
457
|
}
|
|
@@ -19,7 +19,7 @@ const lodash_1 = __importDefault(require("lodash"));
|
|
|
19
19
|
const proof_1 = require("../../../utils/proof");
|
|
20
20
|
const util_crypto_1 = require("@polkadot/util-crypto");
|
|
21
21
|
const utils_1 = require("../../../utils");
|
|
22
|
-
const
|
|
22
|
+
const wasm_executor_1 = require("../../../wasm-executor");
|
|
23
23
|
const MOCK_VALIDATION_DATA = {
|
|
24
24
|
validationData: {
|
|
25
25
|
relayParentNumber: 1000,
|
|
@@ -78,7 +78,7 @@ class SetValidationData {
|
|
|
78
78
|
const hrmpIngressChannelIndexKey = (0, proof_1.hrmpIngressChannelIndex)(paraId);
|
|
79
79
|
const hrmpEgressChannelIndexKey = (0, proof_1.hrmpEgressChannelIndex)(paraId);
|
|
80
80
|
// TODO: refactor this to have a single decodeProof
|
|
81
|
-
const decoded = yield (0,
|
|
81
|
+
const decoded = yield (0, wasm_executor_1.decodeProof)(extrinsic.validationData.relayParentStorageRoot, [...Object.values(proof_1.WELL_KNOWN_KEYS), dmqMqcHeadKey, hrmpIngressChannelIndexKey, hrmpEgressChannelIndexKey], extrinsic.relayChainState.trieNodes);
|
|
82
82
|
for (const key of Object.values(proof_1.WELL_KNOWN_KEYS)) {
|
|
83
83
|
newEntries.push([key, decoded[key]]);
|
|
84
84
|
}
|
|
@@ -113,7 +113,7 @@ class SetValidationData {
|
|
|
113
113
|
receiver: paraId.toNumber(),
|
|
114
114
|
});
|
|
115
115
|
const hrmpChannelKey = (0, proof_1.hrmpChannels)(channelId);
|
|
116
|
-
const decoded = yield (0,
|
|
116
|
+
const decoded = yield (0, wasm_executor_1.decodeProof)(extrinsic.validationData.relayParentStorageRoot, [hrmpChannelKey], extrinsic.relayChainState.trieNodes);
|
|
117
117
|
const abridgedHrmpRaw = decoded[hrmpChannelKey];
|
|
118
118
|
if (!abridgedHrmpRaw)
|
|
119
119
|
throw new Error('Canoot find hrmp channels from validation data');
|
|
@@ -144,7 +144,7 @@ class SetValidationData {
|
|
|
144
144
|
receiver,
|
|
145
145
|
});
|
|
146
146
|
const hrmpChannelKey = (0, proof_1.hrmpChannels)(channelId);
|
|
147
|
-
const decoded = yield (0,
|
|
147
|
+
const decoded = yield (0, wasm_executor_1.decodeProof)(extrinsic.validationData.relayParentStorageRoot, [hrmpChannelKey], extrinsic.relayChainState.trieNodes);
|
|
148
148
|
newEntries.push([hrmpChannelKey, decoded[hrmpChannelKey]]);
|
|
149
149
|
}
|
|
150
150
|
const upgradeKey = (0, proof_1.upgradeGoAheadSignal)(paraId);
|
|
@@ -158,7 +158,7 @@ class SetValidationData {
|
|
|
158
158
|
// make sure previous goAhead is removed
|
|
159
159
|
newEntries.push([upgradeKey, null]);
|
|
160
160
|
}
|
|
161
|
-
const { trieRootHash, nodes } = yield (0,
|
|
161
|
+
const { trieRootHash, nodes } = yield (0, wasm_executor_1.createProof)(extrinsic.relayChainState.trieNodes, newEntries);
|
|
162
162
|
newData = Object.assign(Object.assign({}, extrinsic), { downwardMessages,
|
|
163
163
|
horizontalMessages, validationData: Object.assign(Object.assign({}, extrinsic.validationData), { relayParentStorageRoot: trieRootHash, relayParentNumber: extrinsic.validationData.relayParentNumber + 2 }), relayChainState: {
|
|
164
164
|
trieNodes: nodes,
|
|
File without changes
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// import { EventEmitter } from 'eventemitter3'
|
|
3
|
+
// import {
|
|
4
|
+
// ProviderInterface,
|
|
5
|
+
// ProviderInterfaceCallback,
|
|
6
|
+
// ProviderInterfaceEmitCb,
|
|
7
|
+
// ProviderInterfaceEmitted,
|
|
8
|
+
// ProviderStats,
|
|
9
|
+
// } from '@polkadot/rpc-provider/types'
|
|
10
|
+
// import { StorageValues } from './utils'
|
|
11
|
+
// import { defaultLogger } from './logger'
|
|
12
|
+
// const logger = defaultLogger.child({ name: '[Chopsticks provider]' })
|
|
13
|
+
// interface SubscriptionHandler {
|
|
14
|
+
// callback: ProviderInterfaceCallback
|
|
15
|
+
// type: string
|
|
16
|
+
// }
|
|
17
|
+
// interface Subscription extends SubscriptionHandler {
|
|
18
|
+
// method: string
|
|
19
|
+
// params: unknown[]
|
|
20
|
+
// onCancel?: () => void
|
|
21
|
+
// result?: unknown
|
|
22
|
+
// }
|
|
23
|
+
// interface Handler {
|
|
24
|
+
// callback: ProviderInterfaceCallback
|
|
25
|
+
// method: string
|
|
26
|
+
// params: unknown[]
|
|
27
|
+
// start: number
|
|
28
|
+
// subscription?: SubscriptionHandler | undefined
|
|
29
|
+
// }
|
|
30
|
+
// export interface ChopsticksProviderProps {
|
|
31
|
+
// /** upstream endpoint */
|
|
32
|
+
// endpoint: string
|
|
33
|
+
// /** default to latest block */
|
|
34
|
+
// blockHash?: string
|
|
35
|
+
// dbPath?: string
|
|
36
|
+
// storageValues?: StorageValues
|
|
37
|
+
// }
|
|
38
|
+
// /**
|
|
39
|
+
// * A provider for ApiPromise.
|
|
40
|
+
// *
|
|
41
|
+
// * Currectly only support browser environment.
|
|
42
|
+
// */
|
|
43
|
+
// export class ChopsticksProvider implements ProviderInterface {
|
|
44
|
+
// #isConnected = false
|
|
45
|
+
// #eventemitter: EventEmitter
|
|
46
|
+
// #isReadyPromise: Promise<void>
|
|
47
|
+
// #endpoint: string
|
|
48
|
+
// readonly stats?: ProviderStats
|
|
49
|
+
// #subscriptions: Record<string, Subscription> = {}
|
|
50
|
+
// #worker: Worker
|
|
51
|
+
// #blockHash: string | undefined
|
|
52
|
+
// #dbPath: string | undefined
|
|
53
|
+
// #storageValues: StorageValues | undefined
|
|
54
|
+
// #handlers: Record<string, Handler> = {}
|
|
55
|
+
// #idCounter = 0
|
|
56
|
+
// constructor({ endpoint, blockHash, dbPath, storageValues }: ChopsticksProviderProps) {
|
|
57
|
+
// if (!endpoint) {
|
|
58
|
+
// throw new Error('ChopsticksProvider requires the upstream endpoint')
|
|
59
|
+
// }
|
|
60
|
+
// this.#endpoint = endpoint
|
|
61
|
+
// this.#blockHash = blockHash
|
|
62
|
+
// this.#dbPath = dbPath
|
|
63
|
+
// this.#storageValues = storageValues
|
|
64
|
+
// this.#eventemitter = new EventEmitter()
|
|
65
|
+
// this.#isReadyPromise = new Promise((resolve, reject): void => {
|
|
66
|
+
// this.#eventemitter.once('connected', (): void => {
|
|
67
|
+
// logger.debug('isReadyPromise: connected.')
|
|
68
|
+
// resolve()
|
|
69
|
+
// })
|
|
70
|
+
// this.#eventemitter.once('error', reject)
|
|
71
|
+
// })
|
|
72
|
+
// const chopsticksWorker = new Worker(new URL('./chopsticks-worker', import.meta.url), { type: 'module' })
|
|
73
|
+
// this.#worker = chopsticksWorker
|
|
74
|
+
// this.connect()
|
|
75
|
+
// }
|
|
76
|
+
// get hasSubscriptions(): boolean {
|
|
77
|
+
// return true
|
|
78
|
+
// }
|
|
79
|
+
// get isClonable(): boolean {
|
|
80
|
+
// return true
|
|
81
|
+
// }
|
|
82
|
+
// get isConnected(): boolean {
|
|
83
|
+
// return this.#isConnected
|
|
84
|
+
// }
|
|
85
|
+
// get isReady(): Promise<void> {
|
|
86
|
+
// return this.#isReadyPromise
|
|
87
|
+
// }
|
|
88
|
+
// clone = (): ProviderInterface => {
|
|
89
|
+
// return new ChopsticksProvider({ endpoint: this.#endpoint })
|
|
90
|
+
// }
|
|
91
|
+
// connect = async (): Promise<void> => {
|
|
92
|
+
// if (this.#isConnected) {
|
|
93
|
+
// return
|
|
94
|
+
// }
|
|
95
|
+
// this.#worker!.onmessage = this.#onWorkerMessage
|
|
96
|
+
// this.#worker?.postMessage({
|
|
97
|
+
// type: 'connect',
|
|
98
|
+
// endpoint: this.#endpoint,
|
|
99
|
+
// blockHash: this.#blockHash,
|
|
100
|
+
// dbPath: this.#dbPath,
|
|
101
|
+
// storageValues: this.#storageValues,
|
|
102
|
+
// })
|
|
103
|
+
// }
|
|
104
|
+
// disconnect = async (): Promise<void> => {
|
|
105
|
+
// this.#worker?.postMessage({ type: 'disconnect' })
|
|
106
|
+
// this.#isConnected = false
|
|
107
|
+
// this.#eventemitter.emit('disconnected')
|
|
108
|
+
// }
|
|
109
|
+
// on = (type: ProviderInterfaceEmitted, sub: ProviderInterfaceEmitCb): (() => void) => {
|
|
110
|
+
// this.#eventemitter.on(type, sub)
|
|
111
|
+
// return (): void => {
|
|
112
|
+
// this.#eventemitter.removeListener(type, sub)
|
|
113
|
+
// }
|
|
114
|
+
// }
|
|
115
|
+
// send = async <T>(
|
|
116
|
+
// method: string,
|
|
117
|
+
// params: unknown[],
|
|
118
|
+
// _isCacheable?: boolean,
|
|
119
|
+
// subscription?: SubscriptionHandler,
|
|
120
|
+
// ): Promise<T> => {
|
|
121
|
+
// return new Promise<T>((resolve, reject): void => {
|
|
122
|
+
// try {
|
|
123
|
+
// if (!this.isConnected || this.#worker === undefined) {
|
|
124
|
+
// throw new Error('Api is not connected')
|
|
125
|
+
// }
|
|
126
|
+
// logger.debug('send', { method, params })
|
|
127
|
+
// const id = `${method}::${this.#idCounter++}`
|
|
128
|
+
// const callback = (error?: Error | null, result?: T): void => {
|
|
129
|
+
// if (subscription) {
|
|
130
|
+
// // if it's a subscription, we usually returns the subid
|
|
131
|
+
// const subid = result as string
|
|
132
|
+
// if (subid) {
|
|
133
|
+
// if (!this.#subscriptions[subid]) {
|
|
134
|
+
// this.#subscriptions[subid] = {
|
|
135
|
+
// callback: subscription.callback,
|
|
136
|
+
// method,
|
|
137
|
+
// params,
|
|
138
|
+
// type: subscription.type,
|
|
139
|
+
// }
|
|
140
|
+
// }
|
|
141
|
+
// }
|
|
142
|
+
// }
|
|
143
|
+
// error ? reject(error) : resolve(result as T)
|
|
144
|
+
// }
|
|
145
|
+
// this.#handlers[id] = {
|
|
146
|
+
// callback,
|
|
147
|
+
// method,
|
|
148
|
+
// params,
|
|
149
|
+
// start: Date.now(),
|
|
150
|
+
// subscription,
|
|
151
|
+
// }
|
|
152
|
+
// this.#worker?.postMessage({
|
|
153
|
+
// type: 'send',
|
|
154
|
+
// id,
|
|
155
|
+
// method,
|
|
156
|
+
// params,
|
|
157
|
+
// })
|
|
158
|
+
// } catch (error) {
|
|
159
|
+
// reject(error)
|
|
160
|
+
// }
|
|
161
|
+
// })
|
|
162
|
+
// }
|
|
163
|
+
// subscribe(
|
|
164
|
+
// type: string,
|
|
165
|
+
// method: string,
|
|
166
|
+
// params: unknown[],
|
|
167
|
+
// callback: ProviderInterfaceCallback,
|
|
168
|
+
// ): Promise<number | string> {
|
|
169
|
+
// return this.send<string | number>(method, params, false, { callback, type })
|
|
170
|
+
// }
|
|
171
|
+
// async unsubscribe(_type: string, method: string, id: number | string): Promise<boolean> {
|
|
172
|
+
// if (!this.#subscriptions[id]) {
|
|
173
|
+
// logger.error(`Unable to find active subscription=${id}`)
|
|
174
|
+
// return false
|
|
175
|
+
// }
|
|
176
|
+
// try {
|
|
177
|
+
// return this.isConnected ? this.send<boolean>(method, [id]) : true
|
|
178
|
+
// } catch {
|
|
179
|
+
// return false
|
|
180
|
+
// }
|
|
181
|
+
// }
|
|
182
|
+
// #onWorkerMessage = (e: any) => {
|
|
183
|
+
// switch (e.data.type) {
|
|
184
|
+
// case 'connection':
|
|
185
|
+
// logger.debug('connection.', e.data)
|
|
186
|
+
// if (e.data.connected) {
|
|
187
|
+
// this.#isConnected = true
|
|
188
|
+
// this.#eventemitter.emit('connected')
|
|
189
|
+
// } else {
|
|
190
|
+
// this.#isConnected = false
|
|
191
|
+
// this.#eventemitter.emit('error', new Error('Unable to connect to the chain'))
|
|
192
|
+
// logger.error(`Unable to connect to the chain: ${e.data.message}`)
|
|
193
|
+
// }
|
|
194
|
+
// break
|
|
195
|
+
// case 'subscribe-callback':
|
|
196
|
+
// {
|
|
197
|
+
// logger.debug('subscribe-callback', e.data)
|
|
198
|
+
// const sub = this.#subscriptions[e.data.subid]
|
|
199
|
+
// if (!sub) {
|
|
200
|
+
// // record it first, sometimes callback comes first
|
|
201
|
+
// this.#subscriptions[e.data.subid] = {
|
|
202
|
+
// callback: () => {},
|
|
203
|
+
// method: e.data.method,
|
|
204
|
+
// params: e.data.params,
|
|
205
|
+
// type: e.data.type,
|
|
206
|
+
// result: JSON.parse(e.data.result),
|
|
207
|
+
// }
|
|
208
|
+
// return
|
|
209
|
+
// }
|
|
210
|
+
// sub.callback(null, JSON.parse(e.data.result))
|
|
211
|
+
// }
|
|
212
|
+
// break
|
|
213
|
+
// case 'unsubscribe-callback':
|
|
214
|
+
// {
|
|
215
|
+
// logger.debug('unsubscribe-callback', e.data)
|
|
216
|
+
// const sub = this.#subscriptions[e.data.subid]
|
|
217
|
+
// if (!sub) {
|
|
218
|
+
// logger.error(`Unable to find active subscription=${e.data.subid}`)
|
|
219
|
+
// return
|
|
220
|
+
// }
|
|
221
|
+
// sub?.onCancel?.()
|
|
222
|
+
// delete this.#subscriptions[e.data.subid]
|
|
223
|
+
// }
|
|
224
|
+
// break
|
|
225
|
+
// case 'send-result':
|
|
226
|
+
// {
|
|
227
|
+
// const handler = this.#handlers[e.data.id]
|
|
228
|
+
// if (!handler) {
|
|
229
|
+
// logger.error(`Unable to find handler=${e.data.id}`)
|
|
230
|
+
// return
|
|
231
|
+
// }
|
|
232
|
+
// logger.debug('send-result', {
|
|
233
|
+
// method: e.data.method,
|
|
234
|
+
// result: JSON.parse(e.data.result || '{}'),
|
|
235
|
+
// data: e.data,
|
|
236
|
+
// })
|
|
237
|
+
// try {
|
|
238
|
+
// handler.callback(null, e.data.result ? JSON.parse(e.data.result) : undefined)
|
|
239
|
+
// } catch (error) {
|
|
240
|
+
// handler.callback(error as Error, undefined)
|
|
241
|
+
// }
|
|
242
|
+
// delete this.#handlers[e.data.id]
|
|
243
|
+
// }
|
|
244
|
+
// break
|
|
245
|
+
// default:
|
|
246
|
+
// break
|
|
247
|
+
// }
|
|
248
|
+
// }
|
|
249
|
+
// }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,101 @@
|
|
|
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
|
+
const rpc_1 = require("./rpc");
|
|
13
|
+
const logger_1 = require("./logger");
|
|
14
|
+
const utils_1 = require("./utils");
|
|
15
|
+
const setup_1 = require("./setup");
|
|
16
|
+
let chain;
|
|
17
|
+
const logger = logger_1.defaultLogger.child({ name: '[Chopsticks worker]' });
|
|
18
|
+
const subscriptions = {};
|
|
19
|
+
const providerHandlers = Object.assign(Object.assign({}, rpc_1.allHandlers), { new_block: (context, _params, _subscriptionManager) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
+
const { chain } = context;
|
|
21
|
+
const block = yield chain.newBlock();
|
|
22
|
+
return block;
|
|
23
|
+
}) });
|
|
24
|
+
const subscriptionManager = {
|
|
25
|
+
subscribe: (method, subid, onCancel = () => { }) => {
|
|
26
|
+
subscriptions[subid] = onCancel;
|
|
27
|
+
return (data) => {
|
|
28
|
+
postMessage({
|
|
29
|
+
type: 'subscribe-callback',
|
|
30
|
+
method,
|
|
31
|
+
subid,
|
|
32
|
+
result: JSON.stringify(data),
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
unsubscribe: (subid) => {
|
|
37
|
+
if (subscriptions[subid]) {
|
|
38
|
+
subscriptions[subid](subid); // call onCancel
|
|
39
|
+
postMessage({
|
|
40
|
+
type: 'unsubscribe-callback',
|
|
41
|
+
subid,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
onmessage = (e) => __awaiter(void 0, void 0, void 0, function* () {
|
|
47
|
+
var _a;
|
|
48
|
+
switch (e.data.type) {
|
|
49
|
+
case 'connect':
|
|
50
|
+
try {
|
|
51
|
+
logger.debug('onMessage: connect. Initializing...');
|
|
52
|
+
chain = yield (0, setup_1.setup)({
|
|
53
|
+
endpoint: e.data.endpoint,
|
|
54
|
+
mockSignatureHost: true,
|
|
55
|
+
db: e.data.dbPath,
|
|
56
|
+
block: e.data.blockHash,
|
|
57
|
+
});
|
|
58
|
+
logger.debug('onMessage: connect. Chain setup done.');
|
|
59
|
+
yield (0, utils_1.setStorage)(chain, e.data.storageValues);
|
|
60
|
+
logger.debug('onMessage: connect. Set storage done.');
|
|
61
|
+
postMessage({
|
|
62
|
+
type: 'connection',
|
|
63
|
+
connected: true,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch (e) {
|
|
67
|
+
logger.error('onMessage: connect error.', e);
|
|
68
|
+
postMessage({
|
|
69
|
+
type: 'connection',
|
|
70
|
+
connected: false,
|
|
71
|
+
message: e,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
break;
|
|
75
|
+
case 'disconnect':
|
|
76
|
+
if (chain) {
|
|
77
|
+
yield ((_a = chain === null || chain === void 0 ? void 0 : chain.api) === null || _a === void 0 ? void 0 : _a.disconnect());
|
|
78
|
+
yield (chain === null || chain === void 0 ? void 0 : chain.close());
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
case 'send':
|
|
82
|
+
{
|
|
83
|
+
const { method, params } = e.data;
|
|
84
|
+
const handler = providerHandlers[method];
|
|
85
|
+
if (!handler) {
|
|
86
|
+
logger.error(`Unable to find rpc handler=${method}`);
|
|
87
|
+
return Promise.reject(new Error(`Unable to find handler=${method}`));
|
|
88
|
+
}
|
|
89
|
+
const result = yield handler({ chain: chain }, params, subscriptionManager);
|
|
90
|
+
postMessage({
|
|
91
|
+
type: 'send-result',
|
|
92
|
+
id: e.data.id,
|
|
93
|
+
method: method,
|
|
94
|
+
result: JSON.stringify(result),
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
break;
|
|
98
|
+
default:
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { HexString } from '@polkadot/util/types';
|
|
2
2
|
import { ProviderInterface, ProviderInterfaceCallback, ProviderInterfaceEmitCb, ProviderInterfaceEmitted, ProviderStats } from '@polkadot/rpc-provider/types';
|
|
3
3
|
import { Genesis } from './schema';
|
|
4
|
-
import { JsCallback } from './executor';
|
|
4
|
+
import { JsCallback } from './wasm-executor';
|
|
5
5
|
export declare class GenesisProvider implements ProviderInterface {
|
|
6
6
|
#private;
|
|
7
7
|
readonly stats?: ProviderStats;
|
package/lib/genesis-provider.js
CHANGED
|
@@ -51,7 +51,7 @@ exports.GenesisProvider = void 0;
|
|
|
51
51
|
const eventemitter3_1 = require("eventemitter3");
|
|
52
52
|
const axios_1 = __importDefault(require("axios"));
|
|
53
53
|
const schema_1 = require("./schema");
|
|
54
|
-
const
|
|
54
|
+
const wasm_executor_1 = require("./wasm-executor");
|
|
55
55
|
const utils_1 = require("./utils");
|
|
56
56
|
class GenesisProvider {
|
|
57
57
|
constructor(genesis) {
|
|
@@ -127,7 +127,7 @@ class GenesisProvider {
|
|
|
127
127
|
throw Error('unimplemented');
|
|
128
128
|
});
|
|
129
129
|
__classPrivateFieldSet(this, _GenesisProvider_genesis, genesis, "f");
|
|
130
|
-
__classPrivateFieldSet(this, _GenesisProvider_stateRoot, (0,
|
|
130
|
+
__classPrivateFieldSet(this, _GenesisProvider_stateRoot, (0, wasm_executor_1.calculateStateRoot)(Object.entries(__classPrivateFieldGet(this, _GenesisProvider_genesis, "f").genesis.raw.top).reduce((accu, item) => {
|
|
131
131
|
accu.push(item);
|
|
132
132
|
return accu;
|
|
133
133
|
}, []), 1), "f");
|
|
@@ -157,7 +157,7 @@ class GenesisProvider {
|
|
|
157
157
|
}
|
|
158
158
|
get _jsCallback() {
|
|
159
159
|
const storage = __classPrivateFieldGet(this, _GenesisProvider_genesis, "f").genesis.raw.top;
|
|
160
|
-
return Object.assign(Object.assign({},
|
|
160
|
+
return Object.assign(Object.assign({}, wasm_executor_1.emptyTaskHandler), { getStorage: function (key) {
|
|
161
161
|
return __awaiter(this, void 0, void 0, function* () {
|
|
162
162
|
return storage[key];
|
|
163
163
|
});
|
package/lib/index.d.ts
CHANGED
|
@@ -15,10 +15,11 @@ export * from './blockchain/txpool';
|
|
|
15
15
|
export * from './blockchain/storage-layer';
|
|
16
16
|
export * from './blockchain/head-state';
|
|
17
17
|
export * from './utils';
|
|
18
|
-
export * from './executor';
|
|
18
|
+
export * from './wasm-executor';
|
|
19
19
|
export * from './schema';
|
|
20
20
|
export * from './xcm';
|
|
21
21
|
export * from './setup';
|
|
22
22
|
export * from './blockchain/inherent';
|
|
23
23
|
export * from './logger';
|
|
24
24
|
export * from './offchain';
|
|
25
|
+
export * from './rpc';
|
package/lib/index.js
CHANGED
|
@@ -31,10 +31,12 @@ __exportStar(require("./blockchain/txpool"), exports);
|
|
|
31
31
|
__exportStar(require("./blockchain/storage-layer"), exports);
|
|
32
32
|
__exportStar(require("./blockchain/head-state"), exports);
|
|
33
33
|
__exportStar(require("./utils"), exports);
|
|
34
|
-
__exportStar(require("./executor"), exports);
|
|
34
|
+
__exportStar(require("./wasm-executor"), exports);
|
|
35
35
|
__exportStar(require("./schema"), exports);
|
|
36
36
|
__exportStar(require("./xcm"), exports);
|
|
37
37
|
__exportStar(require("./setup"), exports);
|
|
38
38
|
__exportStar(require("./blockchain/inherent"), exports);
|
|
39
39
|
__exportStar(require("./logger"), exports);
|
|
40
40
|
__exportStar(require("./offchain"), exports);
|
|
41
|
+
// export * from './chopsticks-provider'
|
|
42
|
+
__exportStar(require("./rpc"), exports);
|
package/lib/rpc/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
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.ResponseError = exports.substrate = exports.allHandlers = void 0;
|
|
16
|
+
const substrate_1 = __importDefault(require("./substrate"));
|
|
17
|
+
exports.allHandlers = Object.assign(Object.assign({}, substrate_1.default), { rpc_methods: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
18
|
+
return Promise.resolve({
|
|
19
|
+
version: 1,
|
|
20
|
+
methods: [...Object.keys(exports.allHandlers)],
|
|
21
|
+
});
|
|
22
|
+
}) });
|
|
23
|
+
var substrate_2 = require("./substrate");
|
|
24
|
+
Object.defineProperty(exports, "substrate", { enumerable: true, get: function () { return __importDefault(substrate_2).default; } });
|
|
25
|
+
var shared_1 = require("./shared");
|
|
26
|
+
Object.defineProperty(exports, "ResponseError", { enumerable: true, get: function () { return shared_1.ResponseError; } });
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Blockchain } from '@acala-network/chopsticks-core';
|
|
2
|
+
export declare const logger: import("pino").default.Logger<{
|
|
3
|
+
level: string;
|
|
4
|
+
transport: {
|
|
5
|
+
target: string;
|
|
6
|
+
};
|
|
7
|
+
}>;
|
|
8
|
+
export declare class ResponseError extends Error {
|
|
9
|
+
code: number;
|
|
10
|
+
constructor(code: number, message: string);
|
|
11
|
+
toJSON(): {
|
|
12
|
+
code: number;
|
|
13
|
+
message: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export interface Context {
|
|
17
|
+
/**
|
|
18
|
+
* The blockchain instance
|
|
19
|
+
*/
|
|
20
|
+
chain: Blockchain;
|
|
21
|
+
}
|
|
22
|
+
export interface SubscriptionManager {
|
|
23
|
+
subscribe: (method: string, subid: string, onCancel?: () => void) => (data: any) => void;
|
|
24
|
+
unsubscribe: (subid: string) => void;
|
|
25
|
+
}
|
|
26
|
+
export type Handler<TParams = any, TReturn = any> = (context: Context, params: TParams, subscriptionManager: SubscriptionManager) => Promise<TReturn>;
|
|
27
|
+
export type Handlers = Record<string, Handler>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ResponseError = exports.logger = void 0;
|
|
4
|
+
const logger_1 = require("../logger");
|
|
5
|
+
exports.logger = logger_1.defaultLogger.child({ name: 'rpc' });
|
|
6
|
+
class ResponseError extends Error {
|
|
7
|
+
constructor(code, message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = 'ResponseError';
|
|
10
|
+
this.code = code;
|
|
11
|
+
}
|
|
12
|
+
toJSON() {
|
|
13
|
+
return {
|
|
14
|
+
code: this.code,
|
|
15
|
+
message: this.message,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.ResponseError = ResponseError;
|