@acala-network/chopsticks-core 1.2.7 → 1.2.8

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.
@@ -151,6 +151,7 @@ const newHeader = async (head, unsafeBlockHeight)=>{
151
151
  };
152
152
  const initNewBlock = async (head, header, inherentProviders, params, storageLayer, callback)=>{
153
153
  const blockNumber = header.number.toNumber();
154
+ const { unsafeBlockHeight } = params;
154
155
  const hash = `0x${Math.round(Math.random() * 100000000).toString(16).padEnd(64, '0')}`;
155
156
  const newBlock = new _block.Block(head.chain, blockNumber, hash, head, {
156
157
  header,
@@ -158,6 +159,13 @@ const initNewBlock = async (head, header, inherentProviders, params, storageLaye
158
159
  storage: storageLayer ?? head.storage
159
160
  });
160
161
  {
162
+ // override block number in storage when using unsafeBlockHeight
163
+ // this is needed because the runtime validates that block numbers are strictly increasing
164
+ if (unsafeBlockHeight !== undefined && blockNumber > head.number + 1) {
165
+ const meta = await head.meta;
166
+ const value = meta.registry.createType('BlockNumber', blockNumber - 1).toU8a();
167
+ newBlock.pushStorageLayer().set((0, _index.compactHex)(meta.query.system.number()), (0, _util.u8aToHex)(value));
168
+ }
161
169
  // initialize block
162
170
  const resp = await newBlock.call('Core_initialize_block', [
163
171
  header.toHex()
@@ -3,8 +3,8 @@ import type { Block } from '../../block.js';
3
3
  import type { BuildBlockParams, DownwardMessage, HorizontalMessage } from '../../txpool.js';
4
4
  import type { InherentProvider } from '../index.js';
5
5
  export type ValidationData = {
6
- downwardMessages: DownwardMessage[];
7
- horizontalMessages: Record<number, HorizontalMessage[]>;
6
+ downwardMessages?: DownwardMessage[];
7
+ horizontalMessages?: Record<number, HorizontalMessage[]>;
8
8
  validationData: {
9
9
  relayParentNumber: number;
10
10
  relayParentStorageRoot: HexString;
@@ -51,8 +51,7 @@ const MOCK_VALIDATION_DATA = {
51
51
  horizontalMessages: [],
52
52
  downwardMessages: []
53
53
  };
54
- const getValidationData = async (parent, fallback = true)=>{
55
- const meta = await parent.meta;
54
+ const getValidationData = async (parent)=>{
56
55
  if (parent.number === 0) {
57
56
  const { trieRootHash, nodes } = await (0, _index1.createProof)(MOCK_VALIDATION_DATA.relayChainState.trieNodes, []);
58
57
  return {
@@ -66,39 +65,19 @@ const getValidationData = async (parent, fallback = true)=>{
66
65
  }
67
66
  };
68
67
  }
69
- try {
70
- const extrinsics = await parent.extrinsics;
71
- const validationDataExtrinsic = extrinsics.find((extrinsic)=>{
72
- const firstArg = meta.registry.createType('GenericExtrinsic', extrinsic)?.args?.[0];
73
- return firstArg && 'validationData' in firstArg;
74
- });
75
- if (!validationDataExtrinsic) {
76
- throw new Error('Missing validation data from block');
77
- }
78
- return meta.registry.createType('GenericExtrinsic', validationDataExtrinsic).args[0].toJSON();
79
- } catch (e) {
80
- logger.warn('Failed to get validation data from block %d %s', parent.number, e);
81
- if (fallback) {
82
- // this could fail due to wasm override that breaks the validation data format
83
- // so we will try parent's parent
84
- const grandParent = await parent.parentBlock;
85
- if (grandParent) {
86
- const data = await getValidationData(grandParent, false);
87
- return {
88
- ...data,
89
- validationData: {
90
- ...data.validationData,
91
- relayParentNumber: data.validationData.relayParentNumber + 2
92
- }
93
- };
94
- } else {
95
- throw e;
96
- }
97
- } else {
98
- // fallback failed, throw error
99
- throw e;
100
- }
68
+ // Parent extrinsics are encoded by grand parent meta and new block extrinsics are encoded with parent meta.
69
+ const grandParent = await parent.parentBlock;
70
+ if (!grandParent) throw new Error('grand parent block not found');
71
+ const grandMeta = await grandParent.meta;
72
+ const extrinsics = await parent.extrinsics;
73
+ const validationDataExtrinsic = extrinsics.find((extrinsic)=>{
74
+ const firstArg = grandMeta.registry.createType('GenericExtrinsic', extrinsic)?.args?.[0];
75
+ return firstArg && 'validationData' in firstArg;
76
+ });
77
+ if (!validationDataExtrinsic) {
78
+ throw new Error('Missing validation data from block');
101
79
  }
80
+ return grandMeta.registry.createType('GenericExtrinsic', validationDataExtrinsic).args[0].toJSON();
102
81
  };
103
82
  class SetValidationData {
104
83
  async createInherents(newBlock, params) {
package/dist/cjs/setup.js CHANGED
@@ -26,10 +26,13 @@ const processOptions = async (options)=>{
26
26
  _logger.defaultLogger.debug(options, 'Setup options');
27
27
  let provider;
28
28
  if (options.genesis) {
29
+ _logger.defaultLogger.debug(options, 'Setup options - genesis');
29
30
  provider = options.genesis;
30
31
  } else if (typeof options.endpoint === 'string' && /^(https|http):\/\//.test(options.endpoint || '')) {
32
+ _logger.defaultLogger.debug(options, 'Setup options - HTTP');
31
33
  provider = new _rpcprovider.HttpProvider(options.endpoint);
32
34
  } else {
35
+ _logger.defaultLogger.debug(options, 'Setup options - WS');
33
36
  provider = new _rpcprovider.WsProvider(options.endpoint, 3_000, undefined, options.rpcTimeout);
34
37
  }
35
38
  const api = new _api.Api(provider);
@@ -1,4 +1,4 @@
1
- import { compactAddLength, hexToU8a, stringToHex, u8aConcat } from '@polkadot/util';
1
+ import { compactAddLength, hexToU8a, stringToHex, u8aConcat, u8aToHex } from '@polkadot/util';
2
2
  import { blake2AsU8a } from '@polkadot/util-crypto';
3
3
  import { defaultLogger, truncate } from '../logger.js';
4
4
  import { compactHex, getCurrentSlot } from '../utils/index.js';
@@ -127,6 +127,7 @@ export const newHeader = async (head, unsafeBlockHeight)=>{
127
127
  };
128
128
  const initNewBlock = async (head, header, inherentProviders, params, storageLayer, callback)=>{
129
129
  const blockNumber = header.number.toNumber();
130
+ const { unsafeBlockHeight } = params;
130
131
  const hash = `0x${Math.round(Math.random() * 100000000).toString(16).padEnd(64, '0')}`;
131
132
  const newBlock = new Block(head.chain, blockNumber, hash, head, {
132
133
  header,
@@ -134,6 +135,13 @@ const initNewBlock = async (head, header, inherentProviders, params, storageLaye
134
135
  storage: storageLayer ?? head.storage
135
136
  });
136
137
  {
138
+ // override block number in storage when using unsafeBlockHeight
139
+ // this is needed because the runtime validates that block numbers are strictly increasing
140
+ if (unsafeBlockHeight !== undefined && blockNumber > head.number + 1) {
141
+ const meta = await head.meta;
142
+ const value = meta.registry.createType('BlockNumber', blockNumber - 1).toU8a();
143
+ newBlock.pushStorageLayer().set(compactHex(meta.query.system.number()), u8aToHex(value));
144
+ }
137
145
  // initialize block
138
146
  const resp = await newBlock.call('Core_initialize_block', [
139
147
  header.toHex()
@@ -3,8 +3,8 @@ import type { Block } from '../../block.js';
3
3
  import type { BuildBlockParams, DownwardMessage, HorizontalMessage } from '../../txpool.js';
4
4
  import type { InherentProvider } from '../index.js';
5
5
  export type ValidationData = {
6
- downwardMessages: DownwardMessage[];
7
- horizontalMessages: Record<number, HorizontalMessage[]>;
6
+ downwardMessages?: DownwardMessage[];
7
+ horizontalMessages?: Record<number, HorizontalMessage[]>;
8
8
  validationData: {
9
9
  relayParentNumber: number;
10
10
  relayParentStorageRoot: HexString;
@@ -36,8 +36,7 @@ const MOCK_VALIDATION_DATA = {
36
36
  horizontalMessages: [],
37
37
  downwardMessages: []
38
38
  };
39
- const getValidationData = async (parent, fallback = true)=>{
40
- const meta = await parent.meta;
39
+ const getValidationData = async (parent)=>{
41
40
  if (parent.number === 0) {
42
41
  const { trieRootHash, nodes } = await createProof(MOCK_VALIDATION_DATA.relayChainState.trieNodes, []);
43
42
  return {
@@ -51,39 +50,19 @@ const getValidationData = async (parent, fallback = true)=>{
51
50
  }
52
51
  };
53
52
  }
54
- try {
55
- const extrinsics = await parent.extrinsics;
56
- const validationDataExtrinsic = extrinsics.find((extrinsic)=>{
57
- const firstArg = meta.registry.createType('GenericExtrinsic', extrinsic)?.args?.[0];
58
- return firstArg && 'validationData' in firstArg;
59
- });
60
- if (!validationDataExtrinsic) {
61
- throw new Error('Missing validation data from block');
62
- }
63
- return meta.registry.createType('GenericExtrinsic', validationDataExtrinsic).args[0].toJSON();
64
- } catch (e) {
65
- logger.warn('Failed to get validation data from block %d %s', parent.number, e);
66
- if (fallback) {
67
- // this could fail due to wasm override that breaks the validation data format
68
- // so we will try parent's parent
69
- const grandParent = await parent.parentBlock;
70
- if (grandParent) {
71
- const data = await getValidationData(grandParent, false);
72
- return {
73
- ...data,
74
- validationData: {
75
- ...data.validationData,
76
- relayParentNumber: data.validationData.relayParentNumber + 2
77
- }
78
- };
79
- } else {
80
- throw e;
81
- }
82
- } else {
83
- // fallback failed, throw error
84
- throw e;
85
- }
53
+ // Parent extrinsics are encoded by grand parent meta and new block extrinsics are encoded with parent meta.
54
+ const grandParent = await parent.parentBlock;
55
+ if (!grandParent) throw new Error('grand parent block not found');
56
+ const grandMeta = await grandParent.meta;
57
+ const extrinsics = await parent.extrinsics;
58
+ const validationDataExtrinsic = extrinsics.find((extrinsic)=>{
59
+ const firstArg = grandMeta.registry.createType('GenericExtrinsic', extrinsic)?.args?.[0];
60
+ return firstArg && 'validationData' in firstArg;
61
+ });
62
+ if (!validationDataExtrinsic) {
63
+ throw new Error('Missing validation data from block');
86
64
  }
65
+ return grandMeta.registry.createType('GenericExtrinsic', validationDataExtrinsic).args[0].toJSON();
87
66
  };
88
67
  export class SetValidationData {
89
68
  async createInherents(newBlock, params) {
package/dist/esm/setup.js CHANGED
@@ -8,10 +8,13 @@ export const processOptions = async (options)=>{
8
8
  defaultLogger.debug(options, 'Setup options');
9
9
  let provider;
10
10
  if (options.genesis) {
11
+ defaultLogger.debug(options, 'Setup options - genesis');
11
12
  provider = options.genesis;
12
13
  } else if (typeof options.endpoint === 'string' && /^(https|http):\/\//.test(options.endpoint || '')) {
14
+ defaultLogger.debug(options, 'Setup options - HTTP');
13
15
  provider = new HttpProvider(options.endpoint);
14
16
  } else {
17
+ defaultLogger.debug(options, 'Setup options - WS');
15
18
  provider = new WsProvider(options.endpoint, 3_000, undefined, options.rpcTimeout);
16
19
  }
17
20
  const api = new Api(provider);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acala-network/chopsticks-core",
3
- "version": "1.2.7",
3
+ "version": "1.2.8",
4
4
  "author": "Acala Developers <hello@acala.network>",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -14,7 +14,7 @@
14
14
  "depcheck": "npx depcheck"
15
15
  },
16
16
  "dependencies": {
17
- "@acala-network/chopsticks-executor": "1.2.7",
17
+ "@acala-network/chopsticks-executor": "1.2.8",
18
18
  "@polkadot/rpc-provider": "^16.4.1",
19
19
  "@polkadot/types": "^16.4.1",
20
20
  "@polkadot/types-codec": "^16.4.1",