@acala-network/chopsticks-core 0.10.1 → 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.
- package/dist/cjs/blockchain/block-builder.d.ts +2 -1
- package/dist/cjs/blockchain/block-builder.js +54 -15
- package/dist/cjs/blockchain/inherent/parachain/validation-data.js +6 -3
- package/dist/cjs/blockchain/inherent/timestamp.js +2 -2
- package/dist/cjs/setup.d.ts +0 -1
- package/dist/cjs/setup.js +4 -47
- package/dist/cjs/utils/index.d.ts +4 -3
- package/dist/cjs/utils/index.js +13 -11
- package/dist/cjs/utils/time-travel.js +1 -1
- package/dist/esm/blockchain/block-builder.d.ts +2 -1
- package/dist/esm/blockchain/block-builder.js +51 -15
- package/dist/esm/blockchain/inherent/parachain/validation-data.js +6 -3
- package/dist/esm/blockchain/inherent/timestamp.js +2 -2
- package/dist/esm/setup.d.ts +0 -1
- package/dist/esm/setup.js +2 -42
- package/dist/esm/utils/index.d.ts +4 -3
- package/dist/esm/utils/index.js +13 -11
- package/dist/esm/utils/time-travel.js +1 -1
- package/package.json +2 -2
|
@@ -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
|
|
36
|
-
const [consensusEngine, slot] = preRuntime;
|
|
75
|
+
const [consensusEngine, preDigest] = header.digest.logs[0].asPreRuntime;
|
|
37
76
|
return {
|
|
38
77
|
consensusEngine,
|
|
39
|
-
|
|
78
|
+
preDigest,
|
|
40
79
|
rest: header.digest.logs.slice(1)
|
|
41
80
|
};
|
|
42
81
|
};
|
|
43
|
-
const
|
|
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
|
|
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
|
|
89
|
-
const digest = meta.registry.createType('RawBabePreDigest', consensus.
|
|
90
|
-
const newSlot = (0, _util.compactAddLength)(meta.registry.createType('RawBabePreDigest',
|
|
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 = Math.max(1, meta.consts.timestamp
|
|
92
|
-
|
|
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
|
|
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
|
|
19
|
-
const currentTimestamp = await (0, _index.getCurrentTimestamp)(parent
|
|
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
|
];
|
package/dist/cjs/setup.d.ts
CHANGED
|
@@ -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:
|
|
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
|
-
|
|
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: (
|
|
27
|
-
export declare const getCurrentTimestamp: (
|
|
28
|
-
export declare const getSlotDuration: (
|
|
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>;
|
package/dist/cjs/utils/index.js
CHANGED
|
@@ -153,22 +153,24 @@ const POTENTIAL_SLOT_KEYS = [
|
|
|
153
153
|
'0x8985dff79e6002d0deba9ddac46f32a5a70806914c906d747e668a21f9021729',
|
|
154
154
|
'0xab2a8d5eca218f218c6fda6b1d22bb926bc171ab77f6a731a6e80c34ee1eda19'
|
|
155
155
|
];
|
|
156
|
-
const getCurrentSlot = async (
|
|
157
|
-
const meta = await
|
|
156
|
+
const getCurrentSlot = async (head)=>{
|
|
157
|
+
const meta = await head.meta;
|
|
158
158
|
for (const key of POTENTIAL_SLOT_KEYS){
|
|
159
|
-
const slotRaw = await
|
|
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
|
-
|
|
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 (
|
|
167
|
-
const meta = await
|
|
168
|
-
const timestamp = await
|
|
169
|
-
return timestamp?.toBigInt() ??
|
|
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 (
|
|
172
|
-
const meta = await
|
|
173
|
-
return meta.consts.babe ? meta.consts.babe.expectedBlockTime.toNumber() : meta.query.aura ? (0, _index.getAuraSlotDuration)(await
|
|
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
|
|
12
|
-
const [consensusEngine, slot] = preRuntime;
|
|
48
|
+
const [consensusEngine, preDigest] = header.digest.logs[0].asPreRuntime;
|
|
13
49
|
return {
|
|
14
50
|
consensusEngine,
|
|
15
|
-
|
|
51
|
+
preDigest,
|
|
16
52
|
rest: header.digest.logs.slice(1)
|
|
17
53
|
};
|
|
18
54
|
};
|
|
19
|
-
const
|
|
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
|
|
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
|
|
65
|
-
const digest = meta.registry.createType('RawBabePreDigest', consensus.
|
|
66
|
-
const newSlot = compactAddLength(meta.registry.createType('RawBabePreDigest',
|
|
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 = Math.max(1, meta.consts.timestamp
|
|
77
|
-
|
|
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
|
|
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
|
|
9
|
-
const currentTimestamp = await getCurrentTimestamp(parent
|
|
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
|
];
|
package/dist/esm/setup.d.ts
CHANGED
|
@@ -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
|
-
|
|
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: (
|
|
27
|
-
export declare const getCurrentTimestamp: (
|
|
28
|
-
export declare const getSlotDuration: (
|
|
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>;
|
package/dist/esm/utils/index.js
CHANGED
|
@@ -89,22 +89,24 @@ const POTENTIAL_SLOT_KEYS = [
|
|
|
89
89
|
'0x8985dff79e6002d0deba9ddac46f32a5a70806914c906d747e668a21f9021729',
|
|
90
90
|
'0xab2a8d5eca218f218c6fda6b1d22bb926bc171ab77f6a731a6e80c34ee1eda19'
|
|
91
91
|
];
|
|
92
|
-
export const getCurrentSlot = async (
|
|
93
|
-
const meta = await
|
|
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
|
|
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
|
-
|
|
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 (
|
|
103
|
-
const meta = await
|
|
104
|
-
const timestamp = await
|
|
105
|
-
return timestamp?.toBigInt() ??
|
|
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 (
|
|
108
|
-
const meta = await
|
|
109
|
-
return meta.consts.babe ? meta.consts.babe.expectedBlockTime.toNumber() : meta.query.aura ? getAuraSlotDuration(await
|
|
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.
|
|
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.
|
|
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",
|