@acala-network/chopsticks 0.3.0 → 0.3.2
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/README.md +8 -2
- package/dist/blockchain/block-builder.d.ts +7 -3
- package/dist/blockchain/block-builder.js +136 -15
- package/dist/blockchain/block.d.ts +1 -1
- package/dist/blockchain/index.d.ts +11 -1
- package/dist/blockchain/index.js +22 -0
- package/dist/blockchain/inherent/index.d.ts +2 -0
- package/dist/blockchain/inherent/index.js +5 -1
- package/dist/blockchain/inherent/parachain/babe-randomness.d.ts +7 -0
- package/dist/blockchain/inherent/parachain/babe-randomness.js +15 -0
- package/dist/blockchain/inherent/parachain/nimbus-author-inherent.d.ts +7 -0
- package/dist/blockchain/inherent/parachain/nimbus-author-inherent.js +15 -0
- package/dist/blockchain/txpool.js +1 -62
- package/dist/dry-run.d.ts +2 -0
- package/dist/dry-run.js +35 -0
- package/dist/executor.js +3 -3
- package/dist/index.js +51 -4
- package/dist/logger.d.ts +1 -3
- package/dist/logger.js +19 -13
- package/dist/rpc/dev.js +44 -2
- package/dist/rpc/substrate/system.js +4 -0
- package/dist/run-block.d.ts +1 -1
- package/dist/run-block.js +16 -5
- package/dist/setup.js +9 -2
- package/dist/utils/decoder.d.ts +17 -0
- package/dist/utils/decoder.js +105 -0
- package/dist/utils/generate-html-diff.d.ts +4 -0
- package/dist/utils/generate-html-diff.js +20 -0
- package/dist/utils/open-html.d.ts +1 -0
- package/dist/utils/open-html.js +9 -0
- package/dist/xcm/downward.d.ts +2 -0
- package/dist/xcm/downward.js +27 -0
- package/dist/xcm/horizontal.d.ts +2 -0
- package/dist/xcm/horizontal.js +36 -0
- package/dist/xcm/index.d.ts +7 -1
- package/dist/xcm/index.js +13 -55
- package/dist/xcm/upward.d.ts +2 -0
- package/dist/xcm/upward.js +39 -0
- package/package.json +6 -3
- package/dist/decode-key.d.ts +0 -2
- package/dist/decode-key.js +0 -24
package/dist/index.js
CHANGED
|
@@ -10,8 +10,10 @@ const yargs_1 = __importDefault(require("yargs"));
|
|
|
10
10
|
const txpool_1 = require("./blockchain/txpool");
|
|
11
11
|
const schema_1 = require("./schema");
|
|
12
12
|
const xcm_1 = require("./xcm");
|
|
13
|
-
const
|
|
13
|
+
const decoder_1 = require("./utils/decoder");
|
|
14
|
+
const dry_run_1 = require("./dry-run");
|
|
14
15
|
const run_block_1 = require("./run-block");
|
|
16
|
+
const setup_1 = require("./setup");
|
|
15
17
|
const setup_with_server_1 = require("./setup-with-server");
|
|
16
18
|
const processConfig = (path) => {
|
|
17
19
|
const configFile = (0, node_fs_1.readFileSync)(path, 'utf8');
|
|
@@ -31,7 +33,6 @@ const defaultOptions = {
|
|
|
31
33
|
},
|
|
32
34
|
block: {
|
|
33
35
|
desc: 'Block hash or block number. Default to latest block',
|
|
34
|
-
string: true,
|
|
35
36
|
},
|
|
36
37
|
'wasm-override': {
|
|
37
38
|
desc: 'Path to wasm override',
|
|
@@ -58,8 +59,42 @@ const defaultOptions = {
|
|
|
58
59
|
desc: 'File path to print output',
|
|
59
60
|
string: true,
|
|
60
61
|
},
|
|
62
|
+
html: {
|
|
63
|
+
desc: 'Generate html with storage diff',
|
|
64
|
+
},
|
|
65
|
+
open: {
|
|
66
|
+
desc: 'Open generated html',
|
|
67
|
+
},
|
|
61
68
|
}), async (argv) => {
|
|
62
69
|
await (0, run_block_1.runBlock)(processArgv(argv));
|
|
70
|
+
})
|
|
71
|
+
.command('dry-run', 'Dry run an extrinsic', (yargs) => yargs.options({
|
|
72
|
+
...defaultOptions,
|
|
73
|
+
extrinsic: {
|
|
74
|
+
desc: 'Extrinsic or call to dry run. If you pass call here then address is required to fake signature',
|
|
75
|
+
string: true,
|
|
76
|
+
required: true,
|
|
77
|
+
},
|
|
78
|
+
address: {
|
|
79
|
+
desc: 'Address to fake sign extrinsic',
|
|
80
|
+
string: true,
|
|
81
|
+
},
|
|
82
|
+
at: {
|
|
83
|
+
desc: 'Block hash to dry run',
|
|
84
|
+
string: true,
|
|
85
|
+
},
|
|
86
|
+
'output-path': {
|
|
87
|
+
desc: 'File path to print output',
|
|
88
|
+
string: true,
|
|
89
|
+
},
|
|
90
|
+
html: {
|
|
91
|
+
desc: 'Generate html with storage diff',
|
|
92
|
+
},
|
|
93
|
+
open: {
|
|
94
|
+
desc: 'Open generated html',
|
|
95
|
+
},
|
|
96
|
+
}), async (argv) => {
|
|
97
|
+
await (0, dry_run_1.dryRun)(processArgv(argv));
|
|
63
98
|
})
|
|
64
99
|
.command('dev', 'Dev mode', (yargs) => yargs.options({
|
|
65
100
|
...defaultOptions,
|
|
@@ -79,6 +114,10 @@ const defaultOptions = {
|
|
|
79
114
|
desc: 'Mock signature host so any signature starts with 0xdeadbeef and filled by 0xcd is considered valid',
|
|
80
115
|
boolean: true,
|
|
81
116
|
},
|
|
117
|
+
'allow-unresolved-imports': {
|
|
118
|
+
desc: 'Allow wasm unresolved imports',
|
|
119
|
+
boolean: true,
|
|
120
|
+
},
|
|
82
121
|
}), async (argv) => {
|
|
83
122
|
await (0, setup_with_server_1.setupWithServer)(processArgv(argv));
|
|
84
123
|
})
|
|
@@ -90,7 +129,15 @@ const defaultOptions = {
|
|
|
90
129
|
.options({
|
|
91
130
|
...defaultOptions,
|
|
92
131
|
}), async (argv) => {
|
|
93
|
-
await (0,
|
|
132
|
+
const context = await (0, setup_1.setup)(processArgv(argv));
|
|
133
|
+
const { storage, decodedKey } = await (0, decoder_1.decodeKey)(context.chain.head, argv.key);
|
|
134
|
+
if (storage && decodedKey) {
|
|
135
|
+
console.log(`${storage.section}.${storage.method}`, decodedKey.args.map((x) => JSON.stringify(x.toHuman())).join(', '));
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
console.log('Unknown');
|
|
139
|
+
}
|
|
140
|
+
process.exit(0);
|
|
94
141
|
})
|
|
95
142
|
.command('xcm', 'XCM setup with relaychain and parachains', (yargs) => yargs.options({
|
|
96
143
|
relaychain: {
|
|
@@ -115,7 +162,7 @@ const defaultOptions = {
|
|
|
115
162
|
if (argv.relaychain) {
|
|
116
163
|
const { chain: relaychain } = await (0, setup_with_server_1.setupWithServer)(processConfig(argv.relaychain));
|
|
117
164
|
for (const parachain of parachains) {
|
|
118
|
-
await (0, xcm_1.
|
|
165
|
+
await (0, xcm_1.connectVertical)(relaychain, parachain);
|
|
119
166
|
}
|
|
120
167
|
}
|
|
121
168
|
})
|
package/dist/logger.d.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { HexString } from '@polkadot/util/types';
|
|
2
1
|
export declare const defaultLogger: import("pino").Logger<{
|
|
3
2
|
level: string;
|
|
4
3
|
transport: {
|
|
5
4
|
target: string;
|
|
6
5
|
};
|
|
7
6
|
}>;
|
|
8
|
-
export declare const truncate: (
|
|
9
|
-
export declare const truncateStorageDiff: (diff: [HexString, HexString | null][]) => [HexString, string | null][];
|
|
7
|
+
export declare const truncate: (val: any) => any;
|
package/dist/logger.js
CHANGED
|
@@ -3,7 +3,7 @@ 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.
|
|
6
|
+
exports.truncate = exports.defaultLogger = void 0;
|
|
7
7
|
const pino_1 = __importDefault(require("pino"));
|
|
8
8
|
exports.defaultLogger = (0, pino_1.default)({
|
|
9
9
|
level: process.env.LOG_LEVEL || 'info',
|
|
@@ -11,19 +11,25 @@ exports.defaultLogger = (0, pino_1.default)({
|
|
|
11
11
|
target: 'pino-pretty',
|
|
12
12
|
},
|
|
13
13
|
});
|
|
14
|
-
const truncate = (
|
|
15
|
-
if (
|
|
16
|
-
return
|
|
14
|
+
const truncate = (val) => {
|
|
15
|
+
if (val == null) {
|
|
16
|
+
return val;
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
switch (typeof val) {
|
|
19
|
+
case 'string':
|
|
20
|
+
if (val.length > 66) {
|
|
21
|
+
return val.slice(0, 34) + '…' + val.slice(-32);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
return val;
|
|
25
|
+
}
|
|
26
|
+
case 'object':
|
|
27
|
+
if (Array.isArray(val)) {
|
|
28
|
+
return val.map(exports.truncate);
|
|
29
|
+
}
|
|
30
|
+
return Object.fromEntries(Object.entries(val).map(([k, v]) => [k, (0, exports.truncate)(v)]));
|
|
31
|
+
default:
|
|
32
|
+
return val;
|
|
23
33
|
}
|
|
24
34
|
};
|
|
25
35
|
exports.truncate = truncate;
|
|
26
|
-
const truncateStorageDiff = (diff) => {
|
|
27
|
-
return diff.map(([key, value]) => [key, (0, exports.truncate)(value)]);
|
|
28
|
-
};
|
|
29
|
-
exports.truncateStorageDiff = truncateStorageDiff;
|
package/dist/rpc/dev.js
CHANGED
|
@@ -2,18 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const shared_1 = require("./shared");
|
|
4
4
|
const set_storage_1 = require("../utils/set-storage");
|
|
5
|
+
const decoder_1 = require("../utils/decoder");
|
|
5
6
|
const logger_1 = require("../logger");
|
|
7
|
+
const generate_html_diff_1 = require("../utils/generate-html-diff");
|
|
6
8
|
const time_travel_1 = require("../utils/time-travel");
|
|
7
9
|
const logger = logger_1.defaultLogger.child({ name: 'rpc-dev' });
|
|
8
10
|
const handlers = {
|
|
9
11
|
dev_newBlock: async (context, [param]) => {
|
|
10
|
-
const { count, to } = param || {};
|
|
12
|
+
const { count, to, hrmp } = param || {};
|
|
11
13
|
const now = context.chain.head.number;
|
|
12
14
|
const diff = to ? to - now : count;
|
|
13
15
|
const finalCount = diff > 0 ? diff : 1;
|
|
14
16
|
let finalHash;
|
|
15
17
|
for (let i = 0; i < finalCount; i++) {
|
|
16
|
-
const block = await context.chain.newBlock().catch((error) => {
|
|
18
|
+
const block = await context.chain.newBlock({ inherent: { horizontalMessages: hrmp } }).catch((error) => {
|
|
17
19
|
throw new shared_1.ResponseError(1, error.toString());
|
|
18
20
|
});
|
|
19
21
|
logger.debug({ hash: block.hash }, 'dev_newBlock');
|
|
@@ -39,5 +41,45 @@ const handlers = {
|
|
|
39
41
|
await (0, time_travel_1.timeTravel)(context.chain, timestamp);
|
|
40
42
|
return timestamp;
|
|
41
43
|
},
|
|
44
|
+
dev_dryRun: async (context, [{ html, extrinsic, hrmp, raw }]) => {
|
|
45
|
+
const dryRun = async () => {
|
|
46
|
+
if (extrinsic) {
|
|
47
|
+
const { outcome, storageDiff } = await context.chain.dryRunExtrinsic(extrinsic);
|
|
48
|
+
if (outcome.isErr) {
|
|
49
|
+
throw new Error(outcome.asErr.toString());
|
|
50
|
+
}
|
|
51
|
+
return storageDiff;
|
|
52
|
+
}
|
|
53
|
+
return context.chain.dryRunHrmp(hrmp);
|
|
54
|
+
};
|
|
55
|
+
const storageDiff = await dryRun();
|
|
56
|
+
if (html) {
|
|
57
|
+
return (0, generate_html_diff_1.generateHtmlDiff)(context.chain.head, storageDiff);
|
|
58
|
+
}
|
|
59
|
+
if (raw) {
|
|
60
|
+
return storageDiff;
|
|
61
|
+
}
|
|
62
|
+
const [oldData, newData, delta] = await (0, decoder_1.decodeStorageDiff)(context.chain.head, storageDiff);
|
|
63
|
+
return {
|
|
64
|
+
old: oldData,
|
|
65
|
+
new: newData,
|
|
66
|
+
delta,
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
dev_setHead: async (context, [hashOrNumber]) => {
|
|
70
|
+
let block;
|
|
71
|
+
if (typeof hashOrNumber === 'number') {
|
|
72
|
+
const blockNumber = hashOrNumber > 0 ? hashOrNumber : context.chain.head.number + hashOrNumber;
|
|
73
|
+
block = await context.chain.getBlockAt(blockNumber);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
block = await context.chain.getBlock(hashOrNumber);
|
|
77
|
+
}
|
|
78
|
+
if (!block) {
|
|
79
|
+
throw new shared_1.ResponseError(1, `Block not found ${hashOrNumber}`);
|
|
80
|
+
}
|
|
81
|
+
await context.chain.setHead(block);
|
|
82
|
+
return block.hash;
|
|
83
|
+
},
|
|
42
84
|
};
|
|
43
85
|
exports.default = handlers;
|
package/dist/run-block.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Config } from './schema';
|
|
2
|
-
export declare const runBlock: (argv: Config) => Promise<
|
|
2
|
+
export declare const runBlock: (argv: Config) => Promise<never>;
|
package/dist/run-block.js
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.runBlock = void 0;
|
|
4
4
|
const node_fs_1 = require("node:fs");
|
|
5
|
+
const generate_html_diff_1 = require("./utils/generate-html-diff");
|
|
6
|
+
const open_html_1 = require("./utils/open-html");
|
|
5
7
|
const executor_1 = require("./executor");
|
|
6
|
-
const
|
|
8
|
+
const setup_1 = require("./setup");
|
|
7
9
|
const runBlock = async (argv) => {
|
|
8
|
-
const context = await (0,
|
|
10
|
+
const context = await (0, setup_1.setup)(argv);
|
|
9
11
|
const header = await context.chain.head.header;
|
|
10
12
|
const wasm = await context.chain.head.wasm;
|
|
11
13
|
const block = context.chain.head;
|
|
@@ -24,13 +26,22 @@ const runBlock = async (argv) => {
|
|
|
24
26
|
mockSignatureHost: false,
|
|
25
27
|
allowUnresolvedImports: false,
|
|
26
28
|
}, (0, executor_1.taskHandler)(parent));
|
|
27
|
-
if (
|
|
29
|
+
if (result.Error) {
|
|
30
|
+
throw new Error(result.Error);
|
|
31
|
+
}
|
|
32
|
+
if (argv['html']) {
|
|
33
|
+
const filePath = await (0, generate_html_diff_1.generateHtmlDiffPreviewFile)(parent, result.Call.storageDiff, block.hash);
|
|
34
|
+
console.log(`Generated preview ${filePath}`);
|
|
35
|
+
if (argv['open']) {
|
|
36
|
+
(0, open_html_1.openHtml)(filePath);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (argv['output-path']) {
|
|
28
40
|
(0, node_fs_1.writeFileSync)(argv['output-path'], JSON.stringify(result, null, 2));
|
|
29
41
|
}
|
|
30
42
|
else {
|
|
31
43
|
console.dir(result, { depth: null, colors: false });
|
|
32
44
|
}
|
|
33
|
-
|
|
34
|
-
setTimeout(() => process.exit(0), 50);
|
|
45
|
+
process.exit(0);
|
|
35
46
|
};
|
|
36
47
|
exports.runBlock = runBlock;
|
package/dist/setup.js
CHANGED
|
@@ -30,7 +30,7 @@ const setup = async (argv) => {
|
|
|
30
30
|
if (argv.block == null) {
|
|
31
31
|
blockHash = await api.getBlockHash();
|
|
32
32
|
}
|
|
33
|
-
else if (Number.isInteger(argv.block)) {
|
|
33
|
+
else if (Number.isInteger(+argv.block)) {
|
|
34
34
|
blockHash = await api.getBlockHash(Number(argv.block));
|
|
35
35
|
}
|
|
36
36
|
else {
|
|
@@ -42,7 +42,12 @@ const setup = async (argv) => {
|
|
|
42
42
|
db = await (0, db_1.openDb)(argv.db);
|
|
43
43
|
}
|
|
44
44
|
const header = await api.getHeader(blockHash);
|
|
45
|
-
const inherents = new inherent_1.InherentProviders(new inherent_1.SetTimestamp(), [
|
|
45
|
+
const inherents = new inherent_1.InherentProviders(new inherent_1.SetTimestamp(), [
|
|
46
|
+
new inherent_1.SetValidationData(),
|
|
47
|
+
new inherent_1.ParaInherentEnter(),
|
|
48
|
+
new inherent_1.SetNimbusAuthorInherent(),
|
|
49
|
+
new inherent_1.SetBabeRandomness(),
|
|
50
|
+
]);
|
|
46
51
|
const chain = new blockchain_1.Blockchain({
|
|
47
52
|
api,
|
|
48
53
|
buildBlockMode: argv['build-block-mode'],
|
|
@@ -52,6 +57,8 @@ const setup = async (argv) => {
|
|
|
52
57
|
hash: blockHash,
|
|
53
58
|
number: Number(header.number),
|
|
54
59
|
},
|
|
60
|
+
mockSignatureHost: argv['mock-signature-host'],
|
|
61
|
+
allowUnresolvedImports: argv['allow-unresolved-imports'],
|
|
55
62
|
});
|
|
56
63
|
if (argv.timestamp)
|
|
57
64
|
await (0, time_travel_1.timeTravel)(chain, argv.timestamp);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import '@polkadot/types-codec';
|
|
2
|
+
import { Block } from '../blockchain/block';
|
|
3
|
+
import { HexString } from '@polkadot/util/types';
|
|
4
|
+
import { StorageEntry } from '@polkadot/types/primitive/types';
|
|
5
|
+
import { StorageKey } from '@polkadot/types';
|
|
6
|
+
export declare const decodeKey: (block: Block, key: HexString) => Promise<{
|
|
7
|
+
storage?: StorageEntry | undefined;
|
|
8
|
+
decodedKey?: StorageKey<import("@polkadot/types-codec/types").AnyTuple> | undefined;
|
|
9
|
+
}>;
|
|
10
|
+
export declare const decodeKeyValue: (block: Block, key: HexString, value?: HexString | null) => Promise<{
|
|
11
|
+
[x: string]: `0x${string}` | null | undefined;
|
|
12
|
+
} | {
|
|
13
|
+
[x: string]: {
|
|
14
|
+
[x: string]: import("@polkadot/types-codec/types").AnyJson;
|
|
15
|
+
};
|
|
16
|
+
}>;
|
|
17
|
+
export declare const decodeStorageDiff: (block: Block, diff: [HexString, HexString | null][]) => Promise<({} | undefined)[]>;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.decodeStorageDiff = exports.decodeKeyValue = exports.decodeKey = void 0;
|
|
7
|
+
require("@polkadot/types-codec");
|
|
8
|
+
const util_crypto_1 = require("@polkadot/util-crypto");
|
|
9
|
+
const jsondiffpatch_1 = require("jsondiffpatch");
|
|
10
|
+
const util_1 = require("@polkadot/util");
|
|
11
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
12
|
+
const diffPatcher = (0, jsondiffpatch_1.create)({
|
|
13
|
+
array: { detectMove: false },
|
|
14
|
+
textDiff: { minLength: Number.MAX_VALUE }, // skip text diff
|
|
15
|
+
});
|
|
16
|
+
const _CACHE = {};
|
|
17
|
+
const getCache = (uid) => {
|
|
18
|
+
if (!_CACHE[uid]) {
|
|
19
|
+
_CACHE[uid] = {};
|
|
20
|
+
}
|
|
21
|
+
return _CACHE[uid];
|
|
22
|
+
};
|
|
23
|
+
const getStorageEntry = async (block, key) => {
|
|
24
|
+
const cache = getCache(block.chain.uid);
|
|
25
|
+
for (const [prefix, storageEntry] of Object.entries(cache)) {
|
|
26
|
+
if (key.startsWith(prefix))
|
|
27
|
+
return storageEntry;
|
|
28
|
+
}
|
|
29
|
+
const meta = await block.meta;
|
|
30
|
+
for (const module of Object.values(meta.query)) {
|
|
31
|
+
for (const storage of Object.values(module)) {
|
|
32
|
+
const keyPrefix = (0, util_1.u8aToHex)(storage.keyPrefix());
|
|
33
|
+
if (key.startsWith(keyPrefix)) {
|
|
34
|
+
cache[keyPrefix] = storage;
|
|
35
|
+
return storage;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
throw new Error(`Cannot find key ${key}`);
|
|
40
|
+
};
|
|
41
|
+
const decodeKey = async (block, key) => {
|
|
42
|
+
const meta = await block.meta;
|
|
43
|
+
const storage = await getStorageEntry(block, key).catch(() => undefined);
|
|
44
|
+
const decodedKey = meta.registry.createType('StorageKey', key);
|
|
45
|
+
if (storage) {
|
|
46
|
+
decodedKey.setMeta(storage.meta);
|
|
47
|
+
return { storage, decodedKey };
|
|
48
|
+
}
|
|
49
|
+
return {};
|
|
50
|
+
};
|
|
51
|
+
exports.decodeKey = decodeKey;
|
|
52
|
+
const decodeKeyValue = async (block, key, value) => {
|
|
53
|
+
const meta = await block.meta;
|
|
54
|
+
const { storage, decodedKey } = await (0, exports.decodeKey)(block, key);
|
|
55
|
+
if (!storage || !decodedKey) {
|
|
56
|
+
return { [key]: value };
|
|
57
|
+
}
|
|
58
|
+
const decodeValue = () => {
|
|
59
|
+
if (!value)
|
|
60
|
+
return null;
|
|
61
|
+
if (storage.section === 'substrate' && storage.method === 'code') {
|
|
62
|
+
return `:code blake2_256 ${(0, util_crypto_1.blake2AsHex)(value, 256)} (${(0, util_1.hexToU8a)(value).length} bytes)`;
|
|
63
|
+
}
|
|
64
|
+
return meta.registry.createType(decodedKey.outputType, (0, util_1.hexToU8a)(value)).toHuman();
|
|
65
|
+
};
|
|
66
|
+
switch (decodedKey.args.length) {
|
|
67
|
+
case 2: {
|
|
68
|
+
return {
|
|
69
|
+
[storage.section]: {
|
|
70
|
+
[storage.method]: {
|
|
71
|
+
[decodedKey.args[0].toString()]: {
|
|
72
|
+
[decodedKey.args[1].toString()]: decodeValue(),
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
case 1: {
|
|
79
|
+
return {
|
|
80
|
+
[storage.section]: {
|
|
81
|
+
[storage.method]: {
|
|
82
|
+
[decodedKey.args[0].toString()]: decodeValue(),
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
default:
|
|
88
|
+
return {
|
|
89
|
+
[storage.section]: {
|
|
90
|
+
[storage.method]: decodeValue(),
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
exports.decodeKeyValue = decodeKeyValue;
|
|
96
|
+
const decodeStorageDiff = async (block, diff) => {
|
|
97
|
+
const oldState = {};
|
|
98
|
+
const newState = {};
|
|
99
|
+
for (const [key, value] of diff) {
|
|
100
|
+
lodash_1.default.merge(oldState, await (0, exports.decodeKeyValue)(block, key, (await block.get(key))));
|
|
101
|
+
lodash_1.default.merge(newState, await (0, exports.decodeKeyValue)(block, key, value));
|
|
102
|
+
}
|
|
103
|
+
return [oldState, newState, diffPatcher.diff(oldState, newState)];
|
|
104
|
+
};
|
|
105
|
+
exports.decodeStorageDiff = decodeStorageDiff;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Block } from '../blockchain/block';
|
|
2
|
+
import { HexString } from '@polkadot/util/types';
|
|
3
|
+
export declare const generateHtmlDiff: (block: Block, diff: [HexString, HexString | null][]) => Promise<string>;
|
|
4
|
+
export declare const generateHtmlDiffPreviewFile: (block: Block, diff: [HexString, HexString | null][], filename: string) => Promise<string>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateHtmlDiffPreviewFile = exports.generateHtmlDiff = void 0;
|
|
4
|
+
const decoder_1 = require("./decoder");
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const lodash_1 = require("lodash");
|
|
7
|
+
const generateHtmlDiff = async (block, diff) => {
|
|
8
|
+
const [left, _right, delta] = await (0, decoder_1.decodeStorageDiff)(block, diff);
|
|
9
|
+
const htmlTemplate = (0, node_fs_1.readFileSync)('./template/diff.html', 'utf-8');
|
|
10
|
+
return (0, lodash_1.template)(htmlTemplate)({ left: JSON.stringify(left), delta: JSON.stringify(delta) });
|
|
11
|
+
};
|
|
12
|
+
exports.generateHtmlDiff = generateHtmlDiff;
|
|
13
|
+
const generateHtmlDiffPreviewFile = async (block, diff, filename) => {
|
|
14
|
+
const html = await (0, exports.generateHtmlDiff)(block, diff);
|
|
15
|
+
(0, node_fs_1.mkdirSync)('./preview', { recursive: true });
|
|
16
|
+
const filePath = `./preview/${filename}.html`;
|
|
17
|
+
(0, node_fs_1.writeFileSync)(filePath, html);
|
|
18
|
+
return filePath;
|
|
19
|
+
};
|
|
20
|
+
exports.generateHtmlDiffPreviewFile = generateHtmlDiffPreviewFile;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const openHtml: (filePath: string) => void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.openHtml = void 0;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
const openHtml = (filePath) => {
|
|
6
|
+
const start = process.platform == 'darwin' ? 'open' : process.platform == 'win32' ? 'start' : 'xdg-open';
|
|
7
|
+
(0, node_child_process_1.execSync)(start + ' ' + filePath);
|
|
8
|
+
};
|
|
9
|
+
exports.openHtml = openHtml;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.connectDownward = void 0;
|
|
4
|
+
const util_1 = require("@polkadot/util");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
const _1 = require(".");
|
|
7
|
+
const set_storage_1 = require("../utils/set-storage");
|
|
8
|
+
const connectDownward = async (relaychain, parachain) => {
|
|
9
|
+
const meta = await relaychain.head.meta;
|
|
10
|
+
const paraId = await (0, utils_1.getParaId)(parachain);
|
|
11
|
+
const downwardMessageQueuesKey = (0, utils_1.compactHex)(meta.query.dmp.downwardMessageQueues(paraId));
|
|
12
|
+
await relaychain.headState.subscribeStorage([downwardMessageQueuesKey], async (head, pairs) => {
|
|
13
|
+
const value = pairs[0][1];
|
|
14
|
+
if (!value)
|
|
15
|
+
return;
|
|
16
|
+
const meta = await relaychain.head.meta;
|
|
17
|
+
const downwardMessageQueuesKey = (0, utils_1.compactHex)(meta.query.dmp.downwardMessageQueues(paraId));
|
|
18
|
+
// clear relaychain message queue
|
|
19
|
+
await (0, set_storage_1.setStorage)(relaychain, [[downwardMessageQueuesKey, null]], head.hash);
|
|
20
|
+
const downwardMessages = meta.registry
|
|
21
|
+
.createType('Vec<PolkadotCorePrimitivesInboundDownwardMessage>', (0, util_1.hexToU8a)(value))
|
|
22
|
+
.toJSON();
|
|
23
|
+
_1.logger.debug({ downwardMessages }, 'downward_message');
|
|
24
|
+
await parachain.newBlock({ inherent: { downwardMessages } });
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
exports.connectDownward = connectDownward;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.connectHorizontal = void 0;
|
|
4
|
+
const util_1 = require("@polkadot/util");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
const _1 = require(".");
|
|
7
|
+
const set_storage_1 = require("../utils/set-storage");
|
|
8
|
+
const connectHorizontal = async (parachains) => {
|
|
9
|
+
for (const [id, chain] of Object.entries(parachains)) {
|
|
10
|
+
const meta = await chain.head.meta;
|
|
11
|
+
const hrmpOutboundMessagesKey = (0, utils_1.compactHex)(meta.query.parachainSystem.hrmpOutboundMessages());
|
|
12
|
+
await chain.headState.subscribeStorage([hrmpOutboundMessagesKey], async (head, pairs) => {
|
|
13
|
+
const value = pairs[0][1];
|
|
14
|
+
if (!value)
|
|
15
|
+
return;
|
|
16
|
+
const meta = await chain.head.meta;
|
|
17
|
+
const hrmpOutboundMessagesKey = (0, utils_1.compactHex)(meta.query.parachainSystem.hrmpOutboundMessages());
|
|
18
|
+
// clear sender message queue
|
|
19
|
+
await (0, set_storage_1.setStorage)(chain, [[hrmpOutboundMessagesKey, null]], head.hash);
|
|
20
|
+
const outboundHrmpMessage = meta.registry
|
|
21
|
+
.createType('Vec<PolkadotCorePrimitivesOutboundHrmpMessage>', (0, util_1.hexToU8a)(value))
|
|
22
|
+
.toJSON();
|
|
23
|
+
_1.logger.info({ outboundHrmpMessage }, 'outboundHrmpMessage');
|
|
24
|
+
for (const { recipient, data } of outboundHrmpMessage) {
|
|
25
|
+
const horizontalMessages = {
|
|
26
|
+
[Number(id)]: [{ sentAt: chain.head.number, data }],
|
|
27
|
+
};
|
|
28
|
+
const receiver = parachains[recipient];
|
|
29
|
+
if (receiver) {
|
|
30
|
+
await receiver.newBlock({ inherent: { horizontalMessages } });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
exports.connectHorizontal = connectHorizontal;
|
package/dist/xcm/index.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import { Blockchain } from '../blockchain';
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const logger: import("pino").default.Logger<{
|
|
3
|
+
level: string;
|
|
4
|
+
transport: {
|
|
5
|
+
target: string;
|
|
6
|
+
};
|
|
7
|
+
} & import("pino").default.ChildLoggerOptions>;
|
|
8
|
+
export declare const connectVertical: (relaychain: Blockchain, parachain: Blockchain) => Promise<void>;
|
|
3
9
|
export declare const connectParachains: (parachains: Blockchain[]) => Promise<void>;
|
package/dist/xcm/index.js
CHANGED
|
@@ -1,67 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.connectParachains = exports.
|
|
4
|
-
const
|
|
5
|
-
const
|
|
3
|
+
exports.connectParachains = exports.connectVertical = exports.logger = void 0;
|
|
4
|
+
const downward_1 = require("./downward");
|
|
5
|
+
const horizontal_1 = require("./horizontal");
|
|
6
|
+
const upward_1 = require("./upward");
|
|
6
7
|
const logger_1 = require("../logger");
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
await relaychain.headState.subscribeStorage([downwardMessageQueuesKey], async (head, pairs) => {
|
|
14
|
-
const value = pairs[0][1];
|
|
15
|
-
if (!value)
|
|
16
|
-
return;
|
|
17
|
-
const meta = await relaychain.head.meta;
|
|
18
|
-
const downwardMessageQueuesKey = (0, utils_1.compactHex)(meta.query.dmp.downwardMessageQueues(paraId));
|
|
19
|
-
// clear relaychain message queue
|
|
20
|
-
await (0, set_storage_1.setStorage)(relaychain, [[downwardMessageQueuesKey, null]], head.hash);
|
|
21
|
-
const downwardMessages = meta.registry
|
|
22
|
-
.createType('Vec<PolkadotCorePrimitivesInboundDownwardMessage>', (0, util_1.hexToU8a)(value))
|
|
23
|
-
.toJSON();
|
|
24
|
-
logger.debug({ downwardMessages }, 'downward_message');
|
|
25
|
-
await parachain.newBlock({ inherent: { downwardMessages } });
|
|
26
|
-
});
|
|
27
|
-
logger.info(`Connected relaychain '${await relaychain.api.getSystemChain()}' with parachain '${await parachain.api.getSystemChain()}'`);
|
|
8
|
+
const utils_1 = require("../utils");
|
|
9
|
+
exports.logger = logger_1.defaultLogger.child({ name: 'xcm' });
|
|
10
|
+
const connectVertical = async (relaychain, parachain) => {
|
|
11
|
+
await (0, downward_1.connectDownward)(relaychain, parachain);
|
|
12
|
+
await (0, upward_1.connectUpward)(parachain, relaychain);
|
|
13
|
+
exports.logger.info(`Connected relaychain '${await relaychain.api.getSystemChain()}' with parachain '${await parachain.api.getSystemChain()}'`);
|
|
28
14
|
};
|
|
29
|
-
exports.
|
|
15
|
+
exports.connectVertical = connectVertical;
|
|
30
16
|
const connectParachains = async (parachains) => {
|
|
31
17
|
const list = {};
|
|
32
18
|
for (const chain of parachains) {
|
|
33
19
|
const paraId = await (0, utils_1.getParaId)(chain);
|
|
34
20
|
list[paraId.toNumber()] = chain;
|
|
35
21
|
}
|
|
36
|
-
await connectHorizontal(list);
|
|
37
|
-
logger.info(
|
|
22
|
+
await (0, horizontal_1.connectHorizontal)(list);
|
|
23
|
+
exports.logger.info(`Connected parachains [${Object.keys(list)}]`);
|
|
38
24
|
};
|
|
39
25
|
exports.connectParachains = connectParachains;
|
|
40
|
-
const connectHorizontal = async (parachains) => {
|
|
41
|
-
for (const [id, chain] of Object.entries(parachains)) {
|
|
42
|
-
const meta = await chain.head.meta;
|
|
43
|
-
const hrmpOutboundMessagesKey = (0, utils_1.compactHex)(meta.query.parachainSystem.hrmpOutboundMessages());
|
|
44
|
-
await chain.headState.subscribeStorage([hrmpOutboundMessagesKey], async (head, pairs) => {
|
|
45
|
-
const value = pairs[0][1];
|
|
46
|
-
if (!value)
|
|
47
|
-
return;
|
|
48
|
-
const meta = await chain.head.meta;
|
|
49
|
-
const hrmpOutboundMessagesKey = (0, utils_1.compactHex)(meta.query.parachainSystem.hrmpOutboundMessages());
|
|
50
|
-
// clear sender message queue
|
|
51
|
-
await (0, set_storage_1.setStorage)(chain, [[hrmpOutboundMessagesKey, null]], head.hash);
|
|
52
|
-
const outboundHrmpMessage = meta.registry
|
|
53
|
-
.createType('Vec<PolkadotCorePrimitivesOutboundHrmpMessage>', (0, util_1.hexToU8a)(value))
|
|
54
|
-
.toJSON();
|
|
55
|
-
logger.info({ outboundHrmpMessage }, 'outboundHrmpMessage');
|
|
56
|
-
for (const { recipient, data } of outboundHrmpMessage) {
|
|
57
|
-
const horizontalMessages = {
|
|
58
|
-
[Number(id)]: [{ sentAt: chain.head.number, data }],
|
|
59
|
-
};
|
|
60
|
-
const receiver = parachains[recipient];
|
|
61
|
-
if (receiver) {
|
|
62
|
-
await receiver.newBlock({ inherent: { horizontalMessages } });
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
};
|