@acala-network/chopsticks 0.5.2 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api.js +1 -5
- package/lib/blockchain/block-builder.js +36 -43
- package/lib/blockchain/block.js +24 -28
- package/lib/blockchain/head-state.js +9 -14
- package/lib/blockchain/index.js +24 -28
- package/lib/blockchain/inherent/index.js +11 -20
- package/lib/blockchain/inherent/para-enter.js +3 -7
- package/lib/blockchain/inherent/parachain/babe-randomness.js +3 -7
- package/lib/blockchain/inherent/parachain/nimbus-author-inherent.js +3 -7
- package/lib/blockchain/inherent/parachain/validation-data.js +26 -33
- package/lib/blockchain/storage-layer.js +8 -16
- package/lib/blockchain/txpool.js +13 -20
- package/lib/cli.js +35 -34
- package/lib/db/entities.js +6 -9
- package/lib/db/index.js +5 -32
- package/lib/dry-run-preimage.js +23 -27
- package/lib/dry-run.js +12 -16
- package/lib/executor.js +24 -36
- package/lib/genesis-provider.js +17 -24
- package/lib/index.js +7 -31
- package/lib/logger.js +3 -10
- package/lib/rpc/dev/dry-run.js +21 -28
- package/lib/rpc/dev/index.js +14 -16
- package/lib/rpc/index.js +9 -16
- package/lib/rpc/shared.js +3 -7
- package/lib/rpc/substrate/author.js +8 -10
- package/lib/rpc/substrate/chain.js +5 -7
- package/lib/rpc/substrate/index.js +11 -16
- package/lib/rpc/substrate/payment.js +7 -9
- package/lib/rpc/substrate/state.js +5 -7
- package/lib/rpc/substrate/system.js +6 -11
- package/lib/run-block.js +12 -16
- package/lib/schema/index.js +22 -25
- package/lib/server.js +8 -35
- package/lib/setup-with-server.js +8 -12
- package/lib/setup.js +26 -30
- package/lib/utils/decoder.js +16 -25
- package/lib/utils/generate-html-diff.js +12 -20
- package/lib/utils/import-storage.js +11 -19
- package/lib/utils/index.js +10 -19
- package/lib/utils/open-html.js +3 -7
- package/lib/utils/proof.js +9 -17
- package/lib/utils/set-storage.js +10 -14
- package/lib/utils/time-travel.js +21 -28
- package/lib/xcm/downward.js +11 -15
- package/lib/xcm/horizontal.js +7 -11
- package/lib/xcm/index.js +14 -19
- package/lib/xcm/upward.js +6 -10
- package/package.json +5 -7
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const util_1 = require("@polkadot/util");
|
|
9
|
-
const lodash_1 = __importDefault(require("lodash"));
|
|
10
|
-
const proof_1 = require("../../../utils/proof");
|
|
11
|
-
const util_crypto_1 = require("@polkadot/util-crypto");
|
|
12
|
-
const utils_1 = require("../../../utils");
|
|
13
|
-
const executor_1 = require("../../../executor");
|
|
1
|
+
import { GenericExtrinsic } from '@polkadot/types';
|
|
2
|
+
import { hexToU8a, u8aConcat } from '@polkadot/util';
|
|
3
|
+
import _ from 'lodash';
|
|
4
|
+
import { WELL_KNOWN_KEYS, dmqMqcHead, hrmpChannels, hrmpEgressChannelIndex, hrmpIngressChannelIndex, upgradeGoAheadSignal, } from '../../../utils/proof';
|
|
5
|
+
import { blake2AsHex, blake2AsU8a } from '@polkadot/util-crypto';
|
|
6
|
+
import { compactHex, getParaId } from '../../../utils';
|
|
7
|
+
import { createProof, decodeProof } from '../../../executor';
|
|
14
8
|
const MOCK_VALIDATION_DATA = {
|
|
15
9
|
validationData: {
|
|
16
10
|
relayParentNumber: 1000,
|
|
@@ -35,7 +29,7 @@ const MOCK_VALIDATION_DATA = {
|
|
|
35
29
|
],
|
|
36
30
|
},
|
|
37
31
|
};
|
|
38
|
-
class SetValidationData {
|
|
32
|
+
export class SetValidationData {
|
|
39
33
|
async createInherents(parent, params) {
|
|
40
34
|
const meta = await parent.meta;
|
|
41
35
|
if (!meta.tx.parachainSystem?.setValidationData) {
|
|
@@ -61,13 +55,13 @@ class SetValidationData {
|
|
|
61
55
|
const newEntries = [];
|
|
62
56
|
const downwardMessages = [];
|
|
63
57
|
const horizontalMessages = {};
|
|
64
|
-
const paraId = await
|
|
65
|
-
const dmqMqcHeadKey =
|
|
66
|
-
const hrmpIngressChannelIndexKey =
|
|
67
|
-
const hrmpEgressChannelIndexKey =
|
|
58
|
+
const paraId = await getParaId(parent.chain);
|
|
59
|
+
const dmqMqcHeadKey = dmqMqcHead(paraId);
|
|
60
|
+
const hrmpIngressChannelIndexKey = hrmpIngressChannelIndex(paraId);
|
|
61
|
+
const hrmpEgressChannelIndexKey = hrmpEgressChannelIndex(paraId);
|
|
68
62
|
// TODO: refactor this to have a single decodeProof
|
|
69
|
-
const decoded = await
|
|
70
|
-
for (const key of Object.values(
|
|
63
|
+
const decoded = await decodeProof(extrinsic.validationData.relayParentStorageRoot, [...Object.values(WELL_KNOWN_KEYS), dmqMqcHeadKey, hrmpIngressChannelIndexKey, hrmpEgressChannelIndexKey], extrinsic.relayChainState.trieNodes);
|
|
64
|
+
for (const key of Object.values(WELL_KNOWN_KEYS)) {
|
|
71
65
|
newEntries.push([key, decoded[key]]);
|
|
72
66
|
}
|
|
73
67
|
newEntries.push([hrmpIngressChannelIndexKey, decoded[hrmpIngressChannelIndexKey]]);
|
|
@@ -77,7 +71,7 @@ class SetValidationData {
|
|
|
77
71
|
if (dmqMqcHeadHash) {
|
|
78
72
|
for (const { msg, sentAt } of params.downwardMessages) {
|
|
79
73
|
// calculate new hash
|
|
80
|
-
dmqMqcHeadHash =
|
|
74
|
+
dmqMqcHeadHash = blake2AsHex(u8aConcat(meta.registry.createType('Hash', dmqMqcHeadHash).toU8a(), meta.registry.createType('BlockNumber', sentAt).toU8a(), blake2AsU8a(meta.registry.createType('Bytes', msg).toU8a(), 256)), 256);
|
|
81
75
|
downwardMessages.push({
|
|
82
76
|
msg,
|
|
83
77
|
sentAt,
|
|
@@ -93,7 +87,7 @@ class SetValidationData {
|
|
|
93
87
|
.toJSON();
|
|
94
88
|
const hrmpMessages = {
|
|
95
89
|
// reset values, we just need the keys
|
|
96
|
-
...
|
|
90
|
+
..._.mapValues(extrinsic.horizontalMessages, () => []),
|
|
97
91
|
...params.horizontalMessages,
|
|
98
92
|
};
|
|
99
93
|
// inject horizontal messages
|
|
@@ -104,19 +98,19 @@ class SetValidationData {
|
|
|
104
98
|
sender,
|
|
105
99
|
receiver: paraId.toNumber(),
|
|
106
100
|
});
|
|
107
|
-
const hrmpChannelKey =
|
|
108
|
-
const decoded = await
|
|
101
|
+
const hrmpChannelKey = hrmpChannels(channelId);
|
|
102
|
+
const decoded = await decodeProof(extrinsic.validationData.relayParentStorageRoot, [hrmpChannelKey], extrinsic.relayChainState.trieNodes);
|
|
109
103
|
const abridgedHrmpRaw = decoded[hrmpChannelKey];
|
|
110
104
|
if (!abridgedHrmpRaw)
|
|
111
105
|
throw new Error('Canoot find hrmp channels from validation data');
|
|
112
106
|
const abridgedHrmp = meta.registry
|
|
113
|
-
.createType('AbridgedHrmpChannel',
|
|
107
|
+
.createType('AbridgedHrmpChannel', hexToU8a(abridgedHrmpRaw))
|
|
114
108
|
.toJSON();
|
|
115
109
|
const paraMessages = [];
|
|
116
110
|
for (const { data, sentAt } of messages) {
|
|
117
111
|
// calculate new hash
|
|
118
112
|
const bytes = meta.registry.createType('Bytes', data);
|
|
119
|
-
abridgedHrmp.mqcHead =
|
|
113
|
+
abridgedHrmp.mqcHead = blake2AsHex(u8aConcat(meta.registry.createType('Hash', abridgedHrmp.mqcHead).toU8a(), meta.registry.createType('BlockNumber', sentAt).toU8a(), blake2AsU8a(bytes.toU8a(), 256)), 256);
|
|
120
114
|
abridgedHrmp.msgCount = abridgedHrmp.msgCount + 1;
|
|
121
115
|
abridgedHrmp.totalSize = abridgedHrmp.totalSize + bytes.length;
|
|
122
116
|
paraMessages.push({
|
|
@@ -135,12 +129,12 @@ class SetValidationData {
|
|
|
135
129
|
sender: paraId.toNumber(),
|
|
136
130
|
receiver,
|
|
137
131
|
});
|
|
138
|
-
const hrmpChannelKey =
|
|
139
|
-
const decoded = await
|
|
132
|
+
const hrmpChannelKey = hrmpChannels(channelId);
|
|
133
|
+
const decoded = await decodeProof(extrinsic.validationData.relayParentStorageRoot, [hrmpChannelKey], extrinsic.relayChainState.trieNodes);
|
|
140
134
|
newEntries.push([hrmpChannelKey, decoded[hrmpChannelKey]]);
|
|
141
135
|
}
|
|
142
|
-
const upgradeKey =
|
|
143
|
-
const pendingUpgrade = await parent.get(
|
|
136
|
+
const upgradeKey = upgradeGoAheadSignal(paraId);
|
|
137
|
+
const pendingUpgrade = await parent.get(compactHex(meta.query.parachainSystem.pendingValidationCode()));
|
|
144
138
|
if (pendingUpgrade) {
|
|
145
139
|
// send goAhead signal
|
|
146
140
|
const goAhead = meta.registry.createType('UpgradeGoAhead', 'GoAhead');
|
|
@@ -150,7 +144,7 @@ class SetValidationData {
|
|
|
150
144
|
// make sure previous goAhead is removed
|
|
151
145
|
newEntries.push([upgradeKey, null]);
|
|
152
146
|
}
|
|
153
|
-
const { trieRootHash, nodes } = await
|
|
147
|
+
const { trieRootHash, nodes } = await createProof(extrinsic.validationData.relayParentStorageRoot, extrinsic.relayChainState.trieNodes, newEntries);
|
|
154
148
|
newData = {
|
|
155
149
|
...extrinsic,
|
|
156
150
|
downwardMessages,
|
|
@@ -165,8 +159,7 @@ class SetValidationData {
|
|
|
165
159
|
},
|
|
166
160
|
};
|
|
167
161
|
}
|
|
168
|
-
const inherent = new
|
|
162
|
+
const inherent = new GenericExtrinsic(meta.registry, meta.tx.parachainSystem.setValidationData(newData));
|
|
169
163
|
return [inherent.toHex()];
|
|
170
164
|
}
|
|
171
165
|
}
|
|
172
|
-
exports.SetValidationData = SetValidationData;
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.StorageLayer = exports.RemoteStorageLayer = void 0;
|
|
7
|
-
const lodash_1 = __importDefault(require("lodash"));
|
|
8
|
-
const logger_1 = require("../logger");
|
|
9
|
-
const logger = logger_1.defaultLogger.child({ name: 'layer' });
|
|
10
|
-
class RemoteStorageLayer {
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import { defaultLogger } from '../logger';
|
|
3
|
+
const logger = defaultLogger.child({ name: 'layer' });
|
|
4
|
+
export class RemoteStorageLayer {
|
|
11
5
|
#api;
|
|
12
6
|
#at;
|
|
13
7
|
#db;
|
|
@@ -37,8 +31,7 @@ class RemoteStorageLayer {
|
|
|
37
31
|
return this.#api.getKeysPaged(prefix, pageSize, startKey, this.#at);
|
|
38
32
|
}
|
|
39
33
|
}
|
|
40
|
-
|
|
41
|
-
class StorageLayer {
|
|
34
|
+
export class StorageLayer {
|
|
42
35
|
#store = {};
|
|
43
36
|
#keys = [];
|
|
44
37
|
#deletedPrefix = [];
|
|
@@ -47,7 +40,7 @@ class StorageLayer {
|
|
|
47
40
|
this.#parent = parent;
|
|
48
41
|
}
|
|
49
42
|
#addKey(key) {
|
|
50
|
-
const idx =
|
|
43
|
+
const idx = _.sortedIndex(this.#keys, key);
|
|
51
44
|
const key2 = this.#keys[idx];
|
|
52
45
|
if (key === key2) {
|
|
53
46
|
return;
|
|
@@ -55,7 +48,7 @@ class StorageLayer {
|
|
|
55
48
|
this.#keys.splice(idx, 0, key);
|
|
56
49
|
}
|
|
57
50
|
#removeKey(key) {
|
|
58
|
-
const idx =
|
|
51
|
+
const idx = _.sortedIndex(this.#keys, key);
|
|
59
52
|
const key2 = this.#keys[idx];
|
|
60
53
|
if (key === key2) {
|
|
61
54
|
this.#keys.splice(idx, 1);
|
|
@@ -137,7 +130,7 @@ class StorageLayer {
|
|
|
137
130
|
this.#addKey(key);
|
|
138
131
|
}
|
|
139
132
|
}
|
|
140
|
-
let idx =
|
|
133
|
+
let idx = _.sortedIndex(this.#keys, startKey);
|
|
141
134
|
if (this.#keys[idx] === startKey) {
|
|
142
135
|
++idx;
|
|
143
136
|
}
|
|
@@ -164,4 +157,3 @@ class StorageLayer {
|
|
|
164
157
|
}
|
|
165
158
|
}
|
|
166
159
|
}
|
|
167
|
-
exports.StorageLayer = StorageLayer;
|
package/lib/blockchain/txpool.js
CHANGED
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const node_stream_1 = require("node:stream");
|
|
8
|
-
const lodash_1 = __importDefault(require("lodash"));
|
|
9
|
-
const utils_1 = require("../utils");
|
|
10
|
-
const block_builder_1 = require("./block-builder");
|
|
11
|
-
exports.APPLY_EXTRINSIC_ERROR = 'TxPool::ApplyExtrinsicError';
|
|
12
|
-
var BuildBlockMode;
|
|
1
|
+
import { EventEmitter } from 'node:stream';
|
|
2
|
+
import _ from 'lodash';
|
|
3
|
+
import { defer } from '../utils';
|
|
4
|
+
import { buildBlock } from './block-builder';
|
|
5
|
+
export const APPLY_EXTRINSIC_ERROR = 'TxPool::ApplyExtrinsicError';
|
|
6
|
+
export var BuildBlockMode;
|
|
13
7
|
(function (BuildBlockMode) {
|
|
14
8
|
BuildBlockMode[BuildBlockMode["Batch"] = 0] = "Batch";
|
|
15
9
|
BuildBlockMode[BuildBlockMode["Instant"] = 1] = "Instant";
|
|
16
10
|
BuildBlockMode[BuildBlockMode["Manual"] = 2] = "Manual";
|
|
17
|
-
})(BuildBlockMode
|
|
18
|
-
class TxPool {
|
|
11
|
+
})(BuildBlockMode || (BuildBlockMode = {}));
|
|
12
|
+
export class TxPool {
|
|
19
13
|
#chain;
|
|
20
14
|
#pool = [];
|
|
21
15
|
#ump = {};
|
|
@@ -24,7 +18,7 @@ class TxPool {
|
|
|
24
18
|
#mode;
|
|
25
19
|
#inherentProvider;
|
|
26
20
|
#pendingBlocks = [];
|
|
27
|
-
event = new
|
|
21
|
+
event = new EventEmitter();
|
|
28
22
|
#isBuilding = false;
|
|
29
23
|
constructor(chain, inherentProvider, mode = BuildBlockMode.Batch) {
|
|
30
24
|
this.#chain = chain;
|
|
@@ -77,11 +71,11 @@ class TxPool {
|
|
|
77
71
|
break;
|
|
78
72
|
}
|
|
79
73
|
}
|
|
80
|
-
#batchBuildBlock =
|
|
74
|
+
#batchBuildBlock = _.debounce(this.buildBlock, 100, { maxWait: 1000 });
|
|
81
75
|
async buildBlockWithParams(params) {
|
|
82
76
|
this.#pendingBlocks.push({
|
|
83
77
|
params,
|
|
84
|
-
deferred:
|
|
78
|
+
deferred: defer(),
|
|
85
79
|
});
|
|
86
80
|
this.#buildBlockIfNeeded();
|
|
87
81
|
await this.upcomingBlocks();
|
|
@@ -138,8 +132,8 @@ class TxPool {
|
|
|
138
132
|
const { params, deferred } = pending;
|
|
139
133
|
const head = this.#chain.head;
|
|
140
134
|
const inherents = await this.#inherentProvider.createInherents(head, params);
|
|
141
|
-
const [newBlock, pendingExtrinsics] = await
|
|
142
|
-
this.event.emit(
|
|
135
|
+
const [newBlock, pendingExtrinsics] = await buildBlock(head, inherents, params.transactions, params.upwardMessages, (extrinsic, error) => {
|
|
136
|
+
this.event.emit(APPLY_EXTRINSIC_ERROR, [extrinsic, error]);
|
|
143
137
|
});
|
|
144
138
|
for (const extrinsic of pendingExtrinsics) {
|
|
145
139
|
this.#pool.push({ extrinsic, signer: await this.#getSigner(extrinsic) });
|
|
@@ -149,4 +143,3 @@ class TxPool {
|
|
|
149
143
|
deferred.resolve();
|
|
150
144
|
}
|
|
151
145
|
}
|
|
152
|
-
exports.TxPool = TxPool;
|
package/lib/cli.js
CHANGED
|
@@ -1,30 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const decoder_1 = require("./utils/decoder");
|
|
14
|
-
const dry_run_1 = require("./dry-run");
|
|
15
|
-
const dry_run_preimage_1 = require("./dry-run-preimage");
|
|
16
|
-
const utils_1 = require("./utils");
|
|
17
|
-
const run_block_1 = require("./run-block");
|
|
1
|
+
import { hideBin } from 'yargs/helpers';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import axios from 'axios';
|
|
4
|
+
import yaml from 'js-yaml';
|
|
5
|
+
import yargs from 'yargs';
|
|
6
|
+
import { BuildBlockMode, connectParachains, connectVertical, setup, setupWithServer } from '.';
|
|
7
|
+
import { configSchema } from './schema';
|
|
8
|
+
import { decodeKey } from './utils/decoder';
|
|
9
|
+
import { dryRun } from './dry-run';
|
|
10
|
+
import { dryRunPreimage } from './dry-run-preimage';
|
|
11
|
+
import { isUrl } from './utils';
|
|
12
|
+
import { runBlock } from './run-block';
|
|
18
13
|
const processConfig = async (path) => {
|
|
19
14
|
let file;
|
|
20
|
-
if (
|
|
21
|
-
file = await
|
|
15
|
+
if (isUrl(path)) {
|
|
16
|
+
file = await axios.get(path).then((x) => x.data);
|
|
22
17
|
}
|
|
23
18
|
else {
|
|
24
|
-
file =
|
|
19
|
+
file = readFileSync(path, 'utf8');
|
|
25
20
|
}
|
|
26
|
-
const config =
|
|
27
|
-
return
|
|
21
|
+
const config = yaml.load(file);
|
|
22
|
+
return configSchema.parse(config);
|
|
28
23
|
};
|
|
29
24
|
const processArgv = async (argv) => {
|
|
30
25
|
if (argv.config) {
|
|
@@ -55,7 +50,7 @@ const defaultOptions = {
|
|
|
55
50
|
string: true,
|
|
56
51
|
},
|
|
57
52
|
};
|
|
58
|
-
(
|
|
53
|
+
yargs(hideBin(process.argv))
|
|
59
54
|
.scriptName('chopsticks')
|
|
60
55
|
.command('run-block', 'Replay a block', (yargs) => yargs.options({
|
|
61
56
|
...defaultOptions,
|
|
@@ -74,7 +69,7 @@ const defaultOptions = {
|
|
|
74
69
|
desc: 'Open generated html',
|
|
75
70
|
},
|
|
76
71
|
}), async (argv) => {
|
|
77
|
-
await
|
|
72
|
+
await runBlock(await processArgv(argv));
|
|
78
73
|
})
|
|
79
74
|
.command('dry-run', 'Dry run an extrinsic', (yargs) => yargs.options({
|
|
80
75
|
...defaultOptions,
|
|
@@ -107,10 +102,10 @@ const defaultOptions = {
|
|
|
107
102
|
}), async (argv) => {
|
|
108
103
|
const config = await processArgv(argv);
|
|
109
104
|
if (config.preimage) {
|
|
110
|
-
await
|
|
105
|
+
await dryRunPreimage(config);
|
|
111
106
|
}
|
|
112
107
|
else {
|
|
113
|
-
await
|
|
108
|
+
await dryRun(config);
|
|
114
109
|
}
|
|
115
110
|
})
|
|
116
111
|
.command('dev', 'Dev mode', (yargs) => yargs.options({
|
|
@@ -121,7 +116,7 @@ const defaultOptions = {
|
|
|
121
116
|
},
|
|
122
117
|
'build-block-mode': {
|
|
123
118
|
desc: 'Build block mode. Default to Batch',
|
|
124
|
-
enum: [
|
|
119
|
+
enum: [BuildBlockMode.Batch, BuildBlockMode.Manual, BuildBlockMode.Instant],
|
|
125
120
|
},
|
|
126
121
|
'import-storage': {
|
|
127
122
|
desc: 'Pre-defined JSON/YAML storage file path',
|
|
@@ -136,7 +131,7 @@ const defaultOptions = {
|
|
|
136
131
|
boolean: true,
|
|
137
132
|
},
|
|
138
133
|
}), async (argv) => {
|
|
139
|
-
await
|
|
134
|
+
await setupWithServer(await processArgv(argv));
|
|
140
135
|
})
|
|
141
136
|
.command('decode-key <key>', 'Deocde a key', (yargs) => yargs
|
|
142
137
|
.positional('key', {
|
|
@@ -146,8 +141,8 @@ const defaultOptions = {
|
|
|
146
141
|
.options({
|
|
147
142
|
...defaultOptions,
|
|
148
143
|
}), async (argv) => {
|
|
149
|
-
const context = await
|
|
150
|
-
const { storage, decodedKey } =
|
|
144
|
+
const context = await setup(await processArgv(argv));
|
|
145
|
+
const { storage, decodedKey } = decodeKey(await context.chain.head.meta, context.chain.head, argv.key);
|
|
151
146
|
if (storage && decodedKey) {
|
|
152
147
|
console.log(`${storage.section}.${storage.method}`, decodedKey.args.map((x) => JSON.stringify(x.toHuman())).join(', '));
|
|
153
148
|
}
|
|
@@ -170,18 +165,24 @@ const defaultOptions = {
|
|
|
170
165
|
}), async (argv) => {
|
|
171
166
|
const parachains = [];
|
|
172
167
|
for (const config of argv.parachain) {
|
|
173
|
-
const { chain } = await
|
|
168
|
+
const { chain } = await setupWithServer(await processConfig(config));
|
|
174
169
|
parachains.push(chain);
|
|
175
170
|
}
|
|
176
171
|
if (parachains.length > 1) {
|
|
177
|
-
await
|
|
172
|
+
await connectParachains(parachains);
|
|
178
173
|
}
|
|
179
174
|
if (argv.relaychain) {
|
|
180
|
-
const { chain: relaychain } = await
|
|
175
|
+
const { chain: relaychain } = await setupWithServer(await processConfig(argv.relaychain));
|
|
181
176
|
for (const parachain of parachains) {
|
|
182
|
-
await
|
|
177
|
+
await connectVertical(relaychain, parachain);
|
|
183
178
|
}
|
|
184
179
|
}
|
|
180
|
+
})
|
|
181
|
+
.command({
|
|
182
|
+
command: '*',
|
|
183
|
+
handler() {
|
|
184
|
+
yargs.showHelp();
|
|
185
|
+
},
|
|
185
186
|
})
|
|
186
187
|
.strict()
|
|
187
188
|
.help()
|
package/lib/db/entities.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
2
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
3
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -8,27 +7,25 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
8
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
9
|
};
|
|
11
|
-
|
|
12
|
-
exports.KeyValuePair = void 0;
|
|
13
|
-
const typeorm_1 = require("typeorm");
|
|
10
|
+
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
|
14
11
|
let KeyValuePair = class KeyValuePair {
|
|
15
12
|
blockHash;
|
|
16
13
|
key;
|
|
17
14
|
value;
|
|
18
15
|
};
|
|
19
16
|
__decorate([
|
|
20
|
-
|
|
17
|
+
PrimaryColumn(),
|
|
21
18
|
__metadata("design:type", String)
|
|
22
19
|
], KeyValuePair.prototype, "blockHash", void 0);
|
|
23
20
|
__decorate([
|
|
24
|
-
|
|
21
|
+
PrimaryColumn(),
|
|
25
22
|
__metadata("design:type", String)
|
|
26
23
|
], KeyValuePair.prototype, "key", void 0);
|
|
27
24
|
__decorate([
|
|
28
|
-
|
|
25
|
+
Column({ nullable: true }),
|
|
29
26
|
__metadata("design:type", String)
|
|
30
27
|
], KeyValuePair.prototype, "value", void 0);
|
|
31
28
|
KeyValuePair = __decorate([
|
|
32
|
-
|
|
29
|
+
Entity()
|
|
33
30
|
], KeyValuePair);
|
|
34
|
-
|
|
31
|
+
export { KeyValuePair };
|
package/lib/db/index.js
CHANGED
|
@@ -1,34 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.openDb = void 0;
|
|
27
|
-
require("reflect-metadata");
|
|
28
|
-
const typeorm_1 = require("typeorm");
|
|
29
|
-
const entities = __importStar(require("./entities"));
|
|
30
|
-
const openDb = async (dbPath) => {
|
|
31
|
-
const source = new typeorm_1.DataSource({
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { DataSource } from 'typeorm';
|
|
3
|
+
import * as entities from './entities';
|
|
4
|
+
export const openDb = async (dbPath) => {
|
|
5
|
+
const source = new DataSource({
|
|
32
6
|
type: 'sqlite',
|
|
33
7
|
database: dbPath,
|
|
34
8
|
entities: Object.values(entities),
|
|
@@ -38,4 +12,3 @@ const openDb = async (dbPath) => {
|
|
|
38
12
|
await source.initialize();
|
|
39
13
|
return source;
|
|
40
14
|
};
|
|
41
|
-
exports.openDb = openDb;
|
package/lib/dry-run-preimage.js
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const setup_1 = require("./setup");
|
|
13
|
-
const dryRunPreimage = async (argv) => {
|
|
14
|
-
const context = await (0, setup_1.setup)(argv);
|
|
1
|
+
import { blake2AsHex } from '@polkadot/util-crypto';
|
|
2
|
+
import { hexToU8a } from '@polkadot/util';
|
|
3
|
+
import { defaultLogger } from './logger';
|
|
4
|
+
import { generateHtmlDiffPreviewFile } from './utils/generate-html-diff';
|
|
5
|
+
import { newHeader } from './blockchain/block-builder';
|
|
6
|
+
import { openHtml } from './utils/open-html';
|
|
7
|
+
import { runTask, taskHandler } from './executor';
|
|
8
|
+
import { setStorage } from './utils/set-storage';
|
|
9
|
+
import { setup } from './setup';
|
|
10
|
+
export const dryRunPreimage = async (argv) => {
|
|
11
|
+
const context = await setup(argv);
|
|
15
12
|
const extrinsic = argv['preimage'];
|
|
16
13
|
const block = context.chain.head;
|
|
17
14
|
const registry = await block.registry;
|
|
18
|
-
const header = await
|
|
19
|
-
const data =
|
|
20
|
-
const hash =
|
|
21
|
-
await
|
|
15
|
+
const header = await newHeader(block);
|
|
16
|
+
const data = hexToU8a(extrinsic);
|
|
17
|
+
const hash = blake2AsHex(data, 256);
|
|
18
|
+
await setStorage(context.chain, {
|
|
22
19
|
Preimage: {
|
|
23
20
|
PreimageFor: [[[[hash, data.byteLength]], extrinsic]],
|
|
24
21
|
StatusFor: [
|
|
@@ -60,21 +57,21 @@ const dryRunPreimage = async (argv) => {
|
|
|
60
57
|
calls.push(['BlockBuilder_apply_extrinsic', [inherent]]);
|
|
61
58
|
}
|
|
62
59
|
calls.push(['BlockBuilder_finalize_block', []]);
|
|
63
|
-
|
|
64
|
-
const result = await
|
|
60
|
+
defaultLogger.info({ preimage: registry.createType('Call', data).toHuman() }, 'Dry run preimage');
|
|
61
|
+
const result = await runTask({
|
|
65
62
|
wasm: await block.wasm,
|
|
66
63
|
calls,
|
|
67
64
|
storage: [],
|
|
68
65
|
mockSignatureHost: false,
|
|
69
66
|
allowUnresolvedImports: false,
|
|
70
|
-
},
|
|
67
|
+
}, taskHandler(block));
|
|
71
68
|
if (result.Error) {
|
|
72
69
|
throw new Error(result.Error);
|
|
73
70
|
}
|
|
74
|
-
const filePath = await
|
|
71
|
+
const filePath = await generateHtmlDiffPreviewFile(block, result.Call.storageDiff, hash);
|
|
75
72
|
console.log(`Generated preview ${filePath}`);
|
|
76
73
|
if (argv['open']) {
|
|
77
|
-
|
|
74
|
+
openHtml(filePath);
|
|
78
75
|
}
|
|
79
76
|
// if dry-run preimage has extrinsic arguments then dry-run extrinsic
|
|
80
77
|
// this is usefull to test something after preimage is applied
|
|
@@ -86,14 +83,13 @@ const dryRunPreimage = async (argv) => {
|
|
|
86
83
|
throw new Error(outcome.asErr.toString());
|
|
87
84
|
}
|
|
88
85
|
else {
|
|
89
|
-
|
|
86
|
+
defaultLogger.info(outcome.toHuman(), 'dry_run_outcome');
|
|
90
87
|
}
|
|
91
|
-
const filePath = await
|
|
88
|
+
const filePath = await generateHtmlDiffPreviewFile(context.chain.head, storageDiff, blake2AsHex(argv['extrinsic'], 256));
|
|
92
89
|
console.log(`Generated preview ${filePath}`);
|
|
93
90
|
if (argv['open']) {
|
|
94
|
-
|
|
91
|
+
openHtml(filePath);
|
|
95
92
|
}
|
|
96
93
|
}
|
|
97
94
|
process.exit(0);
|
|
98
95
|
};
|
|
99
|
-
exports.dryRunPreimage = dryRunPreimage;
|
package/lib/dry-run.js
CHANGED
|
@@ -1,35 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const setup_1 = require("./setup");
|
|
10
|
-
const dryRun = async (argv) => {
|
|
11
|
-
const context = await (0, setup_1.setup)(argv);
|
|
1
|
+
import { blake2AsHex } from '@polkadot/util-crypto';
|
|
2
|
+
import { writeFileSync } from 'node:fs';
|
|
3
|
+
import { defaultLogger } from './logger';
|
|
4
|
+
import { generateHtmlDiffPreviewFile } from './utils/generate-html-diff';
|
|
5
|
+
import { openHtml } from './utils/open-html';
|
|
6
|
+
import { setup } from './setup';
|
|
7
|
+
export const dryRun = async (argv) => {
|
|
8
|
+
const context = await setup(argv);
|
|
12
9
|
const input = argv['address'] ? { call: argv['extrinsic'], address: argv['address'] } : argv['extrinsic'];
|
|
13
10
|
const { outcome, storageDiff } = await context.chain.dryRunExtrinsic(input, argv['at']);
|
|
14
11
|
if (outcome.isErr) {
|
|
15
12
|
throw new Error(outcome.asErr.toString());
|
|
16
13
|
}
|
|
17
14
|
else {
|
|
18
|
-
|
|
15
|
+
defaultLogger.info(outcome.toHuman(), 'dry_run_outcome');
|
|
19
16
|
}
|
|
20
17
|
if (argv['html']) {
|
|
21
|
-
const filePath = await
|
|
18
|
+
const filePath = await generateHtmlDiffPreviewFile(context.chain.head, storageDiff, blake2AsHex(argv['extrinsic'], 256));
|
|
22
19
|
console.log(`Generated preview ${filePath}`);
|
|
23
20
|
if (argv['open']) {
|
|
24
|
-
|
|
21
|
+
openHtml(filePath);
|
|
25
22
|
}
|
|
26
23
|
}
|
|
27
24
|
else if (argv['output-path']) {
|
|
28
|
-
|
|
25
|
+
writeFileSync(argv['output-path'], JSON.stringify({ outcome: outcome.toHuman(), storageDiff }, null, 2));
|
|
29
26
|
}
|
|
30
27
|
else {
|
|
31
28
|
console.dir({ outcome: outcome.toHuman(), storageDiff }, { depth: null, colors: false });
|
|
32
29
|
}
|
|
33
30
|
process.exit(0);
|
|
34
31
|
};
|
|
35
|
-
exports.dryRun = dryRun;
|