@acala-network/chopsticks-core 0.9.7 → 0.9.8-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.
Files changed (71) hide show
  1. package/dist/cjs/api.d.ts +1 -0
  2. package/dist/cjs/api.js +26 -0
  3. package/dist/cjs/blockchain/block-builder.d.ts +6 -4
  4. package/dist/cjs/blockchain/block-builder.js +25 -20
  5. package/dist/cjs/blockchain/block.js +1 -3
  6. package/dist/cjs/blockchain/index.d.ts +4 -4
  7. package/dist/cjs/blockchain/index.js +19 -26
  8. package/dist/cjs/blockchain/inherent/index.d.ts +8 -15
  9. package/dist/cjs/blockchain/inherent/index.js +13 -100
  10. package/dist/cjs/blockchain/inherent/para-enter.d.ts +3 -3
  11. package/dist/cjs/blockchain/inherent/para-enter.js +3 -1
  12. package/dist/cjs/blockchain/inherent/parachain/babe-randomness.d.ts +3 -3
  13. package/dist/cjs/blockchain/inherent/parachain/babe-randomness.js +3 -1
  14. package/dist/cjs/blockchain/inherent/parachain/nimbus-author-inherent.d.ts +3 -3
  15. package/dist/cjs/blockchain/inherent/parachain/nimbus-author-inherent.js +20 -1
  16. package/dist/cjs/blockchain/inherent/parachain/validation-data.d.ts +3 -3
  17. package/dist/cjs/blockchain/inherent/parachain/validation-data.js +3 -1
  18. package/dist/cjs/blockchain/inherent/timestamp.d.ts +6 -0
  19. package/dist/cjs/blockchain/inherent/timestamp.js +24 -0
  20. package/dist/cjs/blockchain/storage-layer.js +125 -69
  21. package/dist/cjs/blockchain/txpool.d.ts +1 -1
  22. package/dist/cjs/blockchain/txpool.js +6 -8
  23. package/dist/cjs/logger.d.ts +2 -12
  24. package/dist/cjs/logger.js +8 -2
  25. package/dist/cjs/rpc/shared.d.ts +1 -6
  26. package/dist/cjs/setup.js +7 -13
  27. package/dist/cjs/utils/decoder.js +1 -1
  28. package/dist/cjs/utils/index.d.ts +5 -0
  29. package/dist/cjs/utils/index.js +46 -5
  30. package/dist/cjs/utils/key-cache.d.ts +2 -1
  31. package/dist/cjs/utils/key-cache.js +27 -25
  32. package/dist/cjs/utils/time-travel.d.ts +0 -3
  33. package/dist/cjs/utils/time-travel.js +4 -37
  34. package/dist/cjs/wasm-executor/index.js +2 -3
  35. package/dist/cjs/xcm/index.d.ts +1 -6
  36. package/dist/esm/api.d.ts +1 -0
  37. package/dist/esm/api.js +21 -0
  38. package/dist/esm/blockchain/block-builder.d.ts +6 -4
  39. package/dist/esm/blockchain/block-builder.js +24 -19
  40. package/dist/esm/blockchain/block.js +1 -3
  41. package/dist/esm/blockchain/index.d.ts +4 -4
  42. package/dist/esm/blockchain/index.js +19 -26
  43. package/dist/esm/blockchain/inherent/index.d.ts +8 -15
  44. package/dist/esm/blockchain/inherent/index.js +12 -32
  45. package/dist/esm/blockchain/inherent/para-enter.d.ts +3 -3
  46. package/dist/esm/blockchain/inherent/para-enter.js +3 -1
  47. package/dist/esm/blockchain/inherent/parachain/babe-randomness.d.ts +3 -3
  48. package/dist/esm/blockchain/inherent/parachain/babe-randomness.js +3 -1
  49. package/dist/esm/blockchain/inherent/parachain/nimbus-author-inherent.d.ts +3 -3
  50. package/dist/esm/blockchain/inherent/parachain/nimbus-author-inherent.js +20 -1
  51. package/dist/esm/blockchain/inherent/parachain/validation-data.d.ts +3 -3
  52. package/dist/esm/blockchain/inherent/parachain/validation-data.js +3 -1
  53. package/dist/esm/blockchain/inherent/timestamp.d.ts +6 -0
  54. package/dist/esm/blockchain/inherent/timestamp.js +14 -0
  55. package/dist/esm/blockchain/storage-layer.js +121 -27
  56. package/dist/esm/blockchain/txpool.d.ts +1 -1
  57. package/dist/esm/blockchain/txpool.js +5 -7
  58. package/dist/esm/logger.d.ts +2 -12
  59. package/dist/esm/logger.js +8 -2
  60. package/dist/esm/rpc/shared.d.ts +1 -6
  61. package/dist/esm/setup.js +2 -8
  62. package/dist/esm/utils/decoder.js +1 -1
  63. package/dist/esm/utils/index.d.ts +5 -0
  64. package/dist/esm/utils/index.js +33 -5
  65. package/dist/esm/utils/key-cache.d.ts +2 -1
  66. package/dist/esm/utils/key-cache.js +25 -14
  67. package/dist/esm/utils/time-travel.d.ts +0 -3
  68. package/dist/esm/utils/time-travel.js +2 -21
  69. package/dist/esm/wasm-executor/index.js +1 -2
  70. package/dist/esm/xcm/index.d.ts +1 -6
  71. package/package.json +13 -13
