@acala-network/chopsticks 0.2.0 → 0.2.1
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 -1
- package/dist/blockchain/block.d.ts +1 -0
- package/dist/blockchain/block.js +44 -1
- package/dist/blockchain/inherents.d.ts +4 -4
- package/dist/blockchain/inherents.js +26 -8
- package/dist/blockchain/txpool.js +4 -13
- package/dist/executor.d.ts +6 -1
- package/dist/executor.js +23 -6
- package/dist/executor.test.js +86 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.js +93 -59
- package/dist/rpc/substrate/author.js +1 -0
- package/dist/schema/index.d.ts +5 -2
- package/dist/schema/index.js +1 -0
- package/dist/task.d.ts +2 -2
- package/dist/task.js +1 -0
- package/dist/utils/proof.d.ts +7 -0
- package/dist/utils/proof.js +37 -0
- package/dist/utils/set-storage.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Create parallel reality of your Substrate network.
|
|
4
4
|
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
Fork Acala mainnet: `yarn dlx @acala-network/chopsticks dev --endpoint=wss://acala-rpc-2.aca-api.network/ws`
|
|
8
|
+
|
|
9
|
+
It is recommended to use config file. You can check [configs](configs/) for examples.
|
|
10
|
+
|
|
11
|
+
You can run a test node with config with `yarn dlx @acala-network/chopsticks dev --config=<config_file_path>`
|
|
12
|
+
|
|
5
13
|
## Install
|
|
6
14
|
|
|
7
15
|
Make sure you have setup Rust environment (>= 1.64).
|
|
@@ -49,4 +57,3 @@ Make sure you have setup Rust environment (>= 1.64).
|
|
|
49
57
|
- Run Kusama fork
|
|
50
58
|
- Edit configs/kusama.yml if needed. (e.g. update the block number)
|
|
51
59
|
- `yarn start dev --config=configs/kusama.yml`
|
|
52
|
-
|
|
@@ -33,6 +33,7 @@ export declare class Block {
|
|
|
33
33
|
get registry(): Promise<TypeRegistry>;
|
|
34
34
|
get runtimeVersion(): Promise<RuntimeVersion>;
|
|
35
35
|
get metadata(): Promise<HexString>;
|
|
36
|
+
withAvoidTasks<T>(fn: () => Promise<T>): Promise<T>;
|
|
36
37
|
get meta(): Promise<DecoratedMeta>;
|
|
37
38
|
call(method: string, args: string): Promise<TaskResponseCall['Call']>;
|
|
38
39
|
}
|
package/dist/blockchain/block.js
CHANGED
|
@@ -7,6 +7,7 @@ const util_1 = require("@polkadot/types-known/util");
|
|
|
7
7
|
const util_2 = require("@polkadot/util");
|
|
8
8
|
const storage_layer_1 = require("./storage-layer");
|
|
9
9
|
const shared_1 = require("../rpc/shared");
|
|
10
|
+
const utils_1 = require("../utils");
|
|
10
11
|
const executor_1 = require("../executor");
|
|
11
12
|
class Block {
|
|
12
13
|
number;
|
|
@@ -22,6 +23,7 @@ class Block {
|
|
|
22
23
|
#meta;
|
|
23
24
|
#baseStorage;
|
|
24
25
|
#storages;
|
|
26
|
+
#avoidTasks = false;
|
|
25
27
|
constructor(chain, number, hash, parentBlock, block) {
|
|
26
28
|
this.number = number;
|
|
27
29
|
this.hash = hash;
|
|
@@ -138,10 +140,51 @@ class Block {
|
|
|
138
140
|
}
|
|
139
141
|
get metadata() {
|
|
140
142
|
if (!this.#metadata) {
|
|
141
|
-
this.#
|
|
143
|
+
if (this.#avoidTasks) {
|
|
144
|
+
this.#metadata = this.wasm.then(executor_1.getMetadata);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
this.#metadata = this.wasm.then(async (wasm) => {
|
|
148
|
+
const res = await new Promise((resolve, reject) => {
|
|
149
|
+
this.#chain.tasks.addAndRunTask({
|
|
150
|
+
Call: {
|
|
151
|
+
blockHash: this.hash,
|
|
152
|
+
wasm,
|
|
153
|
+
calls: [['Metadata_metadata', '0x']],
|
|
154
|
+
},
|
|
155
|
+
}, (r) => {
|
|
156
|
+
if ('Call' in r) {
|
|
157
|
+
resolve((0, utils_1.compactHex)((0, util_2.hexToU8a)(r.Call.result)));
|
|
158
|
+
}
|
|
159
|
+
else if ('Error' in r) {
|
|
160
|
+
reject(new shared_1.ResponseError(1, r.Error));
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
reject(new shared_1.ResponseError(1, 'Unexpected response'));
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
return res;
|
|
168
|
+
});
|
|
169
|
+
}
|
|
142
170
|
}
|
|
143
171
|
return this.#metadata;
|
|
144
172
|
}
|
|
173
|
+
// TODO: avoid this hack
|
|
174
|
+
// we cannot use this.#chain.tasks during initialization phase
|
|
175
|
+
// but we want to use it after initialization
|
|
176
|
+
async withAvoidTasks(fn) {
|
|
177
|
+
const old = this.#avoidTasks;
|
|
178
|
+
this.#avoidTasks = true;
|
|
179
|
+
try {
|
|
180
|
+
return await fn();
|
|
181
|
+
}
|
|
182
|
+
finally {
|
|
183
|
+
this.#avoidTasks = old;
|
|
184
|
+
this.#meta = undefined;
|
|
185
|
+
this.#metadata = undefined;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
145
188
|
get meta() {
|
|
146
189
|
if (!this.#meta) {
|
|
147
190
|
this.#meta = Promise.all([this.registry, this.metadata]).then(([registry, metadataStr]) => {
|
|
@@ -5,19 +5,19 @@ export interface CreateInherents {
|
|
|
5
5
|
createInherents(meta: DecoratedMeta, timestamp: number, parent: Block): Promise<string[]>;
|
|
6
6
|
}
|
|
7
7
|
export interface InherentProvider extends CreateInherents {
|
|
8
|
-
getTimestamp(): number;
|
|
8
|
+
getTimestamp(blockNumber: number): number;
|
|
9
9
|
}
|
|
10
10
|
export declare class SetTimestamp implements InherentProvider {
|
|
11
11
|
#private;
|
|
12
|
-
constructor(getTimestamp?: () => number);
|
|
12
|
+
constructor(getTimestamp?: (blockNumber: number) => number);
|
|
13
13
|
createInherents(meta: DecoratedMeta, timestamp: number, _parent: Block): Promise<string[]>;
|
|
14
|
-
getTimestamp(): number;
|
|
14
|
+
getTimestamp(blockNumber: number): number;
|
|
15
15
|
}
|
|
16
16
|
export declare class InherentProviders implements InherentProvider {
|
|
17
17
|
#private;
|
|
18
18
|
constructor(base: InherentProvider, providers: CreateInherents[]);
|
|
19
19
|
createInherents(meta: DecoratedMeta, timestamp: number, parent: Block): Promise<string[]>;
|
|
20
|
-
getTimestamp(): number;
|
|
20
|
+
getTimestamp(blockNumber: number): number;
|
|
21
21
|
}
|
|
22
22
|
export declare class SetValidationData implements CreateInherents {
|
|
23
23
|
#private;
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SetValidationData = exports.InherentProviders = exports.SetTimestamp = void 0;
|
|
4
4
|
const types_1 = require("@polkadot/types");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
const executor_1 = require("../executor");
|
|
7
|
+
const util_1 = require("@polkadot/util");
|
|
8
|
+
const proof_1 = require("../utils/proof");
|
|
5
9
|
class SetTimestamp {
|
|
6
10
|
#getTimestamp;
|
|
7
11
|
constructor(getTimestamp = Date.now) {
|
|
@@ -10,8 +14,8 @@ class SetTimestamp {
|
|
|
10
14
|
async createInherents(meta, timestamp, _parent) {
|
|
11
15
|
return [new types_1.GenericExtrinsic(meta.registry, meta.tx.timestamp.set(timestamp)).toHex()];
|
|
12
16
|
}
|
|
13
|
-
getTimestamp() {
|
|
14
|
-
return this.#getTimestamp();
|
|
17
|
+
getTimestamp(blockNumber) {
|
|
18
|
+
return this.#getTimestamp(blockNumber);
|
|
15
19
|
}
|
|
16
20
|
}
|
|
17
21
|
exports.SetTimestamp = SetTimestamp;
|
|
@@ -51,8 +55,8 @@ class InherentProviders {
|
|
|
51
55
|
const extra = await Promise.all(this.#providers.map((provider) => provider.createInherents(meta, timestamp, parent)));
|
|
52
56
|
return [...base, ...extra.flat()];
|
|
53
57
|
}
|
|
54
|
-
getTimestamp() {
|
|
55
|
-
return this.#base.getTimestamp();
|
|
58
|
+
getTimestamp(blockNumber) {
|
|
59
|
+
return this.#base.getTimestamp(blockNumber);
|
|
56
60
|
}
|
|
57
61
|
}
|
|
58
62
|
exports.InherentProviders = InherentProviders;
|
|
@@ -80,12 +84,26 @@ class SetValidationData {
|
|
|
80
84
|
}
|
|
81
85
|
else {
|
|
82
86
|
const method = meta.registry.createType('GenericExtrinsic', extrinsics[this.#expectedIndex]);
|
|
83
|
-
const
|
|
87
|
+
const extrinsic = method.args[0].toJSON();
|
|
88
|
+
const newEntries = [];
|
|
89
|
+
const upgrade = await parentBlock.get((0, utils_1.compactHex)(meta.query.parachainSystem.pendingValidationCode()));
|
|
90
|
+
if (upgrade) {
|
|
91
|
+
const paraIdStorage = await parentBlock.get((0, utils_1.compactHex)(meta.query.parachainInfo.parachainId()));
|
|
92
|
+
const paraId = meta.registry.createType('u32', (0, util_1.hexToU8a)(paraIdStorage));
|
|
93
|
+
const upgradeKey = (0, proof_1.upgradeGoAheadSignal)(paraId);
|
|
94
|
+
const goAhead = meta.registry.createType('UpgradeGoAhead', 'GoAhead');
|
|
95
|
+
newEntries.push([upgradeKey, goAhead.toHex()]);
|
|
96
|
+
}
|
|
97
|
+
const { trieRootHash, nodes } = await (0, executor_1.createProof)(extrinsic.validationData.relayParentStorageRoot, extrinsic.relayChainState.trieNodes, newEntries);
|
|
84
98
|
newData = {
|
|
85
|
-
...
|
|
99
|
+
...extrinsic,
|
|
86
100
|
validationData: {
|
|
87
|
-
...
|
|
88
|
-
|
|
101
|
+
...extrinsic.validationData,
|
|
102
|
+
relayParentStorageRoot: trieRootHash,
|
|
103
|
+
relayParentNumber: extrinsic.validationData.relayParentNumber + 2,
|
|
104
|
+
},
|
|
105
|
+
relayChainState: {
|
|
106
|
+
trieNodes: nodes,
|
|
89
107
|
},
|
|
90
108
|
};
|
|
91
109
|
}
|
|
@@ -62,7 +62,7 @@ class TxPool {
|
|
|
62
62
|
const extrinsics = this.#pool.splice(0);
|
|
63
63
|
const meta = await head.meta;
|
|
64
64
|
const parentHeader = await head.header;
|
|
65
|
-
const time = this.#inherentProvider.getTimestamp();
|
|
65
|
+
const time = this.#inherentProvider.getTimestamp(head.number + 1);
|
|
66
66
|
let newLogs = parentHeader.digest.logs;
|
|
67
67
|
const expectedSlot = Math.floor(time / (meta.consts.timestamp.minimumPeriod.toNumber() * 2));
|
|
68
68
|
const consensus = getConsensus(parentHeader);
|
|
@@ -72,7 +72,7 @@ class TxPool {
|
|
|
72
72
|
}
|
|
73
73
|
else if (consensus?.consensusEngine.isBabe) {
|
|
74
74
|
// trying to make a SecondaryPlainPreDigest
|
|
75
|
-
const newSlot = (0, util_1.compactAddLength)((0, util_1.u8aConcat)('
|
|
75
|
+
const newSlot = (0, util_1.compactAddLength)((0, util_1.u8aConcat)('0x0200000000', (0, util_1.bnToU8a)(expectedSlot, { isLe: true, bitLength: 64 })));
|
|
76
76
|
newLogs = [{ PreRuntime: [consensus.consensusEngine, newSlot] }, ...consensus.rest];
|
|
77
77
|
}
|
|
78
78
|
const registry = await head.registry;
|
|
@@ -91,6 +91,8 @@ class TxPool {
|
|
|
91
91
|
number: head.number,
|
|
92
92
|
extrinsicsCount: extrinsics.length,
|
|
93
93
|
tempHash: newBlock.hash,
|
|
94
|
+
timeValue: time,
|
|
95
|
+
expectedSlot,
|
|
94
96
|
}, 'Building block');
|
|
95
97
|
const resp = await newBlock.call('Core_initialize_block', header.toHex());
|
|
96
98
|
logger.trace(resp.storageDiff, 'Initialize block');
|
|
@@ -113,17 +115,6 @@ class TxPool {
|
|
|
113
115
|
throw new shared_1.ResponseError(1, 'Failed to apply inherents');
|
|
114
116
|
}
|
|
115
117
|
}
|
|
116
|
-
if (meta.query.parachainSystem?.validationData) {
|
|
117
|
-
// this is a parachain
|
|
118
|
-
const validationDataKey = (0, utils_1.compactHex)(meta.query.parachainSystem.validationData());
|
|
119
|
-
const validationData = await newBlock.get(validationDataKey);
|
|
120
|
-
if (!validationData) {
|
|
121
|
-
// there is no set validation data inherent
|
|
122
|
-
// so we need to restore the old validation data to make the on_finalize check happy
|
|
123
|
-
const oldValidationData = await head.get(validationDataKey);
|
|
124
|
-
newBlock.pushStorageLayer().set(validationDataKey, oldValidationData);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
118
|
for (const extrinsic of extrinsics) {
|
|
128
119
|
try {
|
|
129
120
|
const resp = await newBlock.call('BlockBuilder_apply_extrinsic', extrinsic);
|
package/dist/executor.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HexString } from '@polkadot/util/types';
|
|
2
|
-
import { run_task } from '
|
|
2
|
+
import { run_task } from '../executor/pkg';
|
|
3
3
|
export type RuntimeVersion = {
|
|
4
4
|
specName: string;
|
|
5
5
|
implName: string;
|
|
@@ -13,4 +13,9 @@ export type RuntimeVersion = {
|
|
|
13
13
|
export declare const getRuntimeVersion: (code: HexString) => Promise<RuntimeVersion>;
|
|
14
14
|
export declare const getMetadata: (code: HexString) => Promise<HexString>;
|
|
15
15
|
export declare const calculateStateRoot: (entries: [HexString, HexString][]) => Promise<HexString>;
|
|
16
|
+
export declare const decodeProof: (trieRootHash: HexString, keys: HexString[], nodes: HexString[]) => Promise<Record<`0x${string}`, `0x${string}` | null>>;
|
|
17
|
+
export declare const createProof: (trieRootHash: HexString, nodes: HexString[], entries: [HexString, HexString][]) => Promise<{
|
|
18
|
+
trieRootHash: `0x${string}`;
|
|
19
|
+
nodes: `0x${string}`[];
|
|
20
|
+
}>;
|
|
16
21
|
export { run_task as runTask };
|
package/dist/executor.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.runTask = exports.calculateStateRoot = exports.getMetadata = exports.getRuntimeVersion = void 0;
|
|
3
|
+
exports.runTask = exports.createProof = exports.decodeProof = exports.calculateStateRoot = exports.getMetadata = exports.getRuntimeVersion = void 0;
|
|
4
4
|
const ws_1 = require("ws");
|
|
5
5
|
const util_1 = require("@polkadot/util");
|
|
6
6
|
global.WebSocket = ws_1.WebSocket;
|
|
7
|
-
const
|
|
8
|
-
Object.defineProperty(exports, "runTask", { enumerable: true, get: function () { return
|
|
7
|
+
const pkg_1 = require("../executor/pkg");
|
|
8
|
+
Object.defineProperty(exports, "runTask", { enumerable: true, get: function () { return pkg_1.run_task; } });
|
|
9
9
|
const utils_1 = require("./utils");
|
|
10
10
|
const getRuntimeVersion = async (code) => {
|
|
11
|
-
return (0,
|
|
11
|
+
return (0, pkg_1.get_runtime_version)(code).then((version) => {
|
|
12
12
|
version.specName = (0, util_1.hexToString)(version.specName);
|
|
13
13
|
version.implName = (0, util_1.hexToString)(version.implName);
|
|
14
14
|
return version;
|
|
@@ -16,10 +16,27 @@ const getRuntimeVersion = async (code) => {
|
|
|
16
16
|
};
|
|
17
17
|
exports.getRuntimeVersion = getRuntimeVersion;
|
|
18
18
|
const getMetadata = async (code) => {
|
|
19
|
-
return (0, utils_1.compactHex)((0, util_1.hexToU8a)(await (0,
|
|
19
|
+
return (0, utils_1.compactHex)((0, util_1.hexToU8a)(await (0, pkg_1.get_metadata)(code)));
|
|
20
20
|
};
|
|
21
21
|
exports.getMetadata = getMetadata;
|
|
22
22
|
const calculateStateRoot = async (entries) => {
|
|
23
|
-
return (0,
|
|
23
|
+
return (0, pkg_1.calculate_state_root)(entries);
|
|
24
24
|
};
|
|
25
25
|
exports.calculateStateRoot = calculateStateRoot;
|
|
26
|
+
const nodesAddLength = (nodes) => {
|
|
27
|
+
const nodesWithLength = nodes.map((x) => (0, util_1.compactAddLength)((0, util_1.hexToU8a)(x)));
|
|
28
|
+
return (0, util_1.u8aToHex)((0, util_1.u8aConcatStrict)([(0, util_1.compactToU8a)(nodesWithLength.length), (0, util_1.u8aConcat)(...nodesWithLength)]));
|
|
29
|
+
};
|
|
30
|
+
const decodeProof = async (trieRootHash, keys, nodes) => {
|
|
31
|
+
const decoded = await (0, pkg_1.decode_proof)(trieRootHash, keys, nodesAddLength(nodes));
|
|
32
|
+
return decoded.reduce((accum, [key, value]) => {
|
|
33
|
+
accum[key] = value;
|
|
34
|
+
return accum;
|
|
35
|
+
}, {});
|
|
36
|
+
};
|
|
37
|
+
exports.decodeProof = decodeProof;
|
|
38
|
+
const createProof = async (trieRootHash, nodes, entries) => {
|
|
39
|
+
const result = await (0, pkg_1.create_proof)(trieRootHash, nodesAddLength(nodes), entries);
|
|
40
|
+
return { trieRootHash: result[0], nodes: result[1] };
|
|
41
|
+
};
|
|
42
|
+
exports.createProof = createProof;
|
package/dist/executor.test.js
CHANGED
|
@@ -5,11 +5,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const metadata_1 = require("@polkadot/types/metadata");
|
|
7
7
|
const types_1 = require("@polkadot/types");
|
|
8
|
-
const executor_1 = require("./executor");
|
|
9
8
|
const decorate_1 = require("@polkadot/types/metadata/decorate");
|
|
10
9
|
const vitest_1 = require("vitest");
|
|
11
10
|
const node_fs_1 = require("node:fs");
|
|
12
11
|
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
const proof_1 = require("./utils/proof");
|
|
13
|
+
const executor_1 = require("./executor");
|
|
13
14
|
(0, vitest_1.describe)('wasm', () => {
|
|
14
15
|
(0, vitest_1.it)('get metadata from wasm runtime', async () => {
|
|
15
16
|
const code = String((0, node_fs_1.readFileSync)(node_path_1.default.join(__dirname, 'runtime.example'))).trim();
|
|
@@ -55,4 +56,88 @@ const node_path_1 = __importDefault(require("node:path"));
|
|
|
55
56
|
const b = await (0, executor_1.calculateStateRoot)([['0x5301bf5ff0298f5c7b93a446709f8e885f772afdd0d8ba3d4d559a06f0742f12', '0x02']]);
|
|
56
57
|
(0, vitest_1.expect)(a).to.not.eq(b);
|
|
57
58
|
});
|
|
59
|
+
(0, vitest_1.it)('decode & create proof works', async () => {
|
|
60
|
+
// from acala chain
|
|
61
|
+
const ROOT_TRIE_HASH = '0x4a8902b29241020b24b4a1620d0154f756b81ffbcf739a9f06d3447df8123ebd';
|
|
62
|
+
const NODES = [
|
|
63
|
+
'0x5703f5a4efb16ffa83d007000080d205bfd64a59c64fe84480fda7dafd773cb029530c4efe8441bf1f4332bfa48a',
|
|
64
|
+
'0x5703f5a4efb16ffa83d00700008420e8030000d4070000d6070000db070000dc070000f0070000f2070000f3070000',
|
|
65
|
+
'0x5c8c2de8299067f3070000d0070000d4e8030000009001000090010000000000000000000000e8764817000000000000000000000000e87648170000000000000000000000',
|
|
66
|
+
'0x5d0452a22bee61fad0070000f20700005501e80300000090010000900100000000000000000001e41d29d36ff0b7c6007ec17b68ba6165066170fc67eb9755fbd7ed60bef647c100e8764817000000000000000000000000e87648170000000000000000000000',
|
|
67
|
+
'0x5d04d2a15ab51127e8030000d0070000d4e8030000009001000090010000000000000000000000e8764817000000000000000000000000e87648170000000000000000000000',
|
|
68
|
+
'0x5d07edc4cbc65e03d0070000d40700005501e80300000090010000900100000000000000000001708391b220ce64bab1cc4f79559352e59882ee5bb58329085c2400079c56153a00e8764817000000000000000000000000e87648170000000000000000000000',
|
|
69
|
+
'0x5d0b652b2ae6ed1ddc070000d00700005501e803000000900100009001000000000000000000010a492e67d36615052a89ba50498ed5cf0a587b31fd6f3da464e5d111e4e8a81c00e8764817000000000000000000000000e87648170000000000000000000000',
|
|
70
|
+
'0x5d0be1ee506d55f8d0070000f3070000d4e8030000009001000090010000000000000000000000e8764817000000000000000000000000e87648170000000000000000000000',
|
|
71
|
+
'0x5d0c472775baca93f0070000d00700005501e803000000900100009001000000000000000000013b264b3f72ecfeddbdad3b409887206a18d387f1b81856c0383014c9f559992000e8764817000000000000000000000000e87648170000000000000000000000',
|
|
72
|
+
'0x5e046fae65527199f2070000d0070000d4e8030000009001000090010000000000000000000000e8764817000000000000000000000000e87648170000000000000000000000',
|
|
73
|
+
'0x5e057a605f506cfcd4070000d00700005501e80300000090010000900100000000000000000001d3772d60305c2cbd7acf502a11881e0eef47fdfc85c7d2a0d6241e06ea4a971000e8764817000000000000000000000000e87648170000000000000000000000',
|
|
74
|
+
'0x5e36ad4314650419d0070000f00700005501e80300000090010000900100000000000000000001de18e43e692ffe15ea7a85abbce774e6944c56270a846777352827c7596f6c3e00e8764817000000000000000000000000e87648170000000000000000000000',
|
|
75
|
+
'0x5e36c65ca123d5fbd0070000dc0700005501e80300000090010000900100000000000000000001c5120071fe1663a5a21b96d87446ac903ef1bf87dd729b8b9e92ca42ca303e7400e8764817000000000000000000000000e87648170000000000000000000000',
|
|
76
|
+
'0x5e414cb008e0e61e46722aa60abdd67280b46e626e564d1385d21257d8cb59236ca125657f2a14bebd1af174317ca1055c',
|
|
77
|
+
'0x5e4361975d97255ddb070000d00700005501e803000000900100009001000000000000000000018c74408c28f6627f58a8e10b3ec06b98b0166bfb148641a35c5cdfc7a56e68fb00e8764817000000000000000000000000e87648170000000000000000000000',
|
|
78
|
+
'0x5e4f36708366b722d0070000e8030000d4e8030000009001000090010000000000000000000000e8764817000000000000000000000000e87648170000000000000000000000',
|
|
79
|
+
'0x5e55c8e02d73966fd6070000d00700005501e803000000900100009001000000000000000000019a436c9ae233f8b3cc6a379dc35ff6a3c4153b22a96db9fc81c9cee506a252b900e8764817000000000000000000000000e87648170000000000000000000000',
|
|
80
|
+
'0x5e77dfdb8adb10f78f10a5df8742c545840159a565b0fb89d8eec07b522e4e30e8bc29489ef7a9609dfec01855bd125d2e33',
|
|
81
|
+
'0x5ea99274c2ff3639d0070000d60700005501e80300000090010000900100000000000000000001d10c375b7f3756dd38a6fd0967fa4a92199606619c76c5aedc139eb584e8628b00e8764817000000000000000000000000e87648170000000000000000000000',
|
|
82
|
+
'0x5ec648b30353eed1d0070000db0700005501e8030000009001000090010000000000000000000100382d804f7b02c95c2d6b3b6a9cad2c97c2d7570bdfd32f8e8d961754b74b6d00e8764817000000000000000000000000e87648170000000000000000000000',
|
|
83
|
+
'0x5ee678799d3eff024253b90e84927cc68013c6d5340826d75f6258aad1cf4478c20cae5bbaf189e2fe6e0c997aec0a8c3c',
|
|
84
|
+
'0x5f04b49d95320d9021994c850f25b8e3852d030000a000005000000a00000000c8000000c800000a0000000a00000040380000580200000000500000c8000000e87648170000001e0000000000000000e8764817000000000000000000000000e87648170000000000000000000000e8030000009001001e00000000000000009001004038000000000000000000000a0000000a0000000a00000001000000010500000001c8000000060000005802000002000000580200000200000059000000000000001e0000002800000000c817a804000000000200000014000000',
|
|
85
|
+
'0x800014808fc31cedc9f5a694fdde1823788928749f52e1c637dfbf315637fd89eace451c80b58f7e709e14c8ad32651a7b6f13b2ee8aa4a9566413b985e64eb5f3918a58e9',
|
|
86
|
+
'0x800102802dcdd284f422a6ebda6a6f25c88e3ffe11d1adba81950ba92c640b042c250b1080c3883d3173954c1f95c3cb0612d3445f79eaf866255c3261671c3d50a480dcca',
|
|
87
|
+
'0x80011080453fad35c0a01e1a2af068a21c24622fe089db8330ff1c3d52d3a00c7504e515800ebe650369ce0e3ce85b22816181f598cc6ecf7a3b22314357ab4181b9ccb867',
|
|
88
|
+
'0x80011080bfead2545bbb18bbeccbbc42e419ce81be803a019bc10bc035e040209109ca708029f01a3bcd0dedb0dd8e6953b1c52deb161fb6f06b943a1934bd80506ac8f8ff',
|
|
89
|
+
'0x80046480f2126bccffb3e85172709b56414860c2d5aef6fbdca97efb91b0c7989b2e767c809bbc710130cd3fd1008762577f5a4f1959819fefe31aa2eb38c950b5b0ac16748022cba5584bc0982277b50978b65dd7c8c3702937804ae5b16b7b2dbae18122ff80c2e805afdfad80977cb420fe3c56c481131d8e6575e9dac18bfb48ee70bc5a93',
|
|
90
|
+
'0x80080480b64e0437daeee2d16022caa8e4cb67d9bfff7c5feb34dbbe044da77783421f78809ffe6dc440b4ca64053f01647b2e2d3284a4be15517f6693ee26fe4a84cc8a7b',
|
|
91
|
+
'0x8008208057bb9d54329c52084dafd34bb7a12ae243ed81b29438b7941ad6b08bc0aab080485ead6eef5c4b1c68eaa71ea17a02d9de0400',
|
|
92
|
+
'0x8008c280666c2b4c33ef871664a1cd5f75688bd687415a95f52a12fdaff5e1bb1d714f958049da90db410ddc5fcb63a6ba31fff1140f1f027eab9f575207946938a6dff0498032b1eb1b88050e8be5253bc631c21e5bb73b440ae1188f1da9e141aea5050345800892f12109affae95d1fa83c3e98639ce4aa22b3317846989ac8cc46a37ff2bf',
|
|
93
|
+
'0x801017800bd4a887368b253b446f6743e0b8b47e3384a11be255c56869ac5c22c8989dd8800bce23fe3d2d5b8d0e3a26b96ca234ad713326991a44cb1f30acd20cb8eb400080b47bdf3c44e033a0f6273db0e4d3c805462f92c8ec58046e6ece49d93264edaf80ea85a25e4978d8d9281242dec4943257cfb4d14f3408640b5e643f247d38a91c808a15b3c07f5df5f0771146cf6adb06d2d2af1c9c569c70e42d3d881e60c49cb8',
|
|
94
|
+
'0x801040809d953a8e74f031a6e10d7532012f6e655a37c85c4e37454174b98a7b92ced3f9805f738e2d7016159bb83f0acfc05b94f3bfed39826328fbea9a5a6844b0ee9f62',
|
|
95
|
+
'0x801200802c2bdbfc1bde7cdde01a4db7315c02e0373e1c8b826258e135ded3ca12b9b0e580a18673b451b154098a7a400495526a375c86a62e3c8f6def0a67b00eb6d26e87',
|
|
96
|
+
'0x80132680db8ba95d9fa6771a636c09a99827a9ef71777f6507eb4f789de5e137a7250d3780d99bcdfbfe4d2ba16f4dfaa93a02a3853cbc7912bad01d8f89acd4a18e318e9d807e84d35633382d5c74d5c446d26db1cc01db605ba0c12d399849032872bb731280ac082de8a8e688e9aa6c8d9f06576be0b982e6f7229e7b1f3a0d0cbff4e9cbce80e8f2d389ed545a028c6321d265c650179ed1c671fcfbc417185682c21667059b80a512dfa55fcf04f7e26b5ccdc14466086df66928a4f54dfb12b9873108dbfe88',
|
|
97
|
+
'0x8028388028462a6785718dce363f9fa86db6e6885c1df439739c06df2670b71ca7d1d6ab80f12b3be1de5704b86affeaf4178a0ca8dea056893c12a03c3500ca8af78c128080ae634ca22841dbcd3de33dfcd0730d87335dc93786dec63ff9ff5c494b1c32d2802166c372b218427bae449c6e50a075b4bc604253cea4ad0ee8ee7c16b498f3e9808b81a047e908564423ad8d63ef1677199bb5d41570df5ce359ec0cdc5a66fc06',
|
|
98
|
+
'0x80324680aa309aa88e45c23a7b3361cb9ac5bde5896dde657e8a562ce46cd5587674824080f7f61a745a9fefb91f35658a78ebc397ad0514232c0eec10344331b9a29195b680480c6b47252c3414177fcd8441cc689703241343e1ef84be0b206cc24b043f1c80608329e88f9837bedc55fa039c1c5468fe76304edacab49f89a35685ce0492748043a4144332df717cb9ac20b2b490345f22543965ea5272ce3511fa98f4ddfdcb80c62f5d20c25775fb8a8abded53ae1f6abd8fb9f9d75e306a1973194a9a739f73',
|
|
99
|
+
'0x804008804c9c79007d5b06217f77869639dbf475761b1d45115441ea15641d7db01d2425808c68f773671aec1db46b2c37b4c827e64aa7290d65e305cdaaa6b175596256f1',
|
|
100
|
+
'0x8041088041558830b346eebf7648fb84310d961de185de6ebc1bd22d114980d7793d6ee1804e23dcce96d9e514271688cf0bc5581e5e6e74cc4e079c39e75490ac45272f668071daa4762bcd3732d275bee68e3bb098a140029d7b01e82b4cd106924313f9f6',
|
|
101
|
+
'0x80505480a1fc2c779380c33b94b304c281e55ca5a0807804fe9530c22fdfa76628beb42680a1a8a2d4670241007470d59433dc876b10443654c68ee2c22e43f0505fb7081380cbc649bccb6cbe2678b258eb56b9985865852f8dc3ca4ac4608b46dc9a61a56580379357c2c5523ead8e26c2bd4d0ce06ca7f1726b09ef513a7d501aaa5752368280692755c9209155bd724071de137657f492de5bb5479738d1af7119739b4df473',
|
|
102
|
+
'0x80650080021eceb7212a84c0ce28538807a932d56f7ca04ad18a37eb5a3d81cf2d3a1e888028c2012c52668080a70a29a2704a0e1d108658aa94f21e0dcd5103401c52fff3809264b71d425330b4faf06bc3855662ae7511e854ed5387b3ee8c3fafcd6772d080af579d5ddc5c697d42bfc014076594e66c7b324cfd3017810c4e93e4f6f0ae9e',
|
|
103
|
+
'0x8080018068269bb8490669b94a5f1e0c3b4864e03224a2048271f11b8a95ea6168756573805dc031eeca4040dfb7be6e148287360e67d5ce62125f23d912e7ba6b5e1c3ea8',
|
|
104
|
+
'0x8086108046ea793674e4b7c40067c83aa00ac2fbbf3d2ebd57e01d5065909769da0ea9a2801eacd1970b27e7428c46fc7a1cd539390d664880f8665d1f5d9df711aef78ffc807b7ad6eb73914fd07fc55ad89ba771070c1da532a9269475dc64f1995d4d92668044a0d27ae2362402e5ac6666cbfd7bcaa530f2ea97a73b328a13ece4264ea290',
|
|
105
|
+
'0x80a06b8001abdee51ff39c1b87147abb00a81ce05a7b7bbd43dc1509cb4d97acdf3f8e6d80a296acd1c3810d5724e101343410a44934ed827a0c6931e538c2fc095adac046806661dfd17874a64f7f8e2a1e88db6fe81031f845e8705d6470bd48bef2d9615080df3c444cc602cfb8e35514a12c70fe2f5b2ec2683a3e19889c2bce42e8df423180decf6a9a942e385c520acce9b20917c7a516fee686baab2ca15379828a54ec09808cc9995c94f73aec7861dcd2bb4e389eefad87f4d8c1ece831dbcae8c85f2ab4808bbdb281c19f2e0405ebdcdd3eed583c83be8c5bf317070ab8e144c77aecab54',
|
|
106
|
+
'0x80a090809d70976e45bed6bfbe01cc3a2d2fc8d707784be7b54c5910eda9d60dbaa8dcda80c7d17ef601008c6b5fb577a67c8c0ed8f8a1b4eea0109830cddfc3d05c5955b8808fac6f5b26a0a091512ba579c768e78cd75b5f91ff02dcd27a011a1b9d3f8ca0805fc8b08bf7e5d96506fca5e15f58b00e5857510be132ddf21222fdc441242af5',
|
|
107
|
+
'0x80ffff80c66d277de66aaf06e0d6a1fc26ce21d8f6ef50ff28e14dbccfb2fa5bfbd0e5d680f219622acbd014476d4edb56ff6b86554c683a93a217b9ee5449d5f97350aba980daacb402b9d9534826030a1a087c3a6064f823d9578216b50dcc839b4a1cb4f080538c5f0315259d01b9589faf05886e3222ad437f11afbc79f8ca8fd1a706948b803b47dc6cc57a291d93e562eb748a4f6d5ba08cbd1b4b9980117eceff1ce541f08080b4dd653d14508ffe4e711984c6daebb8c53ffc701bc6c390f170524fe6067e806881eae5c901b2f9da23fc14a7b5c5adddf42803d9e6f6457502263d5c20d1b180552af8589e75bd85f77e14ad29a64b58bf27795087e0f8405f00e0af8c44769180f778234884d04539ae5ee94481786900f08bec239bc9e8a495e44f56ae62bd6f8058c056dc712c11a8aacceb99692e0b12b11fa7d127c512373d6a9312e4b7aa12800b7d692bbe193862e80155a0c60d515e359fc0711797aa73b963f8de206372318032b4da4f9707c28268fda915bad17740b2f29044af3426b93dddb1525d9119a180712826eb964d50810e03c64f0465e9d0aefba0975922e3546c1dd289ae6485ab803fc6afb3bb1a772c1b7865d617175918a1e561e7f9f6d4b3727e2e77d8cd54fd80b84b7a6e9b8ac582dfe53a66e6da54a2bc42162390b409a4fb1cb4d99e823334805ab928b4a3b5103f34f6d934e7c2a71a08f6160242d5a25e8d395f022137b544',
|
|
108
|
+
'0x8109400180c7192966ab02c8fe706a869d280b1f9e4100cd344a11d14d330d2691c06d838080cc5ba161e4197291e156c96df507a376d778fdd94adb9db8cc0f457222957ed9',
|
|
109
|
+
'0x810f080880d066a00dc79b0a8601ea466d09a4c969c246ed7d8b4f029afcd41944e33ae8b08063fee100c551b8c3283651ee6d6aad37bbe2abd5830b3c17785b691c63857dc5',
|
|
110
|
+
'0x9d0da05ca59913bc38a8630590f2627c07d980d131600ec39249fb7e25ce8b2759cbe5d9d22d65865cbdc5d5b6b43442a037a28064d55117d3f84fb235f2051b42475f6a3c165cb066016a54582116560d278c0180868f6dfc79ccadf3a96cf90a2b80fcc7fe47c77e30cbb2c8b88a6f3ee21a7c0a8039ebc92b31a26e4935b2e3ac747dfd531b73be08467c9918cc70090e0ae8859b80090170c9487096f84239151a9ecf92c1efeece708d87844f19f56988ec479a0d80a83b5e3737bfc99ede5e597406cf5b001b7949a5315953134fc321fc8992c0bd80fe20d9a744142b01474930a28d8b9a5ef3c851504a99fed5a4fec46d0533c7d88015dd6cf6cccb6c66a9e56feb41c47cf30a31d39fa77ec8b2eb55dd742db53921',
|
|
111
|
+
'0x9e207f03cfdce586301014700e2c2593414080776fdf331ededb557c273c87efa8d2e3919d6745e8645214665bf43afed8b5e9685f0d9ef3b78afddab7f5c7142131132ad42001000000000000004c5f0ec2d17a76153ff51817f12d9cfc3c7f0400',
|
|
112
|
+
'0x9e710b30bd2eab0352ddcc26417aa1944fc380926c6b63b2fdc00d98403a06793b323674ed75b32e75389a2c9d19140f48d07b80db9c2d25d50f7d4f8c69ee037a096b488bc42e33d2cfeeeff1fe8fc22c8cc1788034979b2e5ea91011d05f74f35d25c5b0da29c03c2c0e8e6b9f0a49ca32f46e58800e21335793e29a09c8eac52a4ed197378fd1ac3552ff31aecddb063d3f2c2f314c5f03c716fb8fff3de61a883bb76adb34a20400803587aeceb149eff2f59b5270a01e8c4fd19d1722eab53bcd8b5fd2aee0606fc14c5f0f4993f016e2d2f8e5f43be7bb2594860400807d9800e301836dcc17032891ceff52fc4029dcef8fc74a471e164eb06eecadaf80ac20693eb2298f6f300752834c3fc31a3c075a4e9a77a67d7ee3d6982d70e3e1',
|
|
113
|
+
'0x9eb6f36e027abb2091cfb5110ab5087ff96e685f06155b3cd9a8c9e5e9a23fd5dc13a5ed20873c991000000000685f08316cbf8fa0da822a20ac1c55bf1be320cc15000000000000505f0e7b9012096b41c4eb3aaf947f6ea429080000805788707c580bffc1660dc8c31ca562b5adf72d7dda390c9016319224cedab6c08084a80a22d77d8016adc89610b528c15ba17e4522a53faec0e60d84f5130362a580950cc9876d11a25f6c56e833f048b7fc32caf0bfbb8d9ff4b6ea993f4e984698800d49fef039517cc312c00412803ca1df50ac6d90c50541f649a9c85b83c0fdd8807a5d73d6c6a648545a7a8de535f9a12c2f7105d012e0eb272d91fb8ec018a2bf80cc59c8e5010713cf8876c314769c49fbe0b9a6e131ebf5a9774f52fe73d9ac66800c999e682e20f4c5ab236641829330b52e9a60e3bb8295c671ae10b0078b1b39685f090e2fbf2d792cb324bffa9427fe1f0e20b94ccb00fa55cb00',
|
|
114
|
+
'0x9ede3d8a54d27e44a9d5ce189618f22d3008505f0e7b9012096b41c4eb3aaf947f6ea4290802004c5f03b4123b2e186e07fb7bad5dda5f55c00400806b5403551f8463a3ddf5063c0454a5bd46c9c3d2e1030a6a838a27cc0c4b983a',
|
|
115
|
+
'0x9ef78c98723ddc9073523ef3beefda0c1004809efa6d0e486c88a89d0cec81b8d06f9b5b1dcff9db2c44a9bca135e300ee700c80a8a03c435efb3b22807974e7d4ef1ebad070a3e9c608ed0e5112c1d7223ca5ea',
|
|
116
|
+
'0x9f012b746dcf32e843354583c9702cc020cabb80ff9bed925038b8804f63090b1e2cf36d0d987e2e85b24f046ceee2d849dd69ff80d11d71ea91a8cbe9858770d23355ed19ad19a263b94d55f6d6f503c17eb3dd5280bb7fd6b2fa22db69bca4f70304addc539798fc6174ddae0c5865c71ff96e53415c5700bd9a93e85e3ce1d20700002408d6070000dc07000080b67cef76f1fdf97b48c1fcba9594f1ae40742c195b8d950ae7f08e4b3314fb2780fd53aee7d7ccb0767af55024401273b0a9437c5917cdd60d406dac4aab722333801bff773d6d6d765292b4e595ee0cd425bebe341c2f21af1768896cbfb71cc5d04c57077a93d174890f1ff20700001404d0070000806e5feeb98858d49ab4f600b9337280df82041595257c4d566175cbf59cc105f680f44d2eba0587ca4f414fe092f163abb43531c554c28cfcc26cf032083a7af9b4',
|
|
117
|
+
'0x9f06604cff828a6e3f579ca6c59ace013df7ff801afb0ed9ee8eab53f55af9e9f1c49736c6186c5852d7bba27baeab053a2d22fc809c793f0292c00ae878a17876cc7fe3343623734664aeb50333eac67dd4077b40808aaa7d061d20c8b96edc45a36746cfc2f8645b20db12f51ca020ed4967049c20804c9d12d0f9b7ab988d1ed94f3972945784bf8fb75767e41b3dc5f12410377c5c8048ddad220fd43771ed93688597e2e167308755101c343e6d465739e1f748a699806ae40eb731b53990d314bc9635edeb0f4f45870cf3d6db37bf48d2343547d2cf8005198aaee0fd5761c623207eea8ad53f057e9de0446cd00c23da5ff1c8183ec7809621a90e7fa3e8ed459a6e474ef84a300363f0d245d36a0851a191240462d6e680e2d358899753b8e0b96e95191efba0fba2333c8e526737b6976fa7b413cfa3b980f42207a985ccdcd35ae1ff027a2611b93edb846fe723806a980b082e6328715f809e314bdc1d2c60c13fd046b06bc81c65bcaad55d821e83a9c2dc31293e5ae21780f08e4a062dfbb903d956382db84eadd0bf0a7b2b8468d8cfed83802de874a67b80424742990c218a746f5754b3a2c769a9ecbb457500412b0281ebb4304054067880b5407c24baa40b063e62c1d162c55f4a646edd70607bcbaef3808211db13013780eba4585adb29d3256f8059f81a40517e63b12c41ef7c0a8726a4ba62701e3598',
|
|
118
|
+
'0x9f0d3719f5b0b12c7105c073c507445948cabb800ff6a2c0cf1c6e2dd1cad56d23aa6f51a78d85792606966afc176ecb4101e51b802db7d1beaf4152abcbe2d72358d938f31eef2e6f9adb322dd6316cd211dfe79580bb7fd6b2fa22db69bca4f70304addc539798fc6174ddae0c5865c71ff96e53415c5700bd9a93e85e3ce1d20700002408d6070000dc07000080054bc6bd08b77192f231932a6e63a3f54a48d954725a2198a762781089bf150980fd53aee7d7ccb0767af55024401273b0a9437c5917cdd60d406dac4aab7223338019cbbdbf60cd90027c802d921f737c07a073bb4bed3b9ff0c37b26506e6aafc94c57077a93d174890f1ff20700001404d0070000806e5feeb98858d49ab4f600b9337280df82041595257c4d566175cbf59cc105f680f44d2eba0587ca4f414fe092f163abb43531c554c28cfcc26cf032083a7af9b4',
|
|
119
|
+
'0x9f0d7fefc408aac59dbfe80a72ac8e3ce5cebf80b9cbd0d700a17a0e4c717af58b887e80c0bce7832e64817caa8b47152baf5ba0807e1ee2c8362cd0745aa0c58780b99fefa1024c1b472d3386a2319e71b68028a68012d23785dbec11744e5f0fef2c34efcb738891240cd4ad63bb101bd4c2512a0980152c557d36cdee4289c8b2c42462576e238b62422b257e91773a473f49c3858680a8842b069c158af198d7d570838f69a2f4c9a218d51c69ad60361a873a11bbea80f08851397f0db3ac9785de1017f41cb5b073b92ecf6b4653d1f38d4993028e4680117820f0023f9e54736ad10ecae8806bcf1cc8b4ed694aa530ed85e6361db7ea80be32eae63e4a223cdf5cbf90b66f48665668ec0bedbb6b76302768ea6f3b19cc8030b143a144cc26437db830e7d750f21dbc87cf3140097b1fdbddb697782a237180ec76035be1c7d52a15dcf76aaf69fced1772f1464ec7886952dada14030ad4fc809b912d6aa76e61c4b515535db14d28490924ef2007cf19e0022b5a089b6d010380f28a57be8a23f6a2588595e53cb640bbeeee2ef9ddc962a6672ac98bd2d6ea4e',
|
|
120
|
+
];
|
|
121
|
+
const registry = new types_1.TypeRegistry();
|
|
122
|
+
const paraId = registry.createType('u32', 2000);
|
|
123
|
+
const headKey = (0, proof_1.dmqMqcHead)(paraId);
|
|
124
|
+
const upgradeKey = (0, proof_1.upgradeGoAheadSignal)(paraId);
|
|
125
|
+
const ingressChannelIndexKey = (0, proof_1.hrmpIngressChannelIndex)(paraId);
|
|
126
|
+
const egressChannelIndexKey = (0, proof_1.hrmpEgressChannelIndex)(paraId);
|
|
127
|
+
const originalDecoded = await (0, executor_1.decodeProof)(ROOT_TRIE_HASH, [headKey, upgradeKey, ingressChannelIndexKey, egressChannelIndexKey, ...Object.values(proof_1.WELL_KNOWN_KEYS)], NODES);
|
|
128
|
+
(0, vitest_1.expect)(originalDecoded).toMatchSnapshot();
|
|
129
|
+
(0, vitest_1.expect)(originalDecoded[upgradeKey]).toBeUndefined();
|
|
130
|
+
const config = registry.createType('HostConfiguration', originalDecoded[proof_1.WELL_KNOWN_KEYS.ACTIVE_CONFIG]);
|
|
131
|
+
(0, vitest_1.expect)(config.toJSON()).toMatchSnapshot();
|
|
132
|
+
const goAhead = registry.createType('UpgradeGoAhead', 'GoAhead');
|
|
133
|
+
const { trieRootHash, nodes } = await (0, executor_1.createProof)(ROOT_TRIE_HASH, NODES, [
|
|
134
|
+
[proof_1.WELL_KNOWN_KEYS.ACTIVE_CONFIG, config.toHex()],
|
|
135
|
+
[upgradeKey, goAhead.toHex()],
|
|
136
|
+
]);
|
|
137
|
+
(0, vitest_1.expect)(trieRootHash).toMatchSnapshot();
|
|
138
|
+
(0, vitest_1.expect)(nodes).toMatchSnapshot();
|
|
139
|
+
const decoded = await (0, executor_1.decodeProof)(trieRootHash, [headKey, upgradeKey, ingressChannelIndexKey, egressChannelIndexKey, ...Object.values(proof_1.WELL_KNOWN_KEYS)], nodes);
|
|
140
|
+
(0, vitest_1.expect)(decoded).toMatchSnapshot();
|
|
141
|
+
(0, vitest_1.expect)(decoded[upgradeKey]).toBe('0x01');
|
|
142
|
+
});
|
|
58
143
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import '@polkadot/types-codec';
|
|
2
|
+
import { ProviderInterface } from '@polkadot/rpc-provider/types';
|
|
2
3
|
import { Api } from './api';
|
|
3
4
|
import { Blockchain } from './blockchain';
|
|
4
5
|
import { Config } from './schema';
|
|
5
|
-
import { ProviderInterface } from '@polkadot/rpc-provider/types';
|
|
6
6
|
import { TaskManager } from './task';
|
|
7
7
|
export declare const setup: (argv: Config) => Promise<{
|
|
8
8
|
chain: Blockchain;
|
|
@@ -10,4 +10,12 @@ export declare const setup: (argv: Config) => Promise<{
|
|
|
10
10
|
ws: ProviderInterface;
|
|
11
11
|
tasks: TaskManager;
|
|
12
12
|
}>;
|
|
13
|
-
export declare const
|
|
13
|
+
export declare const setupWithServer: (argv: Config) => Promise<{
|
|
14
|
+
close: () => Promise<void>;
|
|
15
|
+
chain: Blockchain;
|
|
16
|
+
api: Api;
|
|
17
|
+
ws: ProviderInterface;
|
|
18
|
+
tasks: TaskManager;
|
|
19
|
+
}>;
|
|
20
|
+
export declare const runBlock: (argv: Config) => Promise<void>;
|
|
21
|
+
export declare const decodeKey: (argv: any) => Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -3,40 +3,40 @@ 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.runBlock = exports.setup = void 0;
|
|
6
|
+
exports.decodeKey = exports.runBlock = exports.setupWithServer = exports.setup = void 0;
|
|
7
7
|
require("@polkadot/types-codec");
|
|
8
|
-
const api_1 = require("
|
|
8
|
+
const api_1 = require("@polkadot/api");
|
|
9
|
+
const util_1 = require("@polkadot/util");
|
|
10
|
+
const helpers_1 = require("yargs/helpers");
|
|
11
|
+
const node_fs_1 = require("node:fs");
|
|
12
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
13
|
+
const yargs_1 = __importDefault(require("yargs"));
|
|
14
|
+
const api_2 = require("./api");
|
|
9
15
|
const blockchain_1 = require("./blockchain");
|
|
10
16
|
const txpool_1 = require("./blockchain/txpool");
|
|
11
17
|
const schema_1 = require("./schema");
|
|
12
18
|
const genesis_provider_1 = require("./genesis-provider");
|
|
13
19
|
const inherents_1 = require("./blockchain/inherents");
|
|
14
20
|
const task_1 = require("./task");
|
|
15
|
-
const api_2 = require("@polkadot/api");
|
|
16
21
|
const server_1 = require("./server");
|
|
17
22
|
const logger_1 = require("./logger");
|
|
18
23
|
const rpc_1 = require("./rpc");
|
|
19
|
-
const helpers_1 = require("yargs/helpers");
|
|
20
24
|
const import_storage_1 = require("./utils/import-storage");
|
|
21
25
|
const db_1 = require("./db");
|
|
22
|
-
const node_fs_1 = require("node:fs");
|
|
23
|
-
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
24
|
-
const yargs_1 = __importDefault(require("yargs"));
|
|
25
26
|
const setup = async (argv) => {
|
|
26
|
-
|
|
27
|
-
let wsProvider;
|
|
27
|
+
let provider;
|
|
28
28
|
if (argv.genesis) {
|
|
29
29
|
if (typeof argv.genesis === 'string') {
|
|
30
|
-
|
|
30
|
+
provider = await genesis_provider_1.GenesisProvider.fromUrl(argv.genesis);
|
|
31
31
|
}
|
|
32
32
|
else {
|
|
33
|
-
|
|
33
|
+
provider = new genesis_provider_1.GenesisProvider(argv.genesis);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
else {
|
|
37
|
-
|
|
37
|
+
provider = new api_1.WsProvider(argv.endpoint);
|
|
38
38
|
}
|
|
39
|
-
const api = new
|
|
39
|
+
const api = new api_2.Api(provider);
|
|
40
40
|
await api.isReady;
|
|
41
41
|
let blockHash;
|
|
42
42
|
if (argv.block == null) {
|
|
@@ -54,8 +54,15 @@ const setup = async (argv) => {
|
|
|
54
54
|
db = await (0, db_1.openDb)(argv.db);
|
|
55
55
|
}
|
|
56
56
|
const header = await api.getHeader(blockHash);
|
|
57
|
+
const port = argv.port || Number(process.env.PORT) || 8000;
|
|
57
58
|
const tasks = new task_1.TaskManager(port, argv['mock-signature-host'], argv['executor-cmd']);
|
|
58
|
-
const
|
|
59
|
+
const blockNumber = +header.number;
|
|
60
|
+
const setTimestamp = new inherents_1.SetTimestamp((newBlockNumber) => {
|
|
61
|
+
if (argv.timestamp) {
|
|
62
|
+
return argv.timestamp + (newBlockNumber - blockNumber) * 12000; // TODO: make this more flexible
|
|
63
|
+
}
|
|
64
|
+
return Date.now();
|
|
65
|
+
});
|
|
59
66
|
const inherents = new inherents_1.InherentProviders(setTimestamp, [new inherents_1.SetValidationData(tasks, 1)]);
|
|
60
67
|
const chain = new blockchain_1.Blockchain({
|
|
61
68
|
api,
|
|
@@ -68,20 +75,29 @@ const setup = async (argv) => {
|
|
|
68
75
|
number: Number(header.number),
|
|
69
76
|
},
|
|
70
77
|
});
|
|
71
|
-
const context = { chain, api, ws:
|
|
72
|
-
const listeningPort = await (0, server_1.createServer)(port, (0, rpc_1.handler)(context)).port;
|
|
73
|
-
tasks.updateListeningPort(listeningPort);
|
|
78
|
+
const context = { chain, api, ws: provider, tasks };
|
|
74
79
|
await (0, import_storage_1.importStorage)(chain, argv['import-storage']);
|
|
75
80
|
await (0, import_storage_1.overrideWasm)(chain, argv['wasm-override']);
|
|
81
|
+
return context;
|
|
82
|
+
};
|
|
83
|
+
exports.setup = setup;
|
|
84
|
+
const setupWithServer = async (argv) => {
|
|
85
|
+
const context = await (0, exports.setup)(argv);
|
|
86
|
+
const port = argv.port || Number(process.env.PORT) || 8000;
|
|
87
|
+
const { port: listeningPort, close } = (0, server_1.createServer)(port, (0, rpc_1.handler)(context));
|
|
88
|
+
context.tasks.updateListeningPort(await listeningPort);
|
|
76
89
|
if (argv.genesis) {
|
|
77
90
|
// mine 1st block when starting from genesis to set some mock validation data
|
|
78
|
-
await chain.newBlock();
|
|
91
|
+
await context.chain.newBlock();
|
|
79
92
|
}
|
|
80
|
-
return
|
|
93
|
+
return {
|
|
94
|
+
...context,
|
|
95
|
+
close,
|
|
96
|
+
};
|
|
81
97
|
};
|
|
82
|
-
exports.
|
|
98
|
+
exports.setupWithServer = setupWithServer;
|
|
83
99
|
const runBlock = async (argv) => {
|
|
84
|
-
const context = await (0, exports.
|
|
100
|
+
const context = await (0, exports.setupWithServer)(argv);
|
|
85
101
|
const header = await context.chain.head.header;
|
|
86
102
|
const parent = header.parentHash.toHex();
|
|
87
103
|
const wasm = await context.chain.head.wasm;
|
|
@@ -105,9 +121,28 @@ const runBlock = async (argv) => {
|
|
|
105
121
|
console.dir(output, { depth: null, colors: false });
|
|
106
122
|
}
|
|
107
123
|
});
|
|
124
|
+
await context.close();
|
|
108
125
|
setTimeout(() => process.exit(0), 50);
|
|
109
126
|
};
|
|
110
127
|
exports.runBlock = runBlock;
|
|
128
|
+
const decodeKey = async (argv) => {
|
|
129
|
+
const context = await (0, exports.setup)(argv);
|
|
130
|
+
const key = argv.key;
|
|
131
|
+
const meta = await context.chain.head.meta;
|
|
132
|
+
outer: for (const module of Object.values(meta.query)) {
|
|
133
|
+
for (const storage of Object.values(module)) {
|
|
134
|
+
const keyPrefix = (0, util_1.u8aToHex)(storage.keyPrefix());
|
|
135
|
+
if (key.startsWith(keyPrefix)) {
|
|
136
|
+
const decodedKey = meta.registry.createType('StorageKey', key);
|
|
137
|
+
decodedKey.setMeta(storage.meta);
|
|
138
|
+
console.log(`${storage.section}.${storage.method}`, decodedKey.args.map((x) => x.toHuman()).join(', '));
|
|
139
|
+
break outer;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
setTimeout(() => process.exit(0), 50);
|
|
144
|
+
};
|
|
145
|
+
exports.decodeKey = decodeKey;
|
|
111
146
|
const processConfig = (argv) => {
|
|
112
147
|
if (argv.config) {
|
|
113
148
|
const configFile = (0, node_fs_1.readFileSync)(argv.config, 'utf8');
|
|
@@ -117,12 +152,7 @@ const processConfig = (argv) => {
|
|
|
117
152
|
}
|
|
118
153
|
return argv;
|
|
119
154
|
};
|
|
120
|
-
|
|
121
|
-
.command('run-block', 'Replay a block', (yargs) => yargs.options({
|
|
122
|
-
port: {
|
|
123
|
-
desc: 'Port to listen on',
|
|
124
|
-
number: true,
|
|
125
|
-
},
|
|
155
|
+
const defaultOptions = {
|
|
126
156
|
endpoint: {
|
|
127
157
|
desc: 'Endpoint to connect to',
|
|
128
158
|
string: true,
|
|
@@ -131,26 +161,35 @@ const processConfig = (argv) => {
|
|
|
131
161
|
desc: 'Block hash or block number. Default to latest block',
|
|
132
162
|
string: true,
|
|
133
163
|
},
|
|
134
|
-
'
|
|
135
|
-
desc: '
|
|
136
|
-
string: true,
|
|
137
|
-
},
|
|
138
|
-
'output-path': {
|
|
139
|
-
desc: 'File path to print output',
|
|
164
|
+
'wasm-override': {
|
|
165
|
+
desc: 'Path to wasm override',
|
|
140
166
|
string: true,
|
|
141
167
|
},
|
|
142
168
|
db: {
|
|
143
169
|
desc: 'Path to database',
|
|
144
170
|
string: true,
|
|
145
171
|
},
|
|
146
|
-
'wasm-override': {
|
|
147
|
-
desc: 'Path to wasm override',
|
|
148
|
-
string: true,
|
|
149
|
-
},
|
|
150
172
|
config: {
|
|
151
173
|
desc: 'Path to config file',
|
|
152
174
|
string: true,
|
|
153
175
|
},
|
|
176
|
+
};
|
|
177
|
+
(0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
|
|
178
|
+
.scriptName('chopsticks')
|
|
179
|
+
.command('run-block', 'Replay a block', (yargs) => yargs.options({
|
|
180
|
+
...defaultOptions,
|
|
181
|
+
port: {
|
|
182
|
+
desc: 'Port to listen on',
|
|
183
|
+
number: true,
|
|
184
|
+
},
|
|
185
|
+
'executor-cmd': {
|
|
186
|
+
desc: 'Command to execute the executor',
|
|
187
|
+
string: true,
|
|
188
|
+
},
|
|
189
|
+
'output-path': {
|
|
190
|
+
desc: 'File path to print output',
|
|
191
|
+
string: true,
|
|
192
|
+
},
|
|
154
193
|
}), (argv) => {
|
|
155
194
|
(0, exports.runBlock)(processConfig(argv)).catch((err) => {
|
|
156
195
|
console.error(err);
|
|
@@ -158,18 +197,11 @@ const processConfig = (argv) => {
|
|
|
158
197
|
});
|
|
159
198
|
})
|
|
160
199
|
.command('dev', 'Dev mode', (yargs) => yargs.options({
|
|
200
|
+
...defaultOptions,
|
|
161
201
|
port: {
|
|
162
202
|
desc: 'Port to listen on',
|
|
163
203
|
number: true,
|
|
164
204
|
},
|
|
165
|
-
endpoint: {
|
|
166
|
-
desc: 'Endpoint to connect to',
|
|
167
|
-
string: true,
|
|
168
|
-
},
|
|
169
|
-
block: {
|
|
170
|
-
desc: 'Block hash or block number. Default to latest block',
|
|
171
|
-
string: true,
|
|
172
|
-
},
|
|
173
205
|
'executor-cmd': {
|
|
174
206
|
desc: 'Command to execute the executor',
|
|
175
207
|
string: true,
|
|
@@ -186,23 +218,25 @@ const processConfig = (argv) => {
|
|
|
186
218
|
desc: 'Mock signature host so any signature starts with 0xdeadbeef and filled by 0xcd is considered valid',
|
|
187
219
|
boolean: true,
|
|
188
220
|
},
|
|
189
|
-
db: {
|
|
190
|
-
desc: 'Path to database',
|
|
191
|
-
string: true,
|
|
192
|
-
},
|
|
193
|
-
'wasm-override': {
|
|
194
|
-
desc: 'Path to wasm override',
|
|
195
|
-
string: true,
|
|
196
|
-
},
|
|
197
|
-
config: {
|
|
198
|
-
desc: 'Path to config file',
|
|
199
|
-
string: true,
|
|
200
|
-
},
|
|
201
221
|
}), (argv) => {
|
|
202
|
-
(0, exports.
|
|
222
|
+
(0, exports.setupWithServer)(processConfig(argv)).catch((err) => {
|
|
223
|
+
console.error(err);
|
|
224
|
+
process.exit(1);
|
|
225
|
+
});
|
|
226
|
+
})
|
|
227
|
+
.command('decode-key <key>', 'Deocde a key', (yargs) => yargs
|
|
228
|
+
.positional('key', {
|
|
229
|
+
desc: 'Key to decode',
|
|
230
|
+
type: 'string',
|
|
231
|
+
})
|
|
232
|
+
.options({
|
|
233
|
+
...defaultOptions,
|
|
234
|
+
}), (argv) => {
|
|
235
|
+
(0, exports.decodeKey)(processConfig(argv)).catch((err) => {
|
|
203
236
|
console.error(err);
|
|
204
237
|
process.exit(1);
|
|
205
238
|
});
|
|
206
239
|
})
|
|
207
240
|
.strict()
|
|
208
|
-
.help()
|
|
241
|
+
.help()
|
|
242
|
+
.alias('help', 'h').argv;
|
package/dist/schema/index.d.ts
CHANGED
|
@@ -131,7 +131,10 @@ export declare const configSchema: z.ZodObject<{
|
|
|
131
131
|
};
|
|
132
132
|
};
|
|
133
133
|
}>]>>;
|
|
134
|
+
timestamp: z.ZodOptional<z.ZodNumber>;
|
|
134
135
|
}, "strict", z.ZodTypeAny, {
|
|
136
|
+
port?: number | undefined;
|
|
137
|
+
timestamp?: number | undefined;
|
|
135
138
|
db?: string | undefined;
|
|
136
139
|
genesis?: string | {
|
|
137
140
|
name: string;
|
|
@@ -147,7 +150,6 @@ export declare const configSchema: z.ZodObject<{
|
|
|
147
150
|
};
|
|
148
151
|
};
|
|
149
152
|
} | undefined;
|
|
150
|
-
port?: number | undefined;
|
|
151
153
|
endpoint?: string | undefined;
|
|
152
154
|
block?: string | number | undefined;
|
|
153
155
|
'executor-cmd'?: string | undefined;
|
|
@@ -156,6 +158,8 @@ export declare const configSchema: z.ZodObject<{
|
|
|
156
158
|
'mock-signature-host'?: boolean | undefined;
|
|
157
159
|
'wasm-override'?: string | undefined;
|
|
158
160
|
}, {
|
|
161
|
+
port?: number | undefined;
|
|
162
|
+
timestamp?: number | undefined;
|
|
159
163
|
db?: string | undefined;
|
|
160
164
|
genesis?: string | {
|
|
161
165
|
name: string;
|
|
@@ -171,7 +175,6 @@ export declare const configSchema: z.ZodObject<{
|
|
|
171
175
|
};
|
|
172
176
|
};
|
|
173
177
|
} | undefined;
|
|
174
|
-
port?: number | undefined;
|
|
175
178
|
endpoint?: string | undefined;
|
|
176
179
|
block?: string | number | undefined;
|
|
177
180
|
'executor-cmd'?: string | undefined;
|
package/dist/schema/index.js
CHANGED
package/dist/task.d.ts
CHANGED
package/dist/task.js
CHANGED
|
@@ -29,6 +29,7 @@ class TaskManager {
|
|
|
29
29
|
addTask(task, callback = () => { }) {
|
|
30
30
|
logger.debug({
|
|
31
31
|
kind: Object.keys(task)[0],
|
|
32
|
+
port: this.#listeningPort,
|
|
32
33
|
}, 'AddTask');
|
|
33
34
|
if ('Call' in task && task.Call.mockSignatureHost === undefined) {
|
|
34
35
|
task.Call.mockSignatureHost = this.#mockSignatureHost;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { HexString } from '@polkadot/util/types';
|
|
2
|
+
import { u32 } from '@polkadot/types';
|
|
3
|
+
export declare const WELL_KNOWN_KEYS: Record<string, HexString>;
|
|
4
|
+
export declare const dmqMqcHead: (paraId: u32) => `0x${string}`;
|
|
5
|
+
export declare const upgradeGoAheadSignal: (paraId: u32) => `0x${string}`;
|
|
6
|
+
export declare const hrmpIngressChannelIndex: (paraId: u32) => `0x${string}`;
|
|
7
|
+
export declare const hrmpEgressChannelIndex: (paraId: u32) => `0x${string}`;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hrmpEgressChannelIndex = exports.hrmpIngressChannelIndex = exports.upgradeGoAheadSignal = exports.dmqMqcHead = exports.WELL_KNOWN_KEYS = void 0;
|
|
4
|
+
const util_1 = require("@polkadot/util");
|
|
5
|
+
const util_crypto_1 = require("@polkadot/util-crypto");
|
|
6
|
+
exports.WELL_KNOWN_KEYS = {
|
|
7
|
+
EPOCH_INDEX: '0x1cb6f36e027abb2091cfb5110ab5087f38316cbf8fa0da822a20ac1c55bf1be3',
|
|
8
|
+
CURRENT_BLOCK_RANDOMNESS: '0x1cb6f36e027abb2091cfb5110ab5087fd077dfdb8adb10f78f10a5df8742c545',
|
|
9
|
+
ONE_EPOCH_AGO_RANDOMNESS: '0x1cb6f36e027abb2091cfb5110ab5087f7ce678799d3eff024253b90e84927cc6',
|
|
10
|
+
TWO_EPOCHS_AGO_RANDOMNESS: '0x1cb6f36e027abb2091cfb5110ab5087f7a414cb008e0e61e46722aa60abdd672',
|
|
11
|
+
CURRENT_SLOT: '0x1cb6f36e027abb2091cfb5110ab5087f06155b3cd9a8c9e5e9a23fd5dc13a5ed',
|
|
12
|
+
ACTIVE_CONFIG: '0x06de3d8a54d27e44a9d5ce189618f22db4b49d95320d9021994c850f25b8e385',
|
|
13
|
+
};
|
|
14
|
+
const prefixWithParaId = (prefix, paraId) => {
|
|
15
|
+
const id = paraId.toU8a();
|
|
16
|
+
return (0, util_1.u8aToHex)((0, util_1.u8aConcat)((0, util_1.hexToU8a)(prefix), (0, util_crypto_1.xxhashAsU8a)(id, 64), id));
|
|
17
|
+
};
|
|
18
|
+
const dmqMqcHead = (paraId) => {
|
|
19
|
+
const prefix = '0x63f78c98723ddc9073523ef3beefda0c4d7fefc408aac59dbfe80a72ac8e3ce5';
|
|
20
|
+
return prefixWithParaId(prefix, paraId);
|
|
21
|
+
};
|
|
22
|
+
exports.dmqMqcHead = dmqMqcHead;
|
|
23
|
+
const upgradeGoAheadSignal = (paraId) => {
|
|
24
|
+
const prefix = '0xcd710b30bd2eab0352ddcc26417aa1949e94c040f5e73d9b7addd6cb603d15d3';
|
|
25
|
+
return prefixWithParaId(prefix, paraId);
|
|
26
|
+
};
|
|
27
|
+
exports.upgradeGoAheadSignal = upgradeGoAheadSignal;
|
|
28
|
+
const hrmpIngressChannelIndex = (paraId) => {
|
|
29
|
+
const prefix = '0x6a0da05ca59913bc38a8630590f2627c1d3719f5b0b12c7105c073c507445948';
|
|
30
|
+
return prefixWithParaId(prefix, paraId);
|
|
31
|
+
};
|
|
32
|
+
exports.hrmpIngressChannelIndex = hrmpIngressChannelIndex;
|
|
33
|
+
const hrmpEgressChannelIndex = (paraId) => {
|
|
34
|
+
const prefix = '0x6a0da05ca59913bc38a8630590f2627cf12b746dcf32e843354583c9702cc020';
|
|
35
|
+
return prefixWithParaId(prefix, paraId);
|
|
36
|
+
};
|
|
37
|
+
exports.hrmpEgressChannelIndex = hrmpEgressChannelIndex;
|
|
@@ -49,7 +49,7 @@ const setStorage = async (chain, storage, blockHash) => {
|
|
|
49
49
|
storageItems = storage;
|
|
50
50
|
}
|
|
51
51
|
else {
|
|
52
|
-
storageItems = objectToStorageItems(await block.meta, storage);
|
|
52
|
+
storageItems = objectToStorageItems(await block.withAvoidTasks(() => block.meta), storage);
|
|
53
53
|
}
|
|
54
54
|
block.pushStorageLayer().setAll(storageItems);
|
|
55
55
|
return block.hash;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acala-network/chopsticks",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"author": "Bryan Chen <xlchen1291@gmail.com>",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"dev:acala": "ts-node-dev --transpile-only --inspect --notify=false src/index.ts -- dev --config=configs/acala.yml"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@acala-network/chopsticks-executor": "0.2.
|
|
31
|
+
"@acala-network/chopsticks-executor": "0.2.1",
|
|
32
32
|
"@polkadot/api": "^9.10.1",
|
|
33
33
|
"@polkadot/rpc-provider": "^9.10.1",
|
|
34
34
|
"@polkadot/types": "^9.10.1",
|