@acala-network/chopsticks 0.9.1-2 → 0.9.1-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/dist/cjs/cli-options.js +30 -15
- package/dist/cjs/cli.js +69 -80
- package/dist/cjs/context.js +94 -65
- package/dist/cjs/index.js +32 -20
- package/dist/cjs/logger.js +18 -5
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/plugins/decode-key/index.js +23 -20
- package/dist/cjs/plugins/dry-run/cli.js +46 -41
- package/dist/cjs/plugins/dry-run/dry-run-extrinsic.js +37 -21
- package/dist/cjs/plugins/dry-run/dry-run-preimage.js +102 -48
- package/dist/cjs/plugins/dry-run/index.js +18 -17
- package/dist/cjs/plugins/dry-run/rpc.js +48 -74
- package/dist/cjs/plugins/follow-chain/index.js +78 -46
- package/dist/cjs/plugins/index.js +76 -40
- package/dist/cjs/plugins/new-block/index.js +21 -53
- package/dist/cjs/plugins/run-block/__snapshots__/index.test.ts.snap +16745 -0
- package/dist/cjs/plugins/run-block/index.js +145 -104
- package/dist/cjs/plugins/set-block-build-mode/index.js +17 -25
- package/dist/cjs/plugins/set-head/index.js +13 -23
- package/dist/cjs/plugins/set-runtime-log-level/index.js +16 -23
- package/dist/cjs/plugins/set-storage/index.js +16 -35
- package/dist/cjs/plugins/time-travel/index.js +13 -23
- package/dist/cjs/plugins/try-runtime/index.js +51 -42
- package/dist/cjs/plugins/types.js +43 -18
- package/dist/cjs/rpc/index.js +30 -21
- package/dist/cjs/schema/index.js +77 -48
- package/dist/cjs/server.js +89 -65
- package/dist/cjs/setup-with-server.js +19 -13
- package/dist/cjs/types.js +30 -18
- package/dist/cjs/utils/decoder.js +32 -16
- package/dist/cjs/utils/generate-html-diff.js +38 -19
- package/dist/cjs/utils/index.js +20 -19
- package/dist/cjs/utils/open-html.js +12 -6
- package/dist/cjs/utils/override.js +40 -27
- package/dist/cjs/utils/tunnel.js +11 -14
- package/dist/esm/cli-options.js +11 -11
- package/dist/esm/cli.js +49 -64
- package/dist/esm/context.js +22 -26
- package/dist/esm/index.js +2 -2
- package/dist/esm/plugins/decode-key/index.js +11 -14
- package/dist/esm/plugins/dry-run/cli.js +35 -36
- package/dist/esm/plugins/dry-run/dry-run-extrinsic.js +22 -12
- package/dist/esm/plugins/dry-run/dry-run-preimage.js +77 -29
- package/dist/esm/plugins/dry-run/index.js +2 -2
- package/dist/esm/plugins/dry-run/rpc.js +16 -26
- package/dist/esm/plugins/follow-chain/index.js +56 -32
- package/dist/esm/plugins/index.js +9 -7
- package/dist/esm/plugins/new-block/index.js +9 -10
- package/dist/esm/plugins/run-block/__snapshots__/index.test.ts.snap +16745 -0
- package/dist/esm/plugins/run-block/index.js +101 -69
- package/dist/esm/plugins/set-block-build-mode/index.js +5 -4
- package/dist/esm/plugins/set-head/index.js +2 -4
- package/dist/esm/plugins/set-runtime-log-level/index.js +5 -4
- package/dist/esm/plugins/set-storage/index.js +4 -5
- package/dist/esm/plugins/time-travel/index.js +2 -4
- package/dist/esm/plugins/try-runtime/index.js +37 -34
- package/dist/esm/plugins/types.js +8 -8
- package/dist/esm/rpc/index.js +19 -16
- package/dist/esm/schema/index.js +31 -18
- package/dist/esm/server.js +71 -53
- package/dist/esm/setup-with-server.js +6 -6
- package/dist/esm/types.js +13 -2
- package/dist/esm/utils/decoder.js +12 -4
- package/dist/esm/utils/generate-html-diff.js +11 -7
- package/dist/esm/utils/index.js +4 -4
- package/dist/esm/utils/open-html.js +1 -1
- package/dist/esm/utils/override.js +12 -14
- package/dist/esm/utils/tunnel.js +1 -8
- package/dist/types/context.d.ts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/plugins/dry-run/dry-run-extrinsic.d.ts +1 -1
- package/dist/types/plugins/dry-run/dry-run-preimage.d.ts +1 -1
- package/dist/types/plugins/dry-run/index.d.ts +2 -2
- package/dist/types/plugins/run-block/index.d.ts +1 -1
- package/dist/types/plugins/types.d.ts +11 -11
- package/dist/types/setup-with-server.d.ts +1 -1
- package/dist/types/types.d.ts +2 -2
- package/dist/types/utils/index.d.ts +4 -4
- package/package.json +17 -21
- package/dist/esm/package.json +0 -1
- /package/{chopsticks.js → chopsticks.cjs} +0 -0
|
@@ -1,44 +1,58 @@
|
|
|
1
1
|
import { u8aToHex } from '@polkadot/util';
|
|
2
2
|
import { writeFileSync } from 'node:fs';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { Block, compactHex, decodeKeyValue, printRuntimeLogs, runTask, taskHandler
|
|
5
|
-
import { defaultOptions, mockOptions } from '../../cli-options';
|
|
6
|
-
import { generateHtmlDiffPreviewFile } from '../../utils/generate-html-diff';
|
|
7
|
-
import { openHtml } from '../../utils/open-html';
|
|
8
|
-
import { setupContext } from '../../context';
|
|
9
|
-
export const cli = (y)
|
|
10
|
-
y.command('run-block', 'Replay a block', (yargs)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
4
|
+
import { Block, compactHex, decodeKeyValue, printRuntimeLogs, runTask, taskHandler } from '@acala-network/chopsticks-core';
|
|
5
|
+
import { defaultOptions, mockOptions } from '../../cli-options.js';
|
|
6
|
+
import { generateHtmlDiffPreviewFile } from '../../utils/generate-html-diff.js';
|
|
7
|
+
import { openHtml } from '../../utils/open-html.js';
|
|
8
|
+
import { setupContext } from '../../context.js';
|
|
9
|
+
export const cli = (y)=>{
|
|
10
|
+
y.command('run-block', 'Replay a block', (yargs)=>yargs.options({
|
|
11
|
+
...defaultOptions,
|
|
12
|
+
...mockOptions,
|
|
13
|
+
'output-path': {
|
|
14
|
+
desc: 'File path to print output',
|
|
15
|
+
string: true
|
|
16
|
+
},
|
|
17
|
+
html: {
|
|
18
|
+
desc: 'Generate html with storage diff'
|
|
19
|
+
},
|
|
20
|
+
open: {
|
|
21
|
+
desc: 'Open generated html'
|
|
22
|
+
}
|
|
23
|
+
}), async (argv)=>{
|
|
24
24
|
const context = await setupContext(argv, true);
|
|
25
25
|
const header = await context.chain.head.header;
|
|
26
26
|
const block = context.chain.head;
|
|
27
27
|
const parent = await block.parentBlock;
|
|
28
|
-
if (!parent)
|
|
29
|
-
throw Error('cant find parent block');
|
|
28
|
+
if (!parent) throw Error('cant find parent block');
|
|
30
29
|
const wasm = await parent.wasm;
|
|
31
|
-
const calls = [
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
const calls = [
|
|
31
|
+
[
|
|
32
|
+
'Core_initialize_block',
|
|
33
|
+
[
|
|
34
|
+
header.toHex()
|
|
35
|
+
]
|
|
36
|
+
]
|
|
37
|
+
];
|
|
38
|
+
for (const extrinsic of (await block.extrinsics)){
|
|
39
|
+
calls.push([
|
|
40
|
+
'BlockBuilder_apply_extrinsic',
|
|
41
|
+
[
|
|
42
|
+
extrinsic
|
|
43
|
+
]
|
|
44
|
+
]);
|
|
34
45
|
}
|
|
35
|
-
calls.push([
|
|
46
|
+
calls.push([
|
|
47
|
+
'BlockBuilder_finalize_block',
|
|
48
|
+
[]
|
|
49
|
+
]);
|
|
36
50
|
const result = await runTask({
|
|
37
51
|
wasm,
|
|
38
52
|
calls,
|
|
39
53
|
mockSignatureHost: false,
|
|
40
54
|
allowUnresolvedImports: false,
|
|
41
|
-
runtimeLogLevel: argv.runtimeLogLevel || 0
|
|
55
|
+
runtimeLogLevel: argv.runtimeLogLevel || 0
|
|
42
56
|
}, taskHandler(parent));
|
|
43
57
|
if ('Error' in result) {
|
|
44
58
|
throw new Error(result.Error);
|
|
@@ -50,17 +64,18 @@ export const cli = (y) => {
|
|
|
50
64
|
if (argv.open) {
|
|
51
65
|
openHtml(filePath);
|
|
52
66
|
}
|
|
53
|
-
}
|
|
54
|
-
else if (argv.outputPath) {
|
|
67
|
+
} else if (argv.outputPath) {
|
|
55
68
|
writeFileSync(argv.outputPath, JSON.stringify(result, null, 2));
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
69
|
+
} else {
|
|
70
|
+
console.dir(result, {
|
|
71
|
+
depth: null,
|
|
72
|
+
colors: false
|
|
73
|
+
});
|
|
59
74
|
}
|
|
60
75
|
process.exit(0);
|
|
61
76
|
});
|
|
62
77
|
};
|
|
63
|
-
const zHex = z.custom((val)
|
|
78
|
+
const zHex = z.custom((val)=>/^0x\w+$/.test(val));
|
|
64
79
|
const zHash = z.string().length(66).and(zHex);
|
|
65
80
|
const schema = z.object({
|
|
66
81
|
includeRaw: z.boolean().optional(),
|
|
@@ -69,8 +84,8 @@ const schema = z.object({
|
|
|
69
84
|
parent: zHash.optional(),
|
|
70
85
|
block: z.object({
|
|
71
86
|
header: z.any(),
|
|
72
|
-
extrinsics: z.array(zHex)
|
|
73
|
-
})
|
|
87
|
+
extrinsics: z.array(zHex)
|
|
88
|
+
})
|
|
74
89
|
});
|
|
75
90
|
export const name = 'runBlock';
|
|
76
91
|
/**
|
|
@@ -80,8 +95,7 @@ export const name = 'runBlock';
|
|
|
80
95
|
* NOTE: system.events and system.extrinsicData are excluded from storage diff to reduce size.
|
|
81
96
|
*
|
|
82
97
|
* This function is a dev rpc handler. Use `dev_runBlock` as the method name when calling it.
|
|
83
|
-
*/
|
|
84
|
-
export const rpc = async ({ chain }, [params]) => {
|
|
98
|
+
*/ export const rpc = async ({ chain }, [params])=>{
|
|
85
99
|
const { includeRaw, includeParsed, includeBlockDetails, parent, block } = schema.parse(params);
|
|
86
100
|
const includeRawStorage = includeRaw ?? true;
|
|
87
101
|
const parentBlock = await chain.getBlock(parent);
|
|
@@ -93,36 +107,41 @@ export const rpc = async ({ chain }, [params]) => {
|
|
|
93
107
|
const wasm = await parentBlock.wasm;
|
|
94
108
|
const meta = await parentBlock.meta;
|
|
95
109
|
const blockNumber = parentBlock.number + 1;
|
|
96
|
-
const hash = `0x${Math.round(Math.random() * 100000000)
|
|
97
|
-
.toString(16)
|
|
98
|
-
.padEnd(64, '0')}`;
|
|
110
|
+
const hash = `0x${Math.round(Math.random() * 100000000).toString(16).padEnd(64, '0')}`;
|
|
99
111
|
const newBlock = new Block(chain, blockNumber, hash, parentBlock, {
|
|
100
112
|
header,
|
|
101
113
|
extrinsics: [],
|
|
102
|
-
storage: parentBlock.storage
|
|
114
|
+
storage: parentBlock.storage
|
|
103
115
|
});
|
|
104
116
|
const resp = {
|
|
105
|
-
phases: []
|
|
117
|
+
phases: []
|
|
106
118
|
};
|
|
107
119
|
// exclude system events because it can be stupidly large and redudant
|
|
108
120
|
const systemEventsKey = compactHex(meta.query.system.events());
|
|
109
121
|
// large and not really useful
|
|
110
122
|
const systemExtrinsicDataKey = u8aToHex(meta.query.system.extrinsicData.keyPrefix());
|
|
111
|
-
const run = async (fn, args)
|
|
123
|
+
const run = async (fn, args)=>{
|
|
112
124
|
const result = await runTask({
|
|
113
125
|
wasm,
|
|
114
|
-
calls: [
|
|
126
|
+
calls: [
|
|
127
|
+
[
|
|
128
|
+
fn,
|
|
129
|
+
args
|
|
130
|
+
]
|
|
131
|
+
],
|
|
115
132
|
mockSignatureHost: false,
|
|
116
133
|
allowUnresolvedImports: false,
|
|
117
|
-
runtimeLogLevel: 5
|
|
134
|
+
runtimeLogLevel: 5
|
|
118
135
|
}, taskHandler(newBlock));
|
|
119
136
|
if ('Error' in result) {
|
|
120
137
|
throw new Error(result.Error);
|
|
121
138
|
}
|
|
122
|
-
const resp = {
|
|
139
|
+
const resp = {
|
|
140
|
+
storageDiff: []
|
|
141
|
+
};
|
|
123
142
|
const raw = result.Call.storageDiff;
|
|
124
143
|
newBlock.pushStorageLayer().setAll(raw);
|
|
125
|
-
for (const [key, value] of raw)
|
|
144
|
+
for (const [key, value] of raw){
|
|
126
145
|
if (key === systemEventsKey) {
|
|
127
146
|
continue;
|
|
128
147
|
}
|
|
@@ -131,7 +150,10 @@ export const rpc = async ({ chain }, [params]) => {
|
|
|
131
150
|
}
|
|
132
151
|
const obj = {};
|
|
133
152
|
if (includeRawStorage) {
|
|
134
|
-
obj.raw = {
|
|
153
|
+
obj.raw = {
|
|
154
|
+
key,
|
|
155
|
+
value
|
|
156
|
+
};
|
|
135
157
|
}
|
|
136
158
|
if (includeParsed) {
|
|
137
159
|
const decoded = decodeKeyValue(await newBlock.meta, newBlock, key, value, false);
|
|
@@ -140,7 +162,7 @@ export const rpc = async ({ chain }, [params]) => {
|
|
|
140
162
|
section: decoded.section,
|
|
141
163
|
method: decoded.method,
|
|
142
164
|
key: decoded.key,
|
|
143
|
-
value: decoded.value
|
|
165
|
+
value: decoded.value
|
|
144
166
|
};
|
|
145
167
|
}
|
|
146
168
|
}
|
|
@@ -149,42 +171,52 @@ export const rpc = async ({ chain }, [params]) => {
|
|
|
149
171
|
resp.logs = result.Call.runtimeLogs;
|
|
150
172
|
return resp;
|
|
151
173
|
};
|
|
152
|
-
const resInit = await run('Core_initialize_block', [
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
174
|
+
const resInit = await run('Core_initialize_block', [
|
|
175
|
+
header.toHex()
|
|
176
|
+
]);
|
|
177
|
+
resp.phases.push({
|
|
178
|
+
phase: 'Initialization',
|
|
179
|
+
...resInit
|
|
180
|
+
});
|
|
181
|
+
for (const extrinsic of block.extrinsics){
|
|
182
|
+
const res = await run('BlockBuilder_apply_extrinsic', [
|
|
183
|
+
extrinsic
|
|
184
|
+
]);
|
|
185
|
+
resp.phases.push({
|
|
186
|
+
phase: resp.phases.length - 1,
|
|
187
|
+
...res
|
|
188
|
+
});
|
|
157
189
|
}
|
|
158
190
|
const resFinalize = await run('BlockBuilder_finalize_block', []);
|
|
159
|
-
resp.phases.push({
|
|
191
|
+
resp.phases.push({
|
|
192
|
+
phase: 'Finalization',
|
|
193
|
+
...resFinalize
|
|
194
|
+
});
|
|
160
195
|
if (includeBlockDetails) {
|
|
161
196
|
const meta = await newBlock.meta;
|
|
162
197
|
const registry = await newBlock.registry;
|
|
163
198
|
const timestamp = await newBlock.read('u64', meta.query.timestamp.now);
|
|
164
199
|
const events = await newBlock.read('Vec<EventRecord>', meta.query.system.events);
|
|
165
|
-
const parsedEvents = events?.map((event)
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const extrinsics = block.extrinsics.map((extrinsic, idx)
|
|
200
|
+
const parsedEvents = events?.map((event)=>({
|
|
201
|
+
phase: event.phase.isApplyExtrinsic ? event.phase.asApplyExtrinsic.toNumber() : event.phase.toString(),
|
|
202
|
+
section: event.event.section,
|
|
203
|
+
method: event.event.method,
|
|
204
|
+
args: event.event.data.map((arg)=>arg.toJSON())
|
|
205
|
+
}));
|
|
206
|
+
const extrinsics = block.extrinsics.map((extrinsic, idx)=>{
|
|
172
207
|
const parsed = registry.createType('GenericExtrinsic', extrinsic);
|
|
173
|
-
const resultEvent = events?.find(({ event, phase })
|
|
174
|
-
(event.method === 'ExtrinsicSuccess' || event.method === 'ExtrinsicFailed') &&
|
|
175
|
-
phase.isApplyExtrinsic &&
|
|
176
|
-
phase.asApplyExtrinsic.eq(idx));
|
|
208
|
+
const resultEvent = events?.find(({ event, phase })=>event.section === 'system' && (event.method === 'ExtrinsicSuccess' || event.method === 'ExtrinsicFailed') && phase.isApplyExtrinsic && phase.asApplyExtrinsic.eq(idx));
|
|
177
209
|
return {
|
|
178
210
|
section: parsed.method.section,
|
|
179
211
|
method: parsed.method.method,
|
|
180
|
-
args: parsed.method.args.map((arg)
|
|
181
|
-
success: resultEvent?.event.method === 'ExtrinsicSuccess'
|
|
212
|
+
args: parsed.method.args.map((arg)=>arg.toJSON()),
|
|
213
|
+
success: resultEvent?.event.method === 'ExtrinsicSuccess'
|
|
182
214
|
};
|
|
183
215
|
});
|
|
184
216
|
resp.blockDetails = {
|
|
185
217
|
timestamp: timestamp?.toString(),
|
|
186
218
|
events: parsedEvents,
|
|
187
|
-
extrinsics
|
|
219
|
+
extrinsics
|
|
188
220
|
};
|
|
189
221
|
}
|
|
190
222
|
return resp;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BuildBlockMode, ResponseError } from '@acala-network/chopsticks-core';
|
|
2
|
-
import { defaultLogger } from '../../logger';
|
|
2
|
+
import { defaultLogger } from '../../logger.js';
|
|
3
3
|
/**
|
|
4
4
|
* Set a build block mode. See [BuildBlockMode](../core/enums/BuildBlockMode).
|
|
5
5
|
*
|
|
@@ -15,9 +15,10 @@ import { defaultLogger } from '../../logger';
|
|
|
15
15
|
* const ws = new WsProvider(`ws://localhost:8000`)
|
|
16
16
|
* await ws.send('dev_setBlockBuildMode', [BuildBlockMode.Instant])
|
|
17
17
|
* ```
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
*/ export const rpc = async (context, [mode])=>{
|
|
19
|
+
defaultLogger.debug({
|
|
20
|
+
mode
|
|
21
|
+
}, 'dev_setBlockBuildMode');
|
|
21
22
|
if (BuildBlockMode[mode] === undefined) {
|
|
22
23
|
throw new ResponseError(1, `Invalid mode ${mode}`);
|
|
23
24
|
}
|
|
@@ -13,14 +13,12 @@ import { ResponseError } from '@acala-network/chopsticks-core';
|
|
|
13
13
|
* const ws = new WsProvider(`ws://localhost:8000`)
|
|
14
14
|
* await ws.send('dev_setHead', [1000000])
|
|
15
15
|
* ```
|
|
16
|
-
*/
|
|
17
|
-
export const rpc = async (context, [hashOrNumber]) => {
|
|
16
|
+
*/ export const rpc = async (context, [hashOrNumber])=>{
|
|
18
17
|
let block;
|
|
19
18
|
if (typeof hashOrNumber === 'number') {
|
|
20
19
|
const blockNumber = hashOrNumber > 0 ? hashOrNumber : context.chain.head.number + hashOrNumber;
|
|
21
20
|
block = await context.chain.getBlockAt(blockNumber);
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
21
|
+
} else {
|
|
24
22
|
block = await context.chain.getBlock(hashOrNumber);
|
|
25
23
|
}
|
|
26
24
|
if (!block) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ResponseError } from '@acala-network/chopsticks-core';
|
|
2
|
-
import { defaultLogger } from '../../logger';
|
|
2
|
+
import { defaultLogger } from '../../logger.js';
|
|
3
3
|
/**
|
|
4
4
|
* Set runtime log level.
|
|
5
5
|
*
|
|
@@ -14,9 +14,10 @@ import { defaultLogger } from '../../logger';
|
|
|
14
14
|
* const ws = new WsProvider(`ws://localhost:8000`)
|
|
15
15
|
* await ws.send('dev_setRuntimeLogLevel', [1])
|
|
16
16
|
* ```
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
*/ export const rpc = async (context, [runtimeLogLevel])=>{
|
|
18
|
+
defaultLogger.debug({
|
|
19
|
+
runtimeLogLevel
|
|
20
|
+
}, 'dev_setRuntimeLogLevel');
|
|
20
21
|
if (typeof runtimeLogLevel !== 'number') {
|
|
21
22
|
throw new ResponseError(1, `Invalid runtimeLogLevel ${runtimeLogLevel}`);
|
|
22
23
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ResponseError, setStorage } from '@acala-network/chopsticks-core';
|
|
2
|
-
import { defaultLogger } from '../../logger';
|
|
2
|
+
import { defaultLogger } from '../../logger.js';
|
|
3
3
|
/**
|
|
4
4
|
* Set storage values.
|
|
5
5
|
*
|
|
@@ -24,15 +24,14 @@ import { defaultLogger } from '../../logger';
|
|
|
24
24
|
* }
|
|
25
25
|
* await ws.send('dev_setStorage', [storage])
|
|
26
26
|
* ```
|
|
27
|
-
*/
|
|
28
|
-
export const rpc = async (context, params) => {
|
|
27
|
+
*/ export const rpc = async (context, params)=>{
|
|
29
28
|
const [values, blockHash] = params;
|
|
30
|
-
const hash = await setStorage(context.chain, values, blockHash).catch((error)
|
|
29
|
+
const hash = await setStorage(context.chain, values, blockHash).catch((error)=>{
|
|
31
30
|
throw new ResponseError(1, error.toString());
|
|
32
31
|
});
|
|
33
32
|
defaultLogger.debug({
|
|
34
33
|
hash,
|
|
35
|
-
values
|
|
34
|
+
values
|
|
36
35
|
}, 'dev_setStorage');
|
|
37
36
|
return hash;
|
|
38
37
|
};
|
|
@@ -13,11 +13,9 @@ import { ResponseError, timeTravel } from '@acala-network/chopsticks-core';
|
|
|
13
13
|
* const ws = new WsProvider(`ws://localhost:8000`)
|
|
14
14
|
* await ws.send('dev_timeTravel', ['Jan 1, 2023'])
|
|
15
15
|
* ```
|
|
16
|
-
*/
|
|
17
|
-
export const rpc = async (context, [date]) => {
|
|
16
|
+
*/ export const rpc = async (context, [date])=>{
|
|
18
17
|
const timestamp = typeof date === 'string' ? Date.parse(date) : date;
|
|
19
|
-
if (Number.isNaN(timestamp))
|
|
20
|
-
throw new ResponseError(1, 'Invalid date');
|
|
18
|
+
if (Number.isNaN(timestamp)) throw new ResponseError(1, 'Invalid date');
|
|
21
19
|
await timeTravel(context.chain, timestamp);
|
|
22
20
|
return timestamp;
|
|
23
21
|
};
|
|
@@ -1,53 +1,56 @@
|
|
|
1
1
|
import { writeFileSync } from 'node:fs';
|
|
2
|
-
import { defaultOptions } from '../../cli-options';
|
|
3
|
-
import { generateHtmlDiffPreviewFile } from '../../utils/generate-html-diff';
|
|
4
|
-
import { openHtml } from '../../utils/open-html';
|
|
5
|
-
import { setupContext } from '../../context';
|
|
6
|
-
export const cli = (y)
|
|
7
|
-
y.command('try-runtime', 'Runs runtime upgrade', (yargs)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
2
|
+
import { defaultOptions } from '../../cli-options.js';
|
|
3
|
+
import { generateHtmlDiffPreviewFile } from '../../utils/generate-html-diff.js';
|
|
4
|
+
import { openHtml } from '../../utils/open-html.js';
|
|
5
|
+
import { setupContext } from '../../context.js';
|
|
6
|
+
export const cli = (y)=>{
|
|
7
|
+
y.command('try-runtime', 'Runs runtime upgrade', (yargs)=>yargs.options({
|
|
8
|
+
...defaultOptions,
|
|
9
|
+
'wasm-override': {
|
|
10
|
+
desc: 'Path to WASM built with feature `try-runtime` enabled',
|
|
11
|
+
string: true,
|
|
12
|
+
required: true
|
|
13
|
+
},
|
|
14
|
+
'output-path': {
|
|
15
|
+
desc: 'File path to print output',
|
|
16
|
+
string: true
|
|
17
|
+
},
|
|
18
|
+
html: {
|
|
19
|
+
desc: 'Generate html with storage diff',
|
|
20
|
+
boolean: true
|
|
21
|
+
},
|
|
22
|
+
open: {
|
|
23
|
+
desc: 'Open generated html',
|
|
24
|
+
boolean: true
|
|
25
|
+
}
|
|
26
|
+
}), async (argv)=>{
|
|
27
27
|
const context = await setupContext(argv);
|
|
28
28
|
const block = context.chain.head;
|
|
29
29
|
const registry = await block.registry;
|
|
30
30
|
registry.register({
|
|
31
31
|
UpgradeCheckSelect: {
|
|
32
32
|
_enum: {
|
|
33
|
-
None: null
|
|
34
|
-
}
|
|
35
|
-
}
|
|
33
|
+
None: null
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
36
|
});
|
|
37
37
|
const select_none = registry.createType('UpgradeCheckSelect', 'None');
|
|
38
|
-
const result = await block.call('TryRuntime_on_runtime_upgrade', [
|
|
38
|
+
const result = await block.call('TryRuntime_on_runtime_upgrade', [
|
|
39
|
+
select_none.toHex()
|
|
40
|
+
]);
|
|
39
41
|
if (argv.html) {
|
|
40
42
|
const filePath = await generateHtmlDiffPreviewFile(block, result.storageDiff, block.hash);
|
|
41
43
|
console.log(`Generated preview ${filePath}`);
|
|
42
44
|
if (argv.open) {
|
|
43
45
|
openHtml(filePath);
|
|
44
46
|
}
|
|
45
|
-
}
|
|
46
|
-
else if (argv.outputPath) {
|
|
47
|
+
} else if (argv.outputPath) {
|
|
47
48
|
writeFileSync(argv.outputPath, JSON.stringify(result, null, 2));
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
} else {
|
|
50
|
+
console.dir(result, {
|
|
51
|
+
depth: null,
|
|
52
|
+
colors: false
|
|
53
|
+
});
|
|
51
54
|
}
|
|
52
55
|
process.exit(0);
|
|
53
56
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { rpc as newBlock } from './new-block';
|
|
2
|
-
export { rpc as dryRun } from './dry-run';
|
|
3
|
-
export { rpc as setBlockBuildMode } from './set-block-build-mode';
|
|
4
|
-
export { rpc as setHead } from './set-head';
|
|
5
|
-
export { rpc as setRuntimeLogLevel } from './set-runtime-log-level';
|
|
6
|
-
export { rpc as setStorage } from './set-storage';
|
|
7
|
-
export { rpc as timeTravel } from './time-travel';
|
|
8
|
-
export { rpc as runBlock } from './run-block';
|
|
1
|
+
export { rpc as newBlock } from './new-block/index.js';
|
|
2
|
+
export { rpc as dryRun } from './dry-run/index.js';
|
|
3
|
+
export { rpc as setBlockBuildMode } from './set-block-build-mode/index.js';
|
|
4
|
+
export { rpc as setHead } from './set-head/index.js';
|
|
5
|
+
export { rpc as setRuntimeLogLevel } from './set-runtime-log-level/index.js';
|
|
6
|
+
export { rpc as setStorage } from './set-storage/index.js';
|
|
7
|
+
export { rpc as timeTravel } from './time-travel/index.js';
|
|
8
|
+
export { rpc as runBlock } from './run-block/index.js';
|
package/dist/esm/rpc/index.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import { ResponseError, logger, substrate
|
|
2
|
-
import { pluginHandlers } from '../plugins';
|
|
1
|
+
import { ResponseError, logger, substrate } from '@acala-network/chopsticks-core';
|
|
2
|
+
import { pluginHandlers } from '../plugins/index.js';
|
|
3
3
|
const allHandlers = {
|
|
4
4
|
...substrate,
|
|
5
|
-
rpc_methods: async ()
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
rpc_methods: async ()=>Promise.resolve({
|
|
6
|
+
version: 1,
|
|
7
|
+
methods: [
|
|
8
|
+
...Object.keys(allHandlers),
|
|
9
|
+
...Object.keys(pluginHandlers)
|
|
10
|
+
]
|
|
11
|
+
})
|
|
9
12
|
};
|
|
10
|
-
const getHandler = (method)
|
|
13
|
+
const getHandler = (method)=>{
|
|
11
14
|
const handler = allHandlers[method];
|
|
12
15
|
if (!handler) {
|
|
13
16
|
// no handler for this method, check if it's a plugin
|
|
@@ -15,12 +18,12 @@ const getHandler = (method) => {
|
|
|
15
18
|
}
|
|
16
19
|
return handler;
|
|
17
20
|
};
|
|
18
|
-
export const handler = (context)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
};
|
|
21
|
+
export const handler = (context)=>({ method, params }, subscriptionManager)=>{
|
|
22
|
+
logger.trace('Handling %s', method);
|
|
23
|
+
const handler = getHandler(method);
|
|
24
|
+
if (!handler) {
|
|
25
|
+
logger.warn('Method not found %s', method);
|
|
26
|
+
throw new ResponseError(-32601, `Method not found: ${method}`);
|
|
27
|
+
}
|
|
28
|
+
return handler(context, params, subscriptionManager);
|
|
29
|
+
};
|
package/dist/esm/schema/index.js
CHANGED
|
@@ -5,49 +5,62 @@ import { z } from 'zod';
|
|
|
5
5
|
import _ from 'lodash';
|
|
6
6
|
import axios from 'axios';
|
|
7
7
|
import yaml from 'js-yaml';
|
|
8
|
-
export const configSchema = z
|
|
9
|
-
.object({
|
|
8
|
+
export const configSchema = z.object({
|
|
10
9
|
port: z.number().optional(),
|
|
11
10
|
endpoint: z.string().optional(),
|
|
12
|
-
block: z.union([
|
|
11
|
+
block: z.union([
|
|
12
|
+
z.string().length(66).startsWith('0x'),
|
|
13
|
+
z.number(),
|
|
14
|
+
z.null()
|
|
15
|
+
]).optional(),
|
|
13
16
|
'build-block-mode': z.nativeEnum(BuildBlockMode).optional(),
|
|
14
17
|
'import-storage': z.any().optional(),
|
|
15
18
|
'mock-signature-host': z.boolean().optional(),
|
|
16
19
|
'max-memory-block-count': z.number().optional(),
|
|
17
20
|
db: z.string().optional(),
|
|
18
21
|
'wasm-override': z.string().optional(),
|
|
19
|
-
genesis: z.union([
|
|
22
|
+
genesis: z.union([
|
|
23
|
+
z.string(),
|
|
24
|
+
genesisSchema
|
|
25
|
+
]).optional(),
|
|
20
26
|
timestamp: z.number().optional(),
|
|
21
27
|
'registered-types': z.any().optional(),
|
|
22
28
|
'runtime-log-level': z.number().min(0).max(5).optional(),
|
|
23
29
|
'offchain-worker': z.boolean().optional(),
|
|
24
|
-
resume: z.union([
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
resume: z.union([
|
|
31
|
+
z.string().length(66).startsWith('0x'),
|
|
32
|
+
z.number(),
|
|
33
|
+
z.boolean()
|
|
34
|
+
]).optional()
|
|
35
|
+
}).strict();
|
|
27
36
|
const CONFIGS_BASE_URL = 'https://raw.githubusercontent.com/AcalaNetwork/chopsticks/master/configs/';
|
|
28
|
-
export const fetchConfig = async (path)
|
|
37
|
+
export const fetchConfig = async (path)=>{
|
|
29
38
|
let file;
|
|
30
39
|
if (isUrl(path)) {
|
|
31
|
-
file = await axios.get(path).then((x)
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
40
|
+
file = await axios.get(path).then((x)=>x.data);
|
|
41
|
+
} else {
|
|
34
42
|
try {
|
|
35
43
|
file = readFileSync(path, 'utf8');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
} catch (err) {
|
|
45
|
+
if (basename(path) === path && [
|
|
46
|
+
'',
|
|
47
|
+
'.yml',
|
|
48
|
+
'.yaml',
|
|
49
|
+
'.json'
|
|
50
|
+
].includes(extname(path))) {
|
|
39
51
|
if (extname(path) === '') {
|
|
40
52
|
path += '.yml';
|
|
41
53
|
}
|
|
42
54
|
const url = CONFIGS_BASE_URL + path;
|
|
43
55
|
defaultLogger.info(`Loading config file ${url}`);
|
|
44
|
-
file = await axios.get(url).then((x)
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
56
|
+
file = await axios.get(url).then((x)=>x.data);
|
|
57
|
+
} else {
|
|
47
58
|
throw err;
|
|
48
59
|
}
|
|
49
60
|
}
|
|
50
61
|
}
|
|
51
|
-
const config = yaml.load(_.template(file, {
|
|
62
|
+
const config = yaml.load(_.template(file, {
|
|
63
|
+
variable: 'env'
|
|
64
|
+
})(process.env));
|
|
52
65
|
return configSchema.parse(config);
|
|
53
66
|
};
|