@acala-network/chopsticks 0.4.1 → 0.4.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.
@@ -71,8 +71,11 @@ const newHeader = async (head) => {
71
71
  ],
72
72
  },
73
73
  ...consensus.rest,
74
- head.pushStorageLayer().set((0, utils_1.compactHex)(meta.query.randomness.notFirstBlock()), "Deleted" /* StorageValueKind.Deleted */),
75
74
  ];
75
+ if (meta.query.randomness) {
76
+ // reset notFirstBlock so randomness will skip validation
77
+ head.pushStorageLayer().set((0, utils_1.compactHex)(meta.query.randomness.notFirstBlock()), "Deleted" /* StorageValueKind.Deleted */);
78
+ }
76
79
  }
77
80
  const header = meta.registry.createType('Header', {
78
81
  parentHash: head.hash,
@@ -4,7 +4,7 @@ import { HexString } from '@polkadot/util/types';
4
4
  import { RegisteredTypes } from '@polkadot/types/types';
5
5
  import { Api } from '../api';
6
6
  import { Block } from './block';
7
- import { BuildBlockMode, BuildBlockParams, HorizontalMessage, TxPool, UpcomingBlockParams } from './txpool';
7
+ import { BuildBlockMode, BuildBlockParams, DownwardMessage, HorizontalMessage, TxPool, UpcomingBlockParams } from './txpool';
8
8
  import { HeadState } from './head-state';
9
9
  import { InherentProvider } from './inherent';
10
10
  export interface Options {
@@ -46,6 +46,8 @@ export declare class Blockchain {
46
46
  outcome: ApplyExtrinsicResult;
47
47
  storageDiff: [HexString, HexString | null][];
48
48
  }>;
49
- dryRunHrmp(hrmp: Record<number, HorizontalMessage[]>): Promise<[HexString, HexString | null][]>;
49
+ dryRunHrmp(hrmp: Record<number, HorizontalMessage[]>, at?: HexString): Promise<[HexString, HexString | null][]>;
50
+ dryRunDmp(dmp: DownwardMessage[], at?: HexString): Promise<[HexString, HexString | null][]>;
51
+ dryRunUmp(ump: Record<number, HexString[]>, at?: HexString): Promise<[HexString, HexString | null][]>;
50
52
  getInherents(): Promise<HexString[]>;
51
53
  }
@@ -6,6 +6,7 @@ const util_1 = require("@polkadot/util");
6
6
  const block_1 = require("./block");
7
7
  const txpool_1 = require("./txpool");
8
8
  const head_state_1 = require("./head-state");
9
+ const utils_1 = require("../utils");
9
10
  const logger_1 = require("../logger");
10
11
  const block_builder_1 = require("./block-builder");
11
12
  const logger = logger_1.defaultLogger.child({ name: 'blockchain' });
@@ -136,12 +137,50 @@ class Blockchain {
136
137
  const outcome = registry.createType('ApplyExtrinsicResult', result);
137
138
  return { outcome, storageDiff };
138
139
  }
139
- async dryRunHrmp(hrmp) {
140
+ async dryRunHrmp(hrmp, at) {
140
141
  await this.api.isReady;
141
- const head = this.head;
142
+ const head = at ? await this.getBlock(at) : this.head;
143
+ if (!head) {
144
+ throw new Error(`Cannot find block ${at}`);
145
+ }
142
146
  const inherents = await this.#inherentProvider.createInherents(head, { horizontalMessages: hrmp });
143
147
  return (0, block_builder_1.dryRunInherents)(head, inherents);
144
148
  }
149
+ async dryRunDmp(dmp, at) {
150
+ await this.api.isReady;
151
+ const head = at ? await this.getBlock(at) : this.head;
152
+ if (!head) {
153
+ throw new Error(`Cannot find block ${at}`);
154
+ }
155
+ const inherents = await this.#inherentProvider.createInherents(head, { downwardMessages: dmp });
156
+ return (0, block_builder_1.dryRunInherents)(head, inherents);
157
+ }
158
+ async dryRunUmp(ump, at) {
159
+ await this.api.isReady;
160
+ const head = at ? await this.getBlock(at) : this.head;
161
+ if (!head) {
162
+ throw new Error(`Cannot find block ${at}`);
163
+ }
164
+ const meta = await head.meta;
165
+ const needsDispatch = meta.registry.createType('Vec<u32>', Object.keys(ump));
166
+ const stroageValues = [
167
+ [(0, utils_1.compactHex)(meta.query.ump.needsDispatch()), needsDispatch.toHex()],
168
+ ];
169
+ for (const [paraId, messages] of Object.entries(ump)) {
170
+ const upwardMessages = meta.registry.createType('Vec<Bytes>', messages);
171
+ if (upwardMessages.length === 0)
172
+ throw new Error('No upward meesage');
173
+ const queueSize = meta.registry.createType('(u32, u32)', [
174
+ upwardMessages.length,
175
+ upwardMessages.map((x) => x.byteLength).reduce((s, i) => s + i, 0),
176
+ ]);
177
+ stroageValues.push([(0, utils_1.compactHex)(meta.query.ump.relayDispatchQueues(paraId)), upwardMessages.toHex()]);
178
+ stroageValues.push([(0, utils_1.compactHex)(meta.query.ump.relayDispatchQueueSize(paraId)), queueSize.toHex()]);
179
+ }
180
+ head.pushStorageLayer().setAll(stroageValues);
181
+ const inherents = await this.#inherentProvider.createInherents(head);
182
+ return (0, block_builder_1.dryRunInherents)(head, inherents);
183
+ }
145
184
  async getInherents() {
146
185
  await this.api.isReady;
147
186
  const inherents = await this.#inherentProvider.createInherents(this.head);
@@ -1,16 +1,10 @@
1
1
  import { HexString } from '@polkadot/util/types';
2
2
  import { Block } from '../../block';
3
- import { BuildBlockParams } from '../../txpool';
3
+ import { BuildBlockParams, DownwardMessage, HorizontalMessage } from '../../txpool';
4
4
  import { CreateInherents } from '..';
5
5
  export type ValidationData = {
6
- downwardMessages: {
7
- sent_at: number;
8
- msg: HexString;
9
- }[];
10
- horizontalMessages: Record<number, {
11
- sent_at: number;
12
- data: HexString;
13
- }[]>;
6
+ downwardMessages: DownwardMessage[];
7
+ horizontalMessages: Record<number, HorizontalMessage[]>;
14
8
  validationData: {
15
9
  relayParentNumber: number;
16
10
  relayParentStorageRoot: HexString;
@@ -80,7 +80,7 @@ class SetValidationData {
80
80
  dmqMqcHeadHash = (0, util_crypto_1.blake2AsHex)((0, util_1.u8aConcat)(meta.registry.createType('Hash', dmqMqcHeadHash).toU8a(), meta.registry.createType('BlockNumber', sentAt).toU8a(), (0, util_crypto_1.blake2AsU8a)(meta.registry.createType('Bytes', msg).toU8a(), 256)), 256);
81
81
  downwardMessages.push({
82
82
  msg,
83
- sent_at: sentAt,
83
+ sentAt,
84
84
  });
85
85
  }
86
86
  newEntries.push([dmqMqcHeadKey, dmqMqcHeadHash]);
@@ -92,6 +92,7 @@ class SetValidationData {
92
92
  .createType('Vec<ParaId>', decoded[hrmpEgressChannelIndexKey])
93
93
  .toJSON();
94
94
  const hrmpMessages = {
95
+ // reset values, we just need the keys
95
96
  ...lodash_1.default.mapValues(extrinsic.horizontalMessages, () => []),
96
97
  ...(params?.horizontalMessages || {}),
97
98
  };
@@ -120,7 +121,7 @@ class SetValidationData {
120
121
  abridgedHrmp.totalSize = abridgedHrmp.totalSize + bytes.length;
121
122
  paraMessages.push({
122
123
  data,
123
- sent_at: sentAt,
124
+ sentAt,
124
125
  });
125
126
  }
126
127
  horizontalMessages[sender] = paraMessages;
@@ -0,0 +1,2 @@
1
+ import { Handler } from '../shared';
2
+ export declare const dev_dryRun: Handler;
@@ -0,0 +1,75 @@
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.dev_dryRun = void 0;
7
+ const zod_1 = __importDefault(require("zod"));
8
+ const decoder_1 = require("../../utils/decoder");
9
+ const generate_html_diff_1 = require("../../utils/generate-html-diff");
10
+ const zHex = zod_1.default.custom((val) => /^0x\w+$/.test(val));
11
+ const zHash = zod_1.default.string().length(66).and(zHex);
12
+ const zParaId = zod_1.default.string().regex(/^\d+$/).transform(Number);
13
+ const dryRunSchema = zod_1.default.object({
14
+ raw: zod_1.default.boolean().optional(),
15
+ html: zod_1.default.boolean().optional(),
16
+ extrinsic: zHex
17
+ .or(zod_1.default.object({
18
+ call: zHex,
19
+ address: zHex,
20
+ }))
21
+ .optional(),
22
+ hrmp: zod_1.default
23
+ .record(zParaId, zod_1.default
24
+ .array(zod_1.default.object({
25
+ sentAt: zod_1.default.number(),
26
+ data: zHex,
27
+ }))
28
+ .min(1))
29
+ .optional(),
30
+ dmp: zod_1.default
31
+ .array(zod_1.default.object({
32
+ sentAt: zod_1.default.number(),
33
+ msg: zHex,
34
+ }))
35
+ .min(1)
36
+ .optional(),
37
+ ump: zod_1.default.record(zParaId, zod_1.default.array(zHex).min(1)).optional(),
38
+ at: zHash.optional(),
39
+ });
40
+ const dev_dryRun = async (context, [params]) => {
41
+ const { html, extrinsic, hrmp, dmp, ump, raw, at } = dryRunSchema.parse(params);
42
+ const dryRun = async () => {
43
+ if (extrinsic) {
44
+ const { outcome, storageDiff } = await context.chain.dryRunExtrinsic(extrinsic, at);
45
+ if (outcome.isErr) {
46
+ throw new Error(outcome.asErr.toString());
47
+ }
48
+ return storageDiff;
49
+ }
50
+ if (hrmp) {
51
+ return context.chain.dryRunHrmp(hrmp, at);
52
+ }
53
+ if (dmp) {
54
+ return context.chain.dryRunDmp(dmp, at);
55
+ }
56
+ if (ump) {
57
+ return context.chain.dryRunUmp(ump, at);
58
+ }
59
+ throw new Error('No extrinsic to run');
60
+ };
61
+ const storageDiff = await dryRun();
62
+ if (html) {
63
+ return (0, generate_html_diff_1.generateHtmlDiff)(context.chain.head, storageDiff);
64
+ }
65
+ if (raw) {
66
+ return storageDiff;
67
+ }
68
+ const [oldData, newData, delta] = await (0, decoder_1.decodeStorageDiff)(context.chain.head, storageDiff);
69
+ return {
70
+ old: oldData,
71
+ new: newData,
72
+ delta,
73
+ };
74
+ };
75
+ exports.dev_dryRun = dev_dryRun;
@@ -1,3 +1,3 @@
1
- import { Handlers } from './shared';
1
+ import { Handlers } from '../shared';
2
2
  declare const handlers: Handlers;
3
3
  export default handlers;
@@ -1,11 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const shared_1 = require("./shared");
4
- const set_storage_1 = require("../utils/set-storage");
5
- const decoder_1 = require("../utils/decoder");
6
- const logger_1 = require("../logger");
7
- const generate_html_diff_1 = require("../utils/generate-html-diff");
8
- const time_travel_1 = require("../utils/time-travel");
3
+ const shared_1 = require("../shared");
4
+ const set_storage_1 = require("../../utils/set-storage");
5
+ const logger_1 = require("../../logger");
6
+ const dry_run_1 = require("./dry-run");
7
+ const time_travel_1 = require("../../utils/time-travel");
9
8
  const logger = logger_1.defaultLogger.child({ name: 'rpc-dev' });
10
9
  const handlers = {
11
10
  dev_newBlock: async (context, [param]) => {
@@ -41,31 +40,6 @@ const handlers = {
41
40
  await (0, time_travel_1.timeTravel)(context.chain, timestamp);
42
41
  return timestamp;
43
42
  },
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
43
  dev_setHead: async (context, [hashOrNumber]) => {
70
44
  let block;
71
45
  if (typeof hashOrNumber === 'number') {
@@ -81,5 +55,6 @@ const handlers = {
81
55
  await context.chain.setHead(block);
82
56
  return block.hash;
83
57
  },
58
+ dev_dryRun: dry_run_1.dev_dryRun,
84
59
  };
85
60
  exports.default = handlers;
package/lib/xcm/upward.js CHANGED
@@ -8,26 +8,25 @@ const connectUpward = async (parachain, relaychain) => {
8
8
  const meta = await parachain.head.meta;
9
9
  const paraId = await (0, utils_1.getParaId)(parachain);
10
10
  const upwardMessagesKey = (0, utils_1.compactHex)(meta.query.parachainSystem.upwardMessages());
11
- await parachain.headState.subscribeStorage([upwardMessagesKey], async (head, pairs) => {
11
+ await parachain.headState.subscribeStorage([upwardMessagesKey], async (_head, pairs) => {
12
12
  const value = pairs[0][1];
13
13
  if (!value)
14
14
  return;
15
- const parachainMeta = await head.meta;
16
- const relaychainMeta = await relaychain.head.meta;
17
- const upwardMessages = parachainMeta.registry.createType('Vec<Bytes>', (0, util_1.hexToU8a)(value));
15
+ const meta = await relaychain.head.meta;
16
+ const upwardMessages = meta.registry.createType('Vec<Bytes>', (0, util_1.hexToU8a)(value));
18
17
  if (upwardMessages.length === 0)
19
18
  return;
20
- const queueSize = parachainMeta.registry.createType('(u32, u32)', [
19
+ const queueSize = meta.registry.createType('(u32, u32)', [
21
20
  upwardMessages.length,
22
21
  upwardMessages.map((x) => x.byteLength).reduce((s, i) => s + i, 0),
23
22
  ]);
24
- const needsDispatch = parachainMeta.registry.createType('Vec<u32>', [paraId]);
23
+ const needsDispatch = meta.registry.createType('Vec<u32>', [paraId]);
25
24
  _1.logger.debug({ [paraId.toNumber()]: upwardMessages.toJSON(), queueSize: queueSize.toJSON() }, 'upward_message');
26
25
  // TODO: make sure we append instead of replace
27
26
  relaychain.head.pushStorageLayer().setAll([
28
- [(0, utils_1.compactHex)(relaychainMeta.query.ump.needsDispatch()), needsDispatch.toHex()],
29
- [(0, utils_1.compactHex)(relaychainMeta.query.ump.relayDispatchQueues(paraId)), upwardMessages.toHex()],
30
- [(0, utils_1.compactHex)(relaychainMeta.query.ump.relayDispatchQueueSize(paraId)), queueSize.toHex()],
27
+ [(0, utils_1.compactHex)(meta.query.ump.needsDispatch()), needsDispatch.toHex()],
28
+ [(0, utils_1.compactHex)(meta.query.ump.relayDispatchQueues(paraId)), upwardMessages.toHex()],
29
+ [(0, utils_1.compactHex)(meta.query.ump.relayDispatchQueueSize(paraId)), queueSize.toHex()],
31
30
  ]);
32
31
  await relaychain.newBlock();
33
32
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acala-network/chopsticks",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "main": "./lib/index.js",
5
5
  "types": "./lib/index.d.ts",
6
6
  "author": "Bryan Chen <xlchen1291@gmail.com>",
@@ -12,7 +12,7 @@
12
12
  "build": "rm -rf lib && tsc -p ./tsconfig.json",
13
13
  "test": "vitest run",
14
14
  "test:watch": "vitest",
15
- "script:start": "cd ../..; ts-node packages/chopsticks/src/cli.ts",
15
+ "script:start": "cd ../..; ts-node --transpile-only packages/chopsticks/src/cli.ts",
16
16
  "script:run": "LOG_LEVEL=trace ts-node-dev --transpile-only --inspect --notify=false src/cli.ts -- dev --config=../../configs/dev.yml",
17
17
  "dev:karura": "ts-node-dev --transpile-only --inspect --notify=false src/cli.ts -- dev --config=../../configs/karura.yml",
18
18
  "dev:acala": "ts-node-dev --transpile-only --inspect --notify=false src/cli.ts -- dev --config=../../configs/acala.yml",
@@ -20,7 +20,7 @@
20
20
  "dev:moonbeam": "ts-node-dev --transpile-only --inspect --notify=false src/cli.ts -- dev --config=../../configs/moonbeam.yml"
21
21
  },
22
22
  "dependencies": {
23
- "@acala-network/chopsticks-executor": "0.4.1",
23
+ "@acala-network/chopsticks-executor": "0.4.2",
24
24
  "@polkadot/api": "^9.14.2",
25
25
  "@polkadot/rpc-provider": "^9.14.2",
26
26
  "@polkadot/types": "^9.14.2",
@@ -35,6 +35,7 @@
35
35
  "pino": "^8.11.0",
36
36
  "pino-pretty": "^9.4.0",
37
37
  "reflect-metadata": "^0.1.13",
38
+ "rxjs": "^7.8.0",
38
39
  "sqlite3": "^5.1.4",
39
40
  "typeorm": "^0.3.12",
40
41
  "ws": "^8.12.1",
@@ -147,10 +147,10 @@
147
147
 
148
148
  function renderDelta(value) {
149
149
  if (/^\d+(,\d+)*$/.test(value[0]) && /^\d+(,\d+)*$/.test(value[1])) {
150
- const oldValue = parseInt(value[0].replace(/,/g, ''))
151
- const newValue = parseInt(value[1].replace(/,/g, ''))
150
+ const oldValue = BigInt(value[0].replace(/,/g, ''))
151
+ const newValue = BigInt(value[1].replace(/,/g, ''))
152
152
  if (oldValue > 0 && newValue > 0) {
153
- const delta = Number(newValue - oldValue)
153
+ const delta = newValue - oldValue
154
154
  return (<span className="delta" >{delta > 0 ? '+' : ''}{delta.toLocaleString()}</span>)
155
155
  }
156
156
  }