@@ -2,17 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: all[name]
9
- });
10
- }
11
- _export(exports, {
12
- PREFIX_LENGTH: function() {
13
- return PREFIX_LENGTH;
14
- },
15
- default: function() {
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: function() {
16
8
  return KeyCache;
17
9
  }
18
10
  });
@@ -35,21 +27,20 @@ function _interop_require_default(obj) {
35
27
  default: obj
36
28
  };
37
29
  }
38
- const PREFIX_LENGTH = 66;
39
30
  class KeyCache {
40
31
  feed(keys) {
41
- const _keys = keys.filter((key)=>key.length >= PREFIX_LENGTH);
32
+ const _keys = keys.filter((key)=>key.length >= this.prefixLength);
42
33
  if (_keys.length === 0) return;
43
- const startKey = _keys[0].slice(PREFIX_LENGTH);
44
- const endKey = _keys[_keys.length - 1].slice(PREFIX_LENGTH);
45
- const grouped = _lodash.default.groupBy(_keys, (key)=>key.slice(0, PREFIX_LENGTH));
34
+ const startKey = _keys[0].slice(this.prefixLength);
35
+ const endKey = _keys[_keys.length - 1].slice(this.prefixLength);
36
+ const grouped = _lodash.default.groupBy(_keys, (key)=>key.slice(0, this.prefixLength));
46
37
  for (const [prefix, keys] of Object.entries(grouped)){
47
38
  const ranges = this.ranges.filter((range)=>range.prefix === prefix);
48
39
  if (ranges.length === 0) {
49
40
  // no existing range with prefix
50
41
  this.ranges.push({
51
42
  prefix,
52
- keys: keys.map((i)=>i.slice(PREFIX_LENGTH))
43
+ keys: keys.map((i)=>i.slice(this.prefixLength))
53
44
  });
54
45
  continue;
55
46
  }
@@ -58,14 +49,14 @@ class KeyCache {
58
49
  const startPosition = _lodash.default.sortedIndex(range.keys, startKey);
59
50
  if (startPosition >= 0 && range.keys[startPosition] === startKey) {
60
51
  // found existing range with prefix
61
- range.keys.splice(startPosition, keys.length, ...keys.map((i)=>i.slice(PREFIX_LENGTH)));
52
+ range.keys.splice(startPosition, keys.length, ...keys.map((i)=>i.slice(this.prefixLength)));
62
53
  merged = true;
63
54
  break;
64
55
  }
65
56
  const endPosition = _lodash.default.sortedIndex(range.keys, endKey);
66
57
  if (endPosition >= 0 && range.keys[endPosition] === endKey) {
67
58
  // found existing range with prefix
68
- range.keys.splice(0, endPosition + 1, ...keys.map((i)=>i.slice(PREFIX_LENGTH)));
59
+ range.keys.splice(0, endPosition + 1, ...keys.map((i)=>i.slice(this.prefixLength)));
69
60
  merged = true;
70
61
  break;
71
62
  }
@@ -74,17 +65,25 @@ class KeyCache {
74
65
  if (!merged) {
75
66
  this.ranges.push({
76
67
  prefix,
77
- keys: keys.map((i)=>i.slice(PREFIX_LENGTH))
68
+ keys: keys.map((i)=>i.slice(this.prefixLength))
78
69
  });
79
70
  }
80
71
  }
81
72
  // TODO: merge ranges if they overlap
82
73
  }
83
74
  async next(startKey) {
84
- if (startKey.length < PREFIX_LENGTH) return;
85
- const prefix = startKey.slice(0, PREFIX_LENGTH);
86
- const key = startKey.slice(PREFIX_LENGTH);
75
+ if (startKey.length < this.prefixLength) return;
76
+ const prefix = startKey.slice(0, this.prefixLength);
77
+ const key = startKey.slice(this.prefixLength);
87
78
  for (const range of this.ranges.filter((range)=>range.prefix === prefix)){
79
+ if (key.length === 0) {
80
+ // if key is empty then find the range with first key empty
81
+ if (range.keys[0] !== '') continue;
82
+ return [
83
+ prefix,
84
+ range.keys[1]
85
+ ].join('');
86
+ }
88
87
  const index = _lodash.default.sortedIndex(range.keys, key);
89
88
  if (range.keys[index] !== key) continue;
90
89
  const nextKey = range.keys[index + 1];
@@ -96,7 +95,10 @@ class KeyCache {
96
95
  }
97
96
  }
98
97
  }
99
- constructor(){
100
- _define_property(this, "ranges", []);
98
+ constructor(prefixLength){
99
+ _define_property(this, "prefixLength", void 0);
100
+ _define_property(this, "ranges", void 0);
101
+ this.prefixLength = prefixLength;
102
+ this.ranges = [];
101
103
  }
102
104
  }
@@ -1,5 +1,2 @@
1
1
  import { Blockchain } from '../blockchain/index.js';
2
- export declare const getCurrentSlot: (chain: Blockchain) => Promise<number>;
3
- export declare const getCurrentTimestamp: (chain: Blockchain) => Promise<bigint>;
4
- export declare const getSlotDuration: (chain: Blockchain) => Promise<number>;
5
2
  export declare const timeTravel: (chain: Blockchain, timestamp: number) => Promise<void>;
@@ -2,51 +2,18 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: all[name]
9
- });
10
- }
11
- _export(exports, {
12
- getCurrentSlot: function() {
13
- return getCurrentSlot;
14
- },
15
- getCurrentTimestamp: function() {
16
- return getCurrentTimestamp;
17
- },
18
- getSlotDuration: function() {
19
- return getSlotDuration;
20
- },
21
- timeTravel: function() {
5
+ Object.defineProperty(exports, "timeTravel", {
6
+ enumerable: true,
7
+ get: function() {
22
8
  return timeTravel;
23
9
  }
24
10
  });
25
11
  const _util = require("@polkadot/util");
26
12
  const _index = require("./index.js");
27
- const _index1 = require("../wasm-executor/index.js");
28
13
  const _setstorage = require("./set-storage.js");
29
- const getCurrentSlot = async (chain)=>{
30
- const meta = await chain.head.meta;
31
- // use raw key here because some chain did not expose those storage to metadata
32
- const slotRaw = meta.consts.babe ? await chain.head.get('0x1cb6f36e027abb2091cfb5110ab5087f06155b3cd9a8c9e5e9a23fd5dc13a5ed') // babe.currentSlot
33
- : await chain.head.get('0x57f8dc2f5ab09467896f47300f04243806155b3cd9a8c9e5e9a23fd5dc13a5ed') // aura.currentSlot
34
- ;
35
- if (!slotRaw) throw new Error('Cannot find current slot');
36
- return meta.registry.createType('Slot', (0, _util.hexToU8a)(slotRaw)).toNumber();
37
- };
38
- const getCurrentTimestamp = async (chain)=>{
39
- const meta = await chain.head.meta;
40
- const timestamp = await chain.head.read('u64', meta.query.timestamp.now);
41
- return timestamp?.toBigInt() ?? 0n;
42
- };
43
- const getSlotDuration = async (chain)=>{
44
- const meta = await chain.head.meta;
45
- return meta.consts.babe ? meta.consts.babe.expectedBlockTime.toNumber() : meta.query.aura ? (0, _index1.getAuraSlotDuration)(await chain.head.wasm) : 12_000;
46
- };
47
14
  const timeTravel = async (chain, timestamp)=>{
48
15
  const meta = await chain.head.meta;
49
- const slotDuration = await getSlotDuration(chain);
16
+ const slotDuration = await (0, _index.getSlotDuration)(chain);
50
17
  const newSlot = Math.floor(timestamp / slotDuration);
51
18
  // new timestamp
52
19
  const storage = [
@@ -44,9 +44,8 @@ const _comlink = /*#__PURE__*/ _interop_require_wildcard(require("comlink"));
44
44
  const _util = require("@polkadot/util");
45
45
  const _utilcrypto = require("@polkadot/util-crypto");
46
46
  const _lodash = /*#__PURE__*/ _interop_require_default(require("lodash"));
47
- const _keycache = require("../utils/key-cache.js");
48
- const _logger = require("../logger.js");
49
47
  const _index = require("../utils/index.js");
48
+ const _logger = require("../logger.js");
50
49
  function _interop_require_default(obj) {
51
50
  return obj && obj.__esModule ? obj : {
52
51
  default: obj
@@ -160,7 +159,7 @@ const taskHandler = (block)=>{
160
159
  },
161
160
  getNextKey: async function(prefix, key) {
162
161
  const [nextKey] = await block.getKeysPaged({
163
- prefix: prefix.length === 2 /** 0x */ ? key.slice(0, _keycache.PREFIX_LENGTH) : prefix,
162
+ prefix: prefix.length === 2 /** 0x */ ? key.slice(0, _index.PREFIX_LENGTH) : prefix,
164
163
  pageSize: 1,
165
164
  startKey: key
166
165
  });
@@ -1,9 +1,4 @@
1
1
  import { Blockchain } from '../blockchain/index.js';
2
- export declare const xcmLogger: import("pino").default.Logger<{
3
- level: string;
4
- transport: {
5
- target: string;
6
- };
7
- }>;
2
+ export declare const xcmLogger: import("pino").default.Logger<never>;
8
3
  export declare const connectVertical: (relaychain: Blockchain, parachain: Blockchain) => Promise<void>;
9
4
  export declare const connectParachains: (parachains: Blockchain[]) => Promise<void>;
package/dist/esm/api.d.ts CHANGED
@@ -50,6 +50,7 @@ export declare class Api {
50
50
  getBlock(hash?: string): Promise<SignedBlock | null>;
51
51
  getStorage(key: string, hash?: string): Promise<`0x${string}` | null>;
52
52
  getKeysPaged(prefix: string, pageSize: number, startKey: string, hash?: string): Promise<string[]>;
53
+ getStorageBatch(prefix: HexString, keys: HexString[], hash?: HexString): Promise<[`0x${string}`, `0x${string}` | null][]>;
53
54
  subscribeRemoteNewHeads(cb: ProviderInterfaceCallback): Promise<string | number>;
54
55
  subscribeRemoteFinalizedHeads(cb: ProviderInterfaceCallback): Promise<string | number>;
55
56
  }
package/dist/esm/api.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { prefixedChildKey, splitChildKey, stripChildPrefix } from './utils/index.js';
2
+ import _ from 'lodash';
2
3
  /**
3
4
  * API class. Calls provider to get on-chain data.
4
5
  * Either `endpoint` or `genesis` porvider must be provided.
@@ -119,6 +120,26 @@ import { prefixedChildKey, splitChildKey, stripChildPrefix } from './utils/index
119
120
  return this.#provider.send('state_getKeysPaged', params, !!hash);
120
121
  }
121
122
  }
123
+ async getStorageBatch(prefix, keys, hash) {
124
+ const [child] = splitChildKey(prefix);
125
+ if (child) {
126
+ // child storage key, use childstate_getStorageEntries
127
+ // strip child prefix from keys
128
+ const params = [
129
+ child,
130
+ keys.map((key)=>stripChildPrefix(key))
131
+ ];
132
+ if (hash) params.push(hash);
133
+ return this.#provider.send('childstate_getStorageEntries', params, !!hash).then((values)=>_.zip(keys, values));
134
+ } else {
135
+ // main storage key, use state_getStorageAt
136
+ const params = [
137
+ keys
138
+ ];
139
+ if (hash) params.push(hash);
140
+ return this.#provider.send('state_queryStorageAt', params, !!hash).then((result)=>result[0]?.['changes'] || []);
141
+ }
142
+ }
122
143
  async subscribeRemoteNewHeads(cb) {
123
144
  if (!this.#provider.hasSubscriptions) {
124
145
  throw new Error('subscribeRemoteNewHeads only works with subscriptions');
@@ -1,15 +1,17 @@
1
1
  import { Header, TransactionValidityError } from '@polkadot/types/interfaces';
2
2
  import { Block } from './block.js';
3
+ import { BuildBlockParams } from './txpool.js';
3
4
  import { HexString } from '@polkadot/util/types';
5
+ import { InherentProvider } from './inherent/index.js';
4
6
  import { TaskCallResponse } from '../wasm-executor/index.js';
5
7
  export declare const newHeader: (head: Block, unsafeBlockHeight?: number) => Promise<Header>;
6
8
  export type BuildBlockCallbacks = {
7
9
  onApplyExtrinsicError?: (extrinsic: HexString, error: TransactionValidityError) => void;
8
10
  onPhaseApplied?: (phase: 'initialize' | 'finalize' | number, resp: TaskCallResponse) => void;
9
11
  };
10
- export declare const buildBlock: (head: Block, inherents: HexString[], extrinsics: HexString[], ump: Record<number, HexString[]>, callbacks?: BuildBlockCallbacks, unsafeBlockHeight?: number) => Promise<[Block, HexString[]]>;
11
- export declare const dryRunExtrinsic: (head: Block, inherents: HexString[], extrinsic: HexString | {
12
+ export declare const buildBlock: (head: Block, inherentProviders: InherentProvider[], params: BuildBlockParams, callbacks?: BuildBlockCallbacks) => Promise<[Block, HexString[]]>;
13
+ export declare const dryRunExtrinsic: (head: Block, inherentProviders: InherentProvider[], extrinsic: HexString | {
12
14
  call: HexString;
13
15
  address: string;
14
- }) => Promise<TaskCallResponse>;
15
- export declare const dryRunInherents: (head: Block, inherents: HexString[]) => Promise<[HexString, HexString | null][]>;
16
+ }, params: BuildBlockParams) => Promise<TaskCallResponse>;
17
+ export declare const dryRunInherents: (head: Block, inherentProviders: InherentProvider[], params: BuildBlockParams) => Promise<[HexString, HexString | null][]>;
@@ -1,9 +1,8 @@
1
1
  import { Block } from './block.js';
2
2
  import { StorageLayer, StorageValueKind } from './storage-layer.js';
3
3
  import { compactAddLength, hexToU8a, stringToHex, u8aConcat } from '@polkadot/util';
4
- import { compactHex } from '../utils/index.js';
4
+ import { compactHex, getCurrentSlot } from '../utils/index.js';
5
5
  import { defaultLogger, truncate } from '../logger.js';
6
- import { getCurrentSlot } from '../utils/time-travel.js';
7
6
  const logger = defaultLogger.child({
8
7
  name: 'block-builder'
9
8
  });
@@ -103,7 +102,7 @@ export const newHeader = async (head, unsafeBlockHeight)=>{
103
102
  });
104
103
  return header;
105
104
  };
106
- const initNewBlock = async (head, header, inherents, storageLayer, callback)=>{
105
+ const initNewBlock = async (head, header, inherentProviders, params, storageLayer, callback)=>{
107
106
  const blockNumber = header.number.toNumber();
108
107
  const hash = `0x${Math.round(Math.random() * 100000000).toString(16).padEnd(64, '0')}`;
109
108
  const newBlock = new Block(head.chain, blockNumber, hash, head, {
@@ -131,16 +130,20 @@ const initNewBlock = async (head, header, inherents, storageLayer, callback)=>{
131
130
  }
132
131
  callback?.onPhaseApplied?.('initialize', resp);
133
132
  }
133
+ const inherents = [];
134
134
  const layers = [];
135
135
  // apply inherents
136
- for (const extrinsic of inherents){
136
+ for (const inherentProvider of inherentProviders){
137
137
  try {
138
- const resp = await newBlock.call('BlockBuilder_apply_extrinsic', [
139
- extrinsic
140
- ]);
138
+ const extrinsics = await inherentProvider.createInherents(newBlock, params);
139
+ if (extrinsics.length === 0) {
140
+ continue;
141
+ }
142
+ const resp = await newBlock.call('BlockBuilder_apply_extrinsic', extrinsics);
141
143
  const layer = newBlock.pushStorageLayer();
142
144
  layer.setAll(resp.storageDiff);
143
145
  layers.push(layer);
146
+ inherents.push(...extrinsics);
144
147
  callback?.onPhaseApplied?.(layers.length - 1, resp);
145
148
  } catch (e) {
146
149
  logger.warn('Failed to apply inherents %o %s', e, e);
@@ -149,18 +152,20 @@ const initNewBlock = async (head, header, inherents, storageLayer, callback)=>{
149
152
  }
150
153
  return {
151
154
  block: newBlock,
152
- layers: layers
155
+ layers,
156
+ inherents
153
157
  };
154
158
  };
155
- export const buildBlock = async (head, inherents, extrinsics, ump, callbacks, unsafeBlockHeight)=>{
159
+ export const buildBlock = async (head, inherentProviders, params, callbacks)=>{
160
+ const { transactions: extrinsics, upwardMessages: ump, unsafeBlockHeight } = params;
156
161
  const registry = await head.registry;
157
162
  const header = await newHeader(head, unsafeBlockHeight);
158
163
  const newBlockNumber = header.number.toNumber();
159
164
  logger.info({
160
165
  number: newBlockNumber,
161
- extrinsicsCount: extrinsics.length,
166
+ extrinsics: extrinsics.map(truncate),
162
167
  umpCount: Object.keys(ump).length
163
- }, `Try building block #${newBlockNumber.toLocaleString()}`);
168
+ }, `${await head.chain.api.getSystemChain()} building #${newBlockNumber.toLocaleString()}`);
164
169
  let layer;
165
170
  // apply ump via storage override hack
166
171
  if (Object.keys(ump).length > 0) {
@@ -249,7 +254,7 @@ export const buildBlock = async (head, inherents, extrinsics, ump, callbacks, un
249
254
  layer.set(compactHex(meta.query.ump.needsDispatch()), needsDispatch.toHex());
250
255
  }
251
256
  }
252
- const { block: newBlock } = await initNewBlock(head, header, inherents, layer);
257
+ const { block: newBlock, inherents } = await initNewBlock(head, header, inherentProviders, params, layer);
253
258
  const pendingExtrinsics = [];
254
259
  const includedExtrinsic = [];
255
260
  // apply extrinsics
@@ -298,21 +303,21 @@ export const buildBlock = async (head, inherents, extrinsics, ump, callbacks, un
298
303
  storageDiff
299
304
  });
300
305
  logger.info({
301
- number: newBlock.number,
306
+ number: finalBlock.number,
302
307
  hash: finalBlock.hash,
303
308
  extrinsics: truncate(includedExtrinsic),
304
- pendingExtrinsicsCount: pendingExtrinsics.length,
309
+ pendingExtrinsics: pendingExtrinsics.map(truncate),
305
310
  ump: truncate(ump)
306
- }, 'Block built');
311
+ }, `${await head.chain.api.getSystemChain()} new head #${finalBlock.number.toLocaleString()}`);
307
312
  return [
308
313
  finalBlock,
309
314
  pendingExtrinsics
310
315
  ];
311
316
  };
312
- export const dryRunExtrinsic = async (head, inherents, extrinsic)=>{
317
+ export const dryRunExtrinsic = async (head, inherentProviders, extrinsic, params)=>{
313
318
  const registry = await head.registry;
314
319
  const header = await newHeader(head);
315
- const { block: newBlock } = await initNewBlock(head, header, inherents);
320
+ const { block: newBlock } = await initNewBlock(head, header, inherentProviders, params);
316
321
  if (typeof extrinsic !== 'string') {
317
322
  if (!head.chain.mockSignatureHost) {
318
323
  throw new Error('Cannot fake signature because mock signature host is not enabled. Start chain with `mockSignatureHost: true`');
@@ -351,9 +356,9 @@ export const dryRunExtrinsic = async (head, inherents, extrinsic)=>{
351
356
  extrinsic
352
357
  ]);
353
358
  };
354
- export const dryRunInherents = async (head, inherents)=>{
359
+ export const dryRunInherents = async (head, inherentProviders, params)=>{
355
360
  const header = await newHeader(head);
356
- const { layers } = await initNewBlock(head, header, inherents);
361
+ const { layers } = await initNewBlock(head, header, inherentProviders, params);
357
362
  const storage = {};
358
363
  for (const layer of layers){
359
364
  await layer.mergeInto(storage);
@@ -129,12 +129,10 @@ import { getRuntimeVersion, runTask, taskHandler } from '../wasm-executor/index.
129
129
  /**
130
130
  * Get paged storage keys.
131
131
  */ async getKeysPaged(options) {
132
- const layer = new StorageLayer(this.storage);
133
- await layer.fold();
134
132
  const prefix = options.prefix ?? '0x';
135
133
  const startKey = options.startKey ?? '0x';
136
134
  const pageSize = options.pageSize;
137
- return layer.getKeysPaged(prefix, pageSize, startKey);
135
+ return this.storage.getKeysPaged(prefix, pageSize, startKey);
138
136
  }
139
137
  /**
140
138
  * Push a layer to the storage stack.
@@ -17,7 +17,7 @@ export interface Options {
17
17
  /** Build block mode. Default to Batch. */
18
18
  buildBlockMode?: BuildBlockMode;
19
19
  /** Inherent provider, for creating inherents. */
20
- inherentProvider: InherentProvider;
20
+ inherentProviders: InherentProvider[];
21
21
  /** Datasource for caching storage and blocks data. */
22
22
  db?: Database;
23
23
  /** Used to create the initial head. */
@@ -48,7 +48,7 @@ export interface Options {
48
48
  * const chain = new Blockchain({
49
49
  * api,
50
50
  * buildBlockMode: BuildBlockMode.Manual,
51
- * inherentProvider: inherents,
51
+ * inherentProviders,
52
52
  * header: {
53
53
  * hash: blockHash,
54
54
  * number: Number(header.number),
@@ -79,7 +79,7 @@ export declare class Blockchain {
79
79
  /**
80
80
  * @param options - Options for instantiating the blockchain
81
81
  */
82
- constructor({ api, buildBlockMode, inherentProvider, db, header, mockSignatureHost, allowUnresolvedImports, runtimeLogLevel, registeredTypes, offchainWorker, maxMemoryBlockCount, }: Options);
82
+ constructor({ api, buildBlockMode, inherentProviders, db, header, mockSignatureHost, allowUnresolvedImports, runtimeLogLevel, registeredTypes, offchainWorker, maxMemoryBlockCount, }: Options);
83
83
  get head(): Block;
84
84
  get txPool(): TxPool;
85
85
  get runtimeLogLevel(): number;
@@ -163,7 +163,7 @@ export declare class Blockchain {
163
163
  /**
164
164
  * Get inherents of head.
165
165
  */
166
- getInherents(): Promise<HexString[]>;
166
+ getInherents(): InherentProvider[];
167
167
  /**
168
168
  * Close the db and disconnect api.
169
169
  */
@@ -23,7 +23,7 @@ const logger = defaultLogger.child({
23
23
  * const chain = new Blockchain({
24
24
  * api,
25
25
  * buildBlockMode: BuildBlockMode.Manual,
26
- * inherentProvider: inherents,
26
+ * inherentProviders,
27
27
  * header: {
28
28
  * hash: blockHash,
29
29
  * number: Number(header.number),
@@ -43,7 +43,7 @@ const logger = defaultLogger.child({
43
43
  #runtimeLogLevel;
44
44
  /** Polkadot.js custom types registration. */ registeredTypes;
45
45
  #txpool;
46
- #inherentProvider;
46
+ #inherentProviders;
47
47
  #head;
48
48
  #blocksByNumber = new Map();
49
49
  #blocksByHash = new Map();
@@ -65,7 +65,7 @@ const logger = defaultLogger.child({
65
65
  });
66
66
  /**
67
67
  * @param options - Options for instantiating the blockchain
68
- */ constructor({ api, buildBlockMode, inherentProvider, db, header, mockSignatureHost = false, allowUnresolvedImports = false, runtimeLogLevel = 0, registeredTypes = {}, offchainWorker = false, maxMemoryBlockCount = 500 }){
68
+ */ constructor({ api, buildBlockMode, inherentProviders, db, header, mockSignatureHost = false, allowUnresolvedImports = false, runtimeLogLevel = 0, registeredTypes = {}, offchainWorker = false, maxMemoryBlockCount = 500 }){
69
69
  this.api = api;
70
70
  this.db = db;
71
71
  this.mockSignatureHost = mockSignatureHost;
@@ -74,8 +74,8 @@ const logger = defaultLogger.child({
74
74
  this.registeredTypes = registeredTypes;
75
75
  this.#head = new Block(this, header.number, header.hash);
76
76
  this.#registerBlock(this.#head);
77
- this.#txpool = new TxPool(this, inherentProvider, buildBlockMode);
78
- this.#inherentProvider = inherentProvider;
77
+ this.#txpool = new TxPool(this, inherentProviders, buildBlockMode);
78
+ this.#inherentProviders = inherentProviders;
79
79
  this.headState = new HeadState(this.#head);
80
80
  if (offchainWorker) {
81
81
  this.offchainWorker = new OffchainWorker();
@@ -311,13 +311,13 @@ const logger = defaultLogger.child({
311
311
  throw new Error(`Cannot find block ${at}`);
312
312
  }
313
313
  const registry = await head.registry;
314
- const inherents = await this.#inherentProvider.createInherents(head, {
314
+ const params = {
315
315
  transactions: [],
316
316
  downwardMessages: [],
317
317
  upwardMessages: [],
318
318
  horizontalMessages: {}
319
- });
320
- const { result, storageDiff } = await dryRunExtrinsic(head, inherents, extrinsic);
319
+ };
320
+ const { result, storageDiff } = await dryRunExtrinsic(head, this.#inherentProviders, extrinsic, params);
321
321
  const outcome = registry.createType('ApplyExtrinsicResult', result);
322
322
  return {
323
323
  outcome,
@@ -333,13 +333,13 @@ const logger = defaultLogger.child({
333
333
  if (!head) {
334
334
  throw new Error(`Cannot find block ${at}`);
335
335
  }
336
- const inherents = await this.#inherentProvider.createInherents(head, {
336
+ const params = {
337
337
  transactions: [],
338
338
  downwardMessages: [],
339
339
  upwardMessages: [],
340
340
  horizontalMessages: hrmp
341
- });
342
- return dryRunInherents(head, inherents);
341
+ };
342
+ return dryRunInherents(head, this.#inherentProviders, params);
343
343
  }
344
344
  /**
345
345
  * Dry run dmp messages in block `at`.
@@ -350,13 +350,13 @@ const logger = defaultLogger.child({
350
350
  if (!head) {
351
351
  throw new Error(`Cannot find block ${at}`);
352
352
  }
353
- const inherents = await this.#inherentProvider.createInherents(head, {
353
+ const params = {
354
354
  transactions: [],
355
355
  downwardMessages: dmp,
356
356
  upwardMessages: [],
357
357
  horizontalMessages: {}
358
- });
359
- return dryRunInherents(head, inherents);
358
+ };
359
+ return dryRunInherents(head, this.#inherentProviders, params);
360
360
  }
361
361
  /**
362
362
  * Dry run ump messages in block `at`.
@@ -392,25 +392,18 @@ const logger = defaultLogger.child({
392
392
  ]);
393
393
  }
394
394
  head.pushStorageLayer().setAll(storageValues);
395
- const inherents = await this.#inherentProvider.createInherents(head, {
395
+ const params = {
396
396
  transactions: [],
397
397
  downwardMessages: [],
398
398
  upwardMessages: [],
399
399
  horizontalMessages: {}
400
- });
401
- return dryRunInherents(head, inherents);
400
+ };
401
+ return dryRunInherents(head, this.#inherentProviders, params);
402
402
  }
403
403
  /**
404
404
  * Get inherents of head.
405
- */ async getInherents() {
406
- await this.api.isReady;
407
- const inherents = await this.#inherentProvider.createInherents(this.head, {
408
- transactions: [],
409
- downwardMessages: [],
410
- upwardMessages: [],
411
- horizontalMessages: {}
412
- });
413
- return inherents;
405
+ */ getInherents() {
406
+ return this.#inherentProviders;
414
407
  }
415
408
  /**
416
409
  * Close the db and disconnect api.
@@ -1,19 +1,12 @@
1
1
  import { Block } from '../block.js';
2
2
  import { BuildBlockParams } from '../txpool.js';
3
3
  import { HexString } from '@polkadot/util/types';
4
- export { SetValidationData } from './parachain/validation-data.js';
5
- export { ParaInherentEnter } from './para-enter.js';
6
- export { SetBabeRandomness } from './parachain/babe-randomness.js';
7
- export { SetNimbusAuthorInherent } from './parachain/nimbus-author-inherent.js';
8
- export interface CreateInherents {
9
- createInherents(parent: Block, params: BuildBlockParams): Promise<HexString[]>;
10
- }
11
- export type InherentProvider = CreateInherents;
12
- export declare class SetTimestamp implements InherentProvider {
13
- createInherents(parent: Block): Promise<HexString[]>;
14
- }
15
- export declare class InherentProviders implements InherentProvider {
16
- #private;
17
- constructor(base: InherentProvider, providers: CreateInherents[]);
18
- createInherents(parent: Block, params: BuildBlockParams): Promise<HexString[]>;
4
+ import { ParaInherentEnter } from './para-enter.js';
5
+ import { SetBabeRandomness } from './parachain/babe-randomness.js';
6
+ import { SetNimbusAuthorInherent } from './parachain/nimbus-author-inherent.js';
7
+ import { SetTimestamp } from './timestamp.js';
8
+ import { SetValidationData } from './parachain/validation-data.js';
9
+ export interface InherentProvider {
10
+ createInherents(newBlock: Block, params: BuildBlockParams): Promise<HexString[]>;
19
11
  }
12
+ export declare const inherentProviders: (ParaInherentEnter | SetBabeRandomness | SetNimbusAuthorInherent | SetTimestamp | SetValidationData)[];
@@ -1,32 +1,12 @@
1
- import { GenericExtrinsic } from '@polkadot/types';
2
- import { getCurrentTimestamp, getSlotDuration } from '../../utils/time-travel.js';
3
- export { SetValidationData } from './parachain/validation-data.js';
4
- export { ParaInherentEnter } from './para-enter.js';
5
- export { SetBabeRandomness } from './parachain/babe-randomness.js';
6
- export { SetNimbusAuthorInherent } from './parachain/nimbus-author-inherent.js';
7
- export class SetTimestamp {
8
- async createInherents(parent) {
9
- const meta = await parent.meta;
10
- const slotDuration = await getSlotDuration(parent.chain);
11
- const currentTimestamp = await getCurrentTimestamp(parent.chain);
12
- return [
13
- new GenericExtrinsic(meta.registry, meta.tx.timestamp.set(currentTimestamp + BigInt(slotDuration))).toHex()
14
- ];
15
- }
16
- }
17
- export class InherentProviders {
18
- #base;
19
- #providers;
20
- constructor(base, providers){
21
- this.#base = base;
22
- this.#providers = providers;
23
- }
24
- async createInherents(parent, params) {
25
- const base = await this.#base.createInherents(parent, params);
26
- const extra = await Promise.all(this.#providers.map((provider)=>provider.createInherents(parent, params)));
27
- return [
28
- ...base,
29
- ...extra.flat()
30
- ];
31
- }
32
- }
1
+ import { ParaInherentEnter } from './para-enter.js';
2
+ import { SetBabeRandomness } from './parachain/babe-randomness.js';
3
+ import { SetNimbusAuthorInherent } from './parachain/nimbus-author-inherent.js';
4
+ import { SetTimestamp } from './timestamp.js';
5
+ import { SetValidationData } from './parachain/validation-data.js';
6
+ export const inherentProviders = [
7
+ new SetTimestamp(),
8
+ new SetValidationData(),
9
+ new ParaInherentEnter(),
10
+ new SetNimbusAuthorInherent(),
11
+ new SetBabeRandomness()
12
+ ];
@@ -1,7 +1,7 @@
1
1
  import { HexString } from '@polkadot/util/types';
2
2
  import { Block } from '../block.js';
3
3
  import { BuildBlockParams } from '../txpool.js';
4
- import { CreateInherents } from './index.js';
5
- export declare class ParaInherentEnter implements CreateInherents {
6
- createInherents(parent: Block, _params: BuildBlockParams): Promise<HexString[]>;
4
+ import { InherentProvider } from './index.js';
5
+ export declare class ParaInherentEnter implements InherentProvider {
6
+ createInherents(newBlock: Block, _params: BuildBlockParams): Promise<HexString[]>;
7
7
  }
@@ -1,6 +1,8 @@
1
1
  import { GenericExtrinsic } from '@polkadot/types';
2
2
  export class ParaInherentEnter {
3
- async createInherents(parent, _params) {
3
+ async createInherents(newBlock, _params) {
4
+ const parent = await newBlock.parentBlock;
5
+ if (!parent) throw new Error('parent block not found');
4
6
  const meta = await parent.meta;
5
7
  if (!meta.tx.paraInherent?.enter) {
6
8
  return [];