@acala-network/chopsticks-core 0.10.0 → 0.10.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.
@@ -1,9 +1,10 @@
1
- import { Header, TransactionValidityError } from '@polkadot/types/interfaces';
1
+ import { DigestItem, Header, TransactionValidityError } from '@polkadot/types/interfaces';
2
2
  import { Block } from './block.js';
3
3
  import { BuildBlockParams } from './txpool.js';
4
4
  import { HexString } from '@polkadot/util/types';
5
5
  import { InherentProvider } from './inherent/index.js';
6
6
  import { TaskCallResponse } from '../wasm-executor/index.js';
7
+ export declare const genesisDigestLogs: (head: Block) => Promise<DigestItem[]>;
7
8
  export declare const newHeader: (head: Block, unsafeBlockHeight?: number) => Promise<Header>;
8
9
  export type BuildBlockCallbacks = {
9
10
  onApplyExtrinsicError?: (extrinsic: HexString, error: TransactionValidityError) => void;
@@ -18,6 +18,9 @@ _export(exports, {
18
18
  dryRunInherents: function() {
19
19
  return dryRunInherents;
20
20
  },
21
+ genesisDigestLogs: function() {
22
+ return genesisDigestLogs;
23
+ },
21
24
  newHeader: function() {
22
25
  return newHeader;
23
26
  }
@@ -30,17 +33,53 @@ const _logger = require("../logger.js");
30
33
  const logger = _logger.defaultLogger.child({
31
34
  name: 'block-builder'
32
35
  });
36
+ const genesisDigestLogs = async (head)=>{
37
+ const meta = await head.meta;
38
+ const currentSlot = await (0, _index.getCurrentSlot)(head);
39
+ if (meta.consts.babe) {
40
+ const newSlot = meta.registry.createType('Slot', currentSlot + 1);
41
+ const consensusEngine = meta.registry.createType('ConsensusEngineId', 'BABE');
42
+ const preDigest = meta.registry.createType('RawBabePreDigest', {
43
+ SecondaryVRF: {
44
+ authorityIndex: 514,
45
+ slotNumber: newSlot,
46
+ vrfOutput: '0x44cadd14aaefbda13ac8d85e1a6d58be082e7e2f56a4f95a3c612c784aaa4063',
47
+ vrfProof: '0xf5517bf67d93ce633cde2fde7fbcf8ddca80017aaf8cd48436514687c662f60eda0ffa2c4781906416f4e71a196c9783c60c1b83d54c3a29365d03706714570b'
48
+ }
49
+ });
50
+ const digest = meta.registry.createType('DigestItem', {
51
+ PreRuntime: [
52
+ consensusEngine,
53
+ (0, _util.compactAddLength)(preDigest.toU8a())
54
+ ]
55
+ });
56
+ return [
57
+ digest
58
+ ];
59
+ } else {
60
+ const newSlot = meta.registry.createType('Slot', currentSlot + 1);
61
+ const consensusEngine = meta.registry.createType('ConsensusEngineId', 'aura');
62
+ const digest = meta.registry.createType('DigestItem', {
63
+ PreRuntime: [
64
+ consensusEngine,
65
+ (0, _util.compactAddLength)(newSlot.toU8a())
66
+ ]
67
+ });
68
+ return [
69
+ digest
70
+ ];
71
+ }
72
+ };
33
73
  const getConsensus = (header)=>{
34
74
  if (header.digest.logs.length === 0) return;
35
- const preRuntime = header.digest.logs[0].asPreRuntime;
36
- const [consensusEngine, slot] = preRuntime;
75
+ const [consensusEngine, preDigest] = header.digest.logs[0].asPreRuntime;
37
76
  return {
38
77
  consensusEngine,
39
- slot,
78
+ preDigest,
40
79
  rest: header.digest.logs.slice(1)
41
80
  };
42
81
  };
43
- const getNewSlot = (digest, slotNumber)=>{
82
+ const babePreDigestSetSlot = (digest, slotNumber)=>{
44
83
  if (digest.isPrimary) {
45
84
  return {
46
85
  primary: {
@@ -70,43 +109,43 @@ const getNewSlot = (digest, slotNumber)=>{
70
109
  const newHeader = async (head, unsafeBlockHeight)=>{
71
110
  const meta = await head.meta;
72
111
  const parentHeader = await head.header;
73
- let newLogs = parentHeader.digest.logs;
112
+ let newLogs = !head.number ? await genesisDigestLogs(head) : parentHeader.digest.logs.toArray();
74
113
  const consensus = getConsensus(parentHeader);
75
114
  if (consensus?.consensusEngine.isAura) {
76
- const slot = await (0, _index.getCurrentSlot)(head.chain);
115
+ const slot = await (0, _index.getCurrentSlot)(head);
77
116
  const newSlot = (0, _util.compactAddLength)(meta.registry.createType('Slot', slot + 1).toU8a());
78
117
  newLogs = [
79
- {
118
+ meta.registry.createType('DigestItem', {
80
119
  PreRuntime: [
81
120
  consensus.consensusEngine,
82
121
  newSlot
83
122
  ]
84
- },
123
+ }),
85
124
  ...consensus.rest
86
125
  ];
87
126
  } else if (consensus?.consensusEngine.isBabe) {
88
- const slot = await (0, _index.getCurrentSlot)(head.chain);
89
- const digest = meta.registry.createType('RawBabePreDigest', consensus.slot);
90
- const newSlot = (0, _util.compactAddLength)(meta.registry.createType('RawBabePreDigest', getNewSlot(digest, slot + 1)).toU8a());
127
+ const slot = await (0, _index.getCurrentSlot)(head);
128
+ const digest = meta.registry.createType('RawBabePreDigest', consensus.preDigest);
129
+ const newSlot = (0, _util.compactAddLength)(meta.registry.createType('RawBabePreDigest', babePreDigestSetSlot(digest, slot + 1)).toU8a());
91
130
  newLogs = [
92
- {
131
+ meta.registry.createType('DigestItem', {
93
132
  PreRuntime: [
94
133
  consensus.consensusEngine,
95
134
  newSlot
96
135
  ]
97
- },
136
+ }),
98
137
  ...consensus.rest
99
138
  ];
100
139
  } else if (consensus?.consensusEngine?.toString() == 'nmbs') {
101
140
  const nmbsKey = (0, _util.stringToHex)('nmbs');
102
141
  newLogs = [
103
- {
142
+ meta.registry.createType('DigestItem', {
104
143
  // Using previous block author
105
144
  PreRuntime: [
106
145
  consensus.consensusEngine,
107
146
  parentHeader.digest.logs.find((log)=>log.isPreRuntime && log.asPreRuntime[0].toHex() == nmbsKey)?.asPreRuntime[1].toHex()
108
147
  ]
109
- },
148
+ }),
110
149
  ...consensus.rest
111
150
  ];
112
151
  if (meta.query.randomness?.notFirstBlock) {
@@ -88,12 +88,15 @@ class SetValidationData {
88
88
  const hrmpIngressChannelIndexKey = (0, _proof.hrmpIngressChannelIndex)(paraId);
89
89
  const hrmpEgressChannelIndexKey = (0, _proof.hrmpEgressChannelIndex)(paraId);
90
90
  const decoded = await (0, _index1.decodeProof)(extrinsic.validationData.relayParentStorageRoot, extrinsic.relayChainState.trieNodes);
91
- const slotIncrease = meta.consts.timestamp.minimumPeriod.divn(3000) // relaychain min period
92
- .toNumber();
91
+ const slotIncrease = Math.max(1, meta.consts.timestamp?.minimumPeriod // legacy
92
+ ?.divn(3000) // relaychain min period
93
+ ?.toNumber() || meta.consts.aura?.slotDuration // async backing
94
+ ?.divn(6000) // relaychain block time
95
+ ?.toNumber() || 1);
93
96
  for (const key of Object.values(_proof.WELL_KNOWN_KEYS)){
94
97
  if (key === _proof.WELL_KNOWN_KEYS.CURRENT_SLOT) {
95
98
  // increment current slot
96
- const relayCurrentSlot = decoded[key] ? meta.registry.createType('Slot', (0, _util.hexToU8a)(decoded[key])).toNumber() : await (0, _index.getCurrentSlot)(parent.chain) * slotIncrease;
99
+ const relayCurrentSlot = decoded[key] ? meta.registry.createType('Slot', (0, _util.hexToU8a)(decoded[key])).toNumber() : await (0, _index.getCurrentSlot)(parent) * slotIncrease;
97
100
  const newSlot = meta.registry.createType('Slot', relayCurrentSlot + slotIncrease);
98
101
  newEntries.push([
99
102
  key,
@@ -15,8 +15,8 @@ class SetTimestamp {
15
15
  const parent = await newBlock.parentBlock;
16
16
  if (!parent) throw new Error('parent block not found');
17
17
  const meta = await parent.meta;
18
- const slotDuration = await (0, _index.getSlotDuration)(parent.chain);
19
- const currentTimestamp = await (0, _index.getCurrentTimestamp)(parent.chain);
18
+ const slotDuration = await (0, _index.getSlotDuration)(parent);
19
+ const currentTimestamp = await (0, _index.getCurrentTimestamp)(parent);
20
20
  return [
21
21
  new _types.GenericExtrinsic(meta.registry, meta.tx.timestamp.set(currentTimestamp + BigInt(slotDuration))).toHex()
22
22
  ];
@@ -19,7 +19,6 @@ export type SetupOptions = {
19
19
  maxMemoryBlockCount?: number;
20
20
  processQueuedMessages?: boolean;
21
21
  };
22
- export declare const genesisSetup: (chain: Blockchain, genesis: GenesisProvider) => Promise<void>;
23
22
  export declare const processOptions: (options: SetupOptions) => Promise<{
24
23
  blockHash: string;
25
24
  api: Api;
package/dist/cjs/setup.js CHANGED
@@ -9,9 +9,6 @@ function _export(target, all) {
9
9
  });
10
10
  }
11
11
  _export(exports, {
12
- genesisSetup: function() {
13
- return genesisSetup;
14
- },
15
12
  processOptions: function() {
16
13
  return processOptions;
17
14
  },
@@ -21,51 +18,10 @@ _export(exports, {
21
18
  });
22
19
  require("@polkadot/types-codec");
23
20
  const _rpcprovider = require("@polkadot/rpc-provider");
24
- const _util = require("@polkadot/util");
25
21
  const _api = require("./api.js");
26
22
  const _index = require("./blockchain/index.js");
27
23
  const _logger = require("./logger.js");
28
- const _index1 = require("./index.js");
29
- const _index2 = require("./blockchain/inherent/index.js");
30
- const genesisSetup = async (chain, genesis)=>{
31
- const meta = await chain.head.meta;
32
- const timestamp = Date.now();
33
- await (0, _index1.setStorage)(chain, {
34
- Timestamp: {
35
- Now: timestamp
36
- }
37
- });
38
- const slotDuration = await (0, _index1.getSlotDuration)(chain);
39
- const currentSlot = Math.floor(timestamp / slotDuration);
40
- if (meta.consts.babe) {
41
- await (0, _index1.setStorage)(chain, {
42
- Babe: {
43
- CurrentSlot: currentSlot
44
- }
45
- });
46
- genesis.genesisHeaderLogs = [
47
- '0x0642414245b50103020200001c5fef100000000044cadd14aaefbda13ac8d85e1a6d58be082e7e2f56a4f95a3c612c784aaa4063f5517bf67d93ce633cde2fde7fbcf8ddca80017aaf8cd48436514687c662f60eda0ffa2c4781906416f4e71a196c9783c60c1b83d54c3a29365d03706714570b'
48
- ];
49
- } else {
50
- await (0, _index1.setStorage)(chain, {
51
- Aura: {
52
- CurrentSlot: currentSlot
53
- }
54
- });
55
- const newSlot = (0, _util.compactAddLength)(meta.registry.createType('Slot', currentSlot + 1).toU8a());
56
- const consensusEngine = meta.registry.createType('ConsensusEngineId', 'aura');
57
- const digest = meta.registry.createType('DigestItem', {
58
- PreRuntime: [
59
- consensusEngine,
60
- newSlot
61
- ]
62
- });
63
- genesis.genesisHeaderLogs = [
64
- digest.toHex()
65
- ];
66
- }
67
- await chain.newBlock();
68
- };
24
+ const _index1 = require("./blockchain/inherent/index.js");
69
25
  const processOptions = async (options)=>{
70
26
  _logger.defaultLogger.debug(options, 'Setup options');
71
27
  let provider;
@@ -118,7 +74,7 @@ const setup = async (options)=>{
118
74
  const chain = new _index.Blockchain({
119
75
  api,
120
76
  buildBlockMode: opts.buildBlockMode,
121
- inherentProviders: _index2.inherentProviders,
77
+ inherentProviders: _index1.inherentProviders,
122
78
  db: opts.db,
123
79
  header: {
124
80
  hash: blockHash,
@@ -133,7 +89,8 @@ const setup = async (options)=>{
133
89
  processQueuedMessages: opts.processQueuedMessages
134
90
  });
135
91
  if (opts.genesis) {
136
- await genesisSetup(chain, opts.genesis);
92
+ // build 1st block
93
+ await chain.newBlock();
137
94
  }
138
95
  return chain;
139
96
  };
@@ -1,5 +1,6 @@
1
1
  import { HexString } from '@polkadot/util/types';
2
2
  import { StorageKey } from '@polkadot/types';
3
+ import { Block } from '../blockchain/block.js';
3
4
  import { Blockchain } from '../blockchain/index.js';
4
5
  export * from './set-storage.js';
5
6
  export * from './time-travel.js';
@@ -23,6 +24,6 @@ export declare const prefixedChildKey: (prefix: HexString, key: HexString) => st
23
24
  export declare const isPrefixedChildKey: (key: HexString) => boolean;
24
25
  export declare const splitChildKey: (key: HexString) => [`0x${string}`, `0x${string}`] | never[];
25
26
  export declare const stripChildPrefix: (key: HexString) => `0x${string}`;
26
- export declare const getCurrentSlot: (chain: Blockchain) => Promise<number>;
27
- export declare const getCurrentTimestamp: (chain: Blockchain) => Promise<bigint>;
28
- export declare const getSlotDuration: (chain: Blockchain) => Promise<number>;
27
+ export declare const getCurrentSlot: (head: Block) => Promise<number>;
28
+ export declare const getCurrentTimestamp: (head: Block) => Promise<bigint>;
29
+ export declare const getSlotDuration: (head: Block) => Promise<number>;
@@ -153,22 +153,24 @@ const POTENTIAL_SLOT_KEYS = [
153
153
  '0x8985dff79e6002d0deba9ddac46f32a5a70806914c906d747e668a21f9021729',
154
154
  '0xab2a8d5eca218f218c6fda6b1d22bb926bc171ab77f6a731a6e80c34ee1eda19'
155
155
  ];
156
- const getCurrentSlot = async (chain)=>{
157
- const meta = await chain.head.meta;
156
+ const getCurrentSlot = async (head)=>{
157
+ const meta = await head.meta;
158
158
  for (const key of POTENTIAL_SLOT_KEYS){
159
- const slotRaw = await chain.head.get(key);
159
+ const slotRaw = await head.get(key);
160
160
  if (slotRaw) {
161
161
  return meta.registry.createType('Slot', (0, _util.hexToU8a)(slotRaw)).toNumber();
162
162
  }
163
163
  }
164
- throw new Error('Cannot find current slot');
164
+ const timestamp = await getCurrentTimestamp(head);
165
+ const slotDuration = await getSlotDuration(head);
166
+ return Math.floor(Number(timestamp / BigInt(slotDuration)));
165
167
  };
166
- const getCurrentTimestamp = async (chain)=>{
167
- const meta = await chain.head.meta;
168
- const timestamp = await chain.head.read('u64', meta.query.timestamp.now);
169
- return timestamp?.toBigInt() ?? 0n;
168
+ const getCurrentTimestamp = async (head)=>{
169
+ const meta = await head.meta;
170
+ const timestamp = await head.read('u64', meta.query.timestamp.now);
171
+ return timestamp?.toBigInt() ?? BigInt(Date.now());
170
172
  };
171
- const getSlotDuration = async (chain)=>{
172
- const meta = await chain.head.meta;
173
- return meta.consts.babe ? meta.consts.babe.expectedBlockTime.toNumber() : meta.query.aura ? (0, _index.getAuraSlotDuration)(await chain.head.wasm) : meta.consts.asyncBacking ? meta.consts.asyncBacking.expectedBlockTime.toNumber() : 12_000;
173
+ const getSlotDuration = async (head)=>{
174
+ const meta = await head.meta;
175
+ return meta.consts.babe ? meta.consts.babe.expectedBlockTime.toNumber() : meta.query.aura ? (0, _index.getAuraSlotDuration)(await head.wasm) : meta.consts.asyncBacking ? meta.consts.asyncBacking.expectedBlockTime.toNumber() : 12_000;
174
176
  };
@@ -13,7 +13,7 @@ const _index = require("./index.js");
13
13
  const _setstorage = require("./set-storage.js");
14
14
  const timeTravel = async (chain, timestamp)=>{
15
15
  const meta = await chain.head.meta;
16
- const slotDuration = await (0, _index.getSlotDuration)(chain);
16
+ const slotDuration = await (0, _index.getSlotDuration)(chain.head);
17
17
  const newSlot = Math.floor(timestamp / slotDuration);
18
18
  // new timestamp
19
19
  const storage = [
@@ -1,9 +1,10 @@
1
- import { Header, TransactionValidityError } from '@polkadot/types/interfaces';
1
+ import { DigestItem, Header, TransactionValidityError } from '@polkadot/types/interfaces';
2
2
  import { Block } from './block.js';
3
3
  import { BuildBlockParams } from './txpool.js';
4
4
  import { HexString } from '@polkadot/util/types';
5
5
  import { InherentProvider } from './inherent/index.js';
6
6
  import { TaskCallResponse } from '../wasm-executor/index.js';
7
+ export declare const genesisDigestLogs: (head: Block) => Promise<DigestItem[]>;
7
8
  export declare const newHeader: (head: Block, unsafeBlockHeight?: number) => Promise<Header>;
8
9
  export type BuildBlockCallbacks = {
9
10
  onApplyExtrinsicError?: (extrinsic: HexString, error: TransactionValidityError) => void;
@@ -6,17 +6,53 @@ import { defaultLogger, truncate } from '../logger.js';
6
6
  const logger = defaultLogger.child({
7
7
  name: 'block-builder'
8
8
  });
9
+ export const genesisDigestLogs = async (head)=>{
10
+ const meta = await head.meta;
11
+ const currentSlot = await getCurrentSlot(head);
12
+ if (meta.consts.babe) {
13
+ const newSlot = meta.registry.createType('Slot', currentSlot + 1);
14
+ const consensusEngine = meta.registry.createType('ConsensusEngineId', 'BABE');
15
+ const preDigest = meta.registry.createType('RawBabePreDigest', {
16
+ SecondaryVRF: {
17
+ authorityIndex: 514,
18
+ slotNumber: newSlot,
19
+ vrfOutput: '0x44cadd14aaefbda13ac8d85e1a6d58be082e7e2f56a4f95a3c612c784aaa4063',
20
+ vrfProof: '0xf5517bf67d93ce633cde2fde7fbcf8ddca80017aaf8cd48436514687c662f60eda0ffa2c4781906416f4e71a196c9783c60c1b83d54c3a29365d03706714570b'
21
+ }
22
+ });
23
+ const digest = meta.registry.createType('DigestItem', {
24
+ PreRuntime: [
25
+ consensusEngine,
26
+ compactAddLength(preDigest.toU8a())
27
+ ]
28
+ });
29
+ return [
30
+ digest
31
+ ];
32
+ } else {
33
+ const newSlot = meta.registry.createType('Slot', currentSlot + 1);
34
+ const consensusEngine = meta.registry.createType('ConsensusEngineId', 'aura');
35
+ const digest = meta.registry.createType('DigestItem', {
36
+ PreRuntime: [
37
+ consensusEngine,
38
+ compactAddLength(newSlot.toU8a())
39
+ ]
40
+ });
41
+ return [
42
+ digest
43
+ ];
44
+ }
45
+ };
9
46
  const getConsensus = (header)=>{
10
47
  if (header.digest.logs.length === 0) return;
11
- const preRuntime = header.digest.logs[0].asPreRuntime;
12
- const [consensusEngine, slot] = preRuntime;
48
+ const [consensusEngine, preDigest] = header.digest.logs[0].asPreRuntime;
13
49
  return {
14
50
  consensusEngine,
15
- slot,
51
+ preDigest,
16
52
  rest: header.digest.logs.slice(1)
17
53
  };
18
54
  };
19
- const getNewSlot = (digest, slotNumber)=>{
55
+ const babePreDigestSetSlot = (digest, slotNumber)=>{
20
56
  if (digest.isPrimary) {
21
57
  return {
22
58
  primary: {
@@ -46,43 +82,43 @@ const getNewSlot = (digest, slotNumber)=>{
46
82
  export const newHeader = async (head, unsafeBlockHeight)=>{
47
83
  const meta = await head.meta;
48
84
  const parentHeader = await head.header;
49
- let newLogs = parentHeader.digest.logs;
85
+ let newLogs = !head.number ? await genesisDigestLogs(head) : parentHeader.digest.logs.toArray();
50
86
  const consensus = getConsensus(parentHeader);
51
87
  if (consensus?.consensusEngine.isAura) {
52
- const slot = await getCurrentSlot(head.chain);
88
+ const slot = await getCurrentSlot(head);
53
89
  const newSlot = compactAddLength(meta.registry.createType('Slot', slot + 1).toU8a());
54
90
  newLogs = [
55
- {
91
+ meta.registry.createType('DigestItem', {
56
92
  PreRuntime: [
57
93
  consensus.consensusEngine,
58
94
  newSlot
59
95
  ]
60
- },
96
+ }),
61
97
  ...consensus.rest
62
98
  ];
63
99
  } else if (consensus?.consensusEngine.isBabe) {
64
- const slot = await getCurrentSlot(head.chain);
65
- const digest = meta.registry.createType('RawBabePreDigest', consensus.slot);
66
- const newSlot = compactAddLength(meta.registry.createType('RawBabePreDigest', getNewSlot(digest, slot + 1)).toU8a());
100
+ const slot = await getCurrentSlot(head);
101
+ const digest = meta.registry.createType('RawBabePreDigest', consensus.preDigest);
102
+ const newSlot = compactAddLength(meta.registry.createType('RawBabePreDigest', babePreDigestSetSlot(digest, slot + 1)).toU8a());
67
103
  newLogs = [
68
- {
104
+ meta.registry.createType('DigestItem', {
69
105
  PreRuntime: [
70
106
  consensus.consensusEngine,
71
107
  newSlot
72
108
  ]
73
- },
109
+ }),
74
110
  ...consensus.rest
75
111
  ];
76
112
  } else if (consensus?.consensusEngine?.toString() == 'nmbs') {
77
113
  const nmbsKey = stringToHex('nmbs');
78
114
  newLogs = [
79
- {
115
+ meta.registry.createType('DigestItem', {
80
116
  // Using previous block author
81
117
  PreRuntime: [
82
118
  consensus.consensusEngine,
83
119
  parentHeader.digest.logs.find((log)=>log.isPreRuntime && log.asPreRuntime[0].toHex() == nmbsKey)?.asPreRuntime[1].toHex()
84
120
  ]
85
- },
121
+ }),
86
122
  ...consensus.rest
87
123
  ];
88
124
  if (meta.query.randomness?.notFirstBlock) {
@@ -73,12 +73,15 @@ export class SetValidationData {
73
73
  const hrmpIngressChannelIndexKey = hrmpIngressChannelIndex(paraId);
74
74
  const hrmpEgressChannelIndexKey = hrmpEgressChannelIndex(paraId);
75
75
  const decoded = await decodeProof(extrinsic.validationData.relayParentStorageRoot, extrinsic.relayChainState.trieNodes);
76
- const slotIncrease = meta.consts.timestamp.minimumPeriod.divn(3000) // relaychain min period
77
- .toNumber();
76
+ const slotIncrease = Math.max(1, meta.consts.timestamp?.minimumPeriod // legacy
77
+ ?.divn(3000) // relaychain min period
78
+ ?.toNumber() || meta.consts.aura?.slotDuration // async backing
79
+ ?.divn(6000) // relaychain block time
80
+ ?.toNumber() || 1);
78
81
  for (const key of Object.values(WELL_KNOWN_KEYS)){
79
82
  if (key === WELL_KNOWN_KEYS.CURRENT_SLOT) {
80
83
  // increment current slot
81
- const relayCurrentSlot = decoded[key] ? meta.registry.createType('Slot', hexToU8a(decoded[key])).toNumber() : await getCurrentSlot(parent.chain) * slotIncrease;
84
+ const relayCurrentSlot = decoded[key] ? meta.registry.createType('Slot', hexToU8a(decoded[key])).toNumber() : await getCurrentSlot(parent) * slotIncrease;
82
85
  const newSlot = meta.registry.createType('Slot', relayCurrentSlot + slotIncrease);
83
86
  newEntries.push([
84
87
  key,
@@ -5,8 +5,8 @@ export class SetTimestamp {
5
5
  const parent = await newBlock.parentBlock;
6
6
  if (!parent) throw new Error('parent block not found');
7
7
  const meta = await parent.meta;
8
- const slotDuration = await getSlotDuration(parent.chain);
9
- const currentTimestamp = await getCurrentTimestamp(parent.chain);
8
+ const slotDuration = await getSlotDuration(parent);
9
+ const currentTimestamp = await getCurrentTimestamp(parent);
10
10
  return [
11
11
  new GenericExtrinsic(meta.registry, meta.tx.timestamp.set(currentTimestamp + BigInt(slotDuration))).toHex()
12
12
  ];
@@ -19,7 +19,6 @@ export type SetupOptions = {
19
19
  maxMemoryBlockCount?: number;
20
20
  processQueuedMessages?: boolean;
21
21
  };
22
- export declare const genesisSetup: (chain: Blockchain, genesis: GenesisProvider) => Promise<void>;
23
22
  export declare const processOptions: (options: SetupOptions) => Promise<{
24
23
  blockHash: string;
25
24
  api: Api;
package/dist/esm/setup.js CHANGED
@@ -1,50 +1,9 @@
1
1
  import '@polkadot/types-codec';
2
2
  import { HttpProvider, WsProvider } from '@polkadot/rpc-provider';
3
- import { compactAddLength } from '@polkadot/util';
4
3
  import { Api } from './api.js';
5
4
  import { Blockchain } from './blockchain/index.js';
6
5
  import { defaultLogger } from './logger.js';
7
- import { getSlotDuration, setStorage } from './index.js';
8
6
  import { inherentProviders } from './blockchain/inherent/index.js';
9
- export const genesisSetup = async (chain, genesis)=>{
10
- const meta = await chain.head.meta;
11
- const timestamp = Date.now();
12
- await setStorage(chain, {
13
- Timestamp: {
14
- Now: timestamp
15
- }
16
- });
17
- const slotDuration = await getSlotDuration(chain);
18
- const currentSlot = Math.floor(timestamp / slotDuration);
19
- if (meta.consts.babe) {
20
- await setStorage(chain, {
21
- Babe: {
22
- CurrentSlot: currentSlot
23
- }
24
- });
25
- genesis.genesisHeaderLogs = [
26
- '0x0642414245b50103020200001c5fef100000000044cadd14aaefbda13ac8d85e1a6d58be082e7e2f56a4f95a3c612c784aaa4063f5517bf67d93ce633cde2fde7fbcf8ddca80017aaf8cd48436514687c662f60eda0ffa2c4781906416f4e71a196c9783c60c1b83d54c3a29365d03706714570b'
27
- ];
28
- } else {
29
- await setStorage(chain, {
30
- Aura: {
31
- CurrentSlot: currentSlot
32
- }
33
- });
34
- const newSlot = compactAddLength(meta.registry.createType('Slot', currentSlot + 1).toU8a());
35
- const consensusEngine = meta.registry.createType('ConsensusEngineId', 'aura');
36
- const digest = meta.registry.createType('DigestItem', {
37
- PreRuntime: [
38
- consensusEngine,
39
- newSlot
40
- ]
41
- });
42
- genesis.genesisHeaderLogs = [
43
- digest.toHex()
44
- ];
45
- }
46
- await chain.newBlock();
47
- };
48
7
  export const processOptions = async (options)=>{
49
8
  defaultLogger.debug(options, 'Setup options');
50
9
  let provider;
@@ -112,7 +71,8 @@ export const setup = async (options)=>{
112
71
  processQueuedMessages: opts.processQueuedMessages
113
72
  });
114
73
  if (opts.genesis) {
115
- await genesisSetup(chain, opts.genesis);
74
+ // build 1st block
75
+ await chain.newBlock();
116
76
  }
117
77
  return chain;
118
78
  };
@@ -1,5 +1,6 @@
1
1
  import { HexString } from '@polkadot/util/types';
2
2
  import { StorageKey } from '@polkadot/types';
3
+ import { Block } from '../blockchain/block.js';
3
4
  import { Blockchain } from '../blockchain/index.js';
4
5
  export * from './set-storage.js';
5
6
  export * from './time-travel.js';
@@ -23,6 +24,6 @@ export declare const prefixedChildKey: (prefix: HexString, key: HexString) => st
23
24
  export declare const isPrefixedChildKey: (key: HexString) => boolean;
24
25
  export declare const splitChildKey: (key: HexString) => [`0x${string}`, `0x${string}`] | never[];
25
26
  export declare const stripChildPrefix: (key: HexString) => `0x${string}`;
26
- export declare const getCurrentSlot: (chain: Blockchain) => Promise<number>;
27
- export declare const getCurrentTimestamp: (chain: Blockchain) => Promise<bigint>;
28
- export declare const getSlotDuration: (chain: Blockchain) => Promise<number>;
27
+ export declare const getCurrentSlot: (head: Block) => Promise<number>;
28
+ export declare const getCurrentTimestamp: (head: Block) => Promise<bigint>;
29
+ export declare const getSlotDuration: (head: Block) => Promise<number>;
@@ -89,22 +89,24 @@ const POTENTIAL_SLOT_KEYS = [
89
89
  '0x8985dff79e6002d0deba9ddac46f32a5a70806914c906d747e668a21f9021729',
90
90
  '0xab2a8d5eca218f218c6fda6b1d22bb926bc171ab77f6a731a6e80c34ee1eda19'
91
91
  ];
92
- export const getCurrentSlot = async (chain)=>{
93
- const meta = await chain.head.meta;
92
+ export const getCurrentSlot = async (head)=>{
93
+ const meta = await head.meta;
94
94
  for (const key of POTENTIAL_SLOT_KEYS){
95
- const slotRaw = await chain.head.get(key);
95
+ const slotRaw = await head.get(key);
96
96
  if (slotRaw) {
97
97
  return meta.registry.createType('Slot', hexToU8a(slotRaw)).toNumber();
98
98
  }
99
99
  }
100
- throw new Error('Cannot find current slot');
100
+ const timestamp = await getCurrentTimestamp(head);
101
+ const slotDuration = await getSlotDuration(head);
102
+ return Math.floor(Number(timestamp / BigInt(slotDuration)));
101
103
  };
102
- export const getCurrentTimestamp = async (chain)=>{
103
- const meta = await chain.head.meta;
104
- const timestamp = await chain.head.read('u64', meta.query.timestamp.now);
105
- return timestamp?.toBigInt() ?? 0n;
104
+ export const getCurrentTimestamp = async (head)=>{
105
+ const meta = await head.meta;
106
+ const timestamp = await head.read('u64', meta.query.timestamp.now);
107
+ return timestamp?.toBigInt() ?? BigInt(Date.now());
106
108
  };
107
- export const getSlotDuration = async (chain)=>{
108
- const meta = await chain.head.meta;
109
- return meta.consts.babe ? meta.consts.babe.expectedBlockTime.toNumber() : meta.query.aura ? getAuraSlotDuration(await chain.head.wasm) : meta.consts.asyncBacking ? meta.consts.asyncBacking.expectedBlockTime.toNumber() : 12_000;
109
+ export const getSlotDuration = async (head)=>{
110
+ const meta = await head.meta;
111
+ return meta.consts.babe ? meta.consts.babe.expectedBlockTime.toNumber() : meta.query.aura ? getAuraSlotDuration(await head.wasm) : meta.consts.asyncBacking ? meta.consts.asyncBacking.expectedBlockTime.toNumber() : 12_000;
110
112
  };
@@ -3,7 +3,7 @@ import { compactHex, getSlotDuration } from './index.js';
3
3
  import { setStorage } from './set-storage.js';
4
4
  export const timeTravel = async (chain, timestamp)=>{
5
5
  const meta = await chain.head.meta;
6
- const slotDuration = await getSlotDuration(chain);
6
+ const slotDuration = await getSlotDuration(chain.head);
7
7
  const newSlot = Math.floor(timestamp / slotDuration);
8
8
  // new timestamp
9
9
  const storage = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acala-network/chopsticks-core",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
4
4
  "author": "Acala Developers <hello@acala.network>",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -12,7 +12,7 @@
12
12
  "docs:prep": "typedoc"
13
13
  },
14
14
  "dependencies": {
15
- "@acala-network/chopsticks-executor": "0.10.0",
15
+ "@acala-network/chopsticks-executor": "0.10.2",
16
16
  "@polkadot/rpc-provider": "^10.11.2",
17
17
  "@polkadot/types": "^10.11.2",
18
18
  "@polkadot/types-codec": "^10.11.2",