@acala-network/chopsticks-core 0.8.0-0
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/lib/api.d.ts +43 -0
- package/lib/api.js +116 -0
- package/lib/blockchain/block-builder.d.ts +10 -0
- package/lib/blockchain/block-builder.js +290 -0
- package/lib/blockchain/block.d.ts +45 -0
- package/lib/blockchain/block.js +221 -0
- package/lib/blockchain/head-state.d.ts +15 -0
- package/lib/blockchain/head-state.js +94 -0
- package/lib/blockchain/index.d.ts +73 -0
- package/lib/blockchain/index.js +351 -0
- package/lib/blockchain/inherent/index.d.ts +19 -0
- package/lib/blockchain/inherent/index.js +53 -0
- package/lib/blockchain/inherent/para-enter.d.ts +7 -0
- package/lib/blockchain/inherent/para-enter.js +37 -0
- package/lib/blockchain/inherent/parachain/babe-randomness.d.ts +7 -0
- package/lib/blockchain/inherent/parachain/babe-randomness.js +23 -0
- package/lib/blockchain/inherent/parachain/nimbus-author-inherent.d.ts +7 -0
- package/lib/blockchain/inherent/parachain/nimbus-author-inherent.js +23 -0
- package/lib/blockchain/inherent/parachain/validation-data.d.ts +19 -0
- package/lib/blockchain/inherent/parachain/validation-data.js +165 -0
- package/lib/blockchain/storage-layer.d.ts +32 -0
- package/lib/blockchain/storage-layer.js +242 -0
- package/lib/blockchain/txpool.d.ts +44 -0
- package/lib/blockchain/txpool.js +210 -0
- package/lib/db/browser.d.ts +2 -0
- package/lib/db/browser.js +33 -0
- package/lib/db/entities.d.ts +16 -0
- package/lib/db/entities.js +50 -0
- package/lib/db/index.d.ts +1 -0
- package/lib/db/index.js +17 -0
- package/lib/db/node.d.ts +2 -0
- package/lib/db/node.js +22 -0
- package/lib/executor.d.ts +41 -0
- package/lib/executor.js +160 -0
- package/lib/genesis-provider.d.ts +44 -0
- package/lib/genesis-provider.js +172 -0
- package/lib/index.d.ts +13 -0
- package/lib/index.js +13 -0
- package/lib/logger.d.ts +7 -0
- package/lib/logger.js +34 -0
- package/lib/offchain.d.ts +10 -0
- package/lib/offchain.js +49 -0
- package/lib/schema/index.d.ts +62 -0
- package/lib/schema/index.js +11 -0
- package/lib/setup.d.ts +20 -0
- package/lib/setup.js +74 -0
- package/lib/utils/index.d.ts +18 -0
- package/lib/utils/index.js +65 -0
- package/lib/utils/key-cache.d.ts +10 -0
- package/lib/utils/key-cache.js +72 -0
- package/lib/utils/proof.d.ts +15 -0
- package/lib/utils/proof.js +33 -0
- package/lib/utils/set-storage.d.ts +7 -0
- package/lib/utils/set-storage.js +65 -0
- package/lib/utils/time-travel.d.ts +5 -0
- package/lib/utils/time-travel.js +67 -0
- package/lib/xcm/downward.d.ts +2 -0
- package/lib/xcm/downward.js +34 -0
- package/lib/xcm/horizontal.d.ts +2 -0
- package/lib/xcm/horizontal.js +34 -0
- package/lib/xcm/index.d.ts +9 -0
- package/lib/xcm/index.js +29 -0
- package/lib/xcm/upward.d.ts +2 -0
- package/lib/xcm/upward.js +26 -0
- package/package.json +46 -0
package/lib/api.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ExtDef } from '@polkadot/types/extrinsic/signedExtensions/types';
|
|
2
|
+
import { HexString } from '@polkadot/util/types';
|
|
3
|
+
import { ProviderInterface } from '@polkadot/rpc-provider/types';
|
|
4
|
+
type ChainProperties = {
|
|
5
|
+
ss58Format?: number;
|
|
6
|
+
tokenDecimals?: number[];
|
|
7
|
+
tokenSymbol?: string[];
|
|
8
|
+
};
|
|
9
|
+
type Header = {
|
|
10
|
+
parentHash: HexString;
|
|
11
|
+
number: HexString;
|
|
12
|
+
stateRoot: HexString;
|
|
13
|
+
extrinsicsRoot: HexString;
|
|
14
|
+
digest: {
|
|
15
|
+
logs: HexString[];
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
type SignedBlock = {
|
|
19
|
+
block: {
|
|
20
|
+
header: Header;
|
|
21
|
+
extrinsics: HexString[];
|
|
22
|
+
};
|
|
23
|
+
justifications?: HexString[];
|
|
24
|
+
};
|
|
25
|
+
export declare class Api {
|
|
26
|
+
#private;
|
|
27
|
+
readonly signedExtensions: ExtDef;
|
|
28
|
+
constructor(provider: ProviderInterface, signedExtensions?: ExtDef);
|
|
29
|
+
disconnect(): Promise<void>;
|
|
30
|
+
get isReady(): Promise<void> | undefined;
|
|
31
|
+
get chain(): Promise<string>;
|
|
32
|
+
get chainProperties(): Promise<ChainProperties>;
|
|
33
|
+
getSystemName(): Promise<string>;
|
|
34
|
+
getSystemProperties(): Promise<ChainProperties>;
|
|
35
|
+
getSystemChain(): Promise<string>;
|
|
36
|
+
getMetadata(hash?: string): Promise<string>;
|
|
37
|
+
getBlockHash(blockNumber?: number): Promise<`0x${string}`>;
|
|
38
|
+
getHeader(hash?: string): Promise<Header>;
|
|
39
|
+
getBlock(hash?: string): Promise<SignedBlock>;
|
|
40
|
+
getStorage(key: string, hash?: string): Promise<string>;
|
|
41
|
+
getKeysPaged(prefix: string, pageSize: number, startKey: string, hash?: string): Promise<string[]>;
|
|
42
|
+
}
|
|
43
|
+
export {};
|
package/lib/api.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
11
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
12
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
13
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
14
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
15
|
+
};
|
|
16
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
17
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
18
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
19
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
20
|
+
};
|
|
21
|
+
var _Api_provider, _Api_ready, _Api_chain, _Api_chainProperties;
|
|
22
|
+
export class Api {
|
|
23
|
+
constructor(provider, signedExtensions) {
|
|
24
|
+
_Api_provider.set(this, void 0);
|
|
25
|
+
_Api_ready.set(this, void 0);
|
|
26
|
+
_Api_chain.set(this, void 0);
|
|
27
|
+
_Api_chainProperties.set(this, void 0);
|
|
28
|
+
__classPrivateFieldSet(this, _Api_provider, provider, "f");
|
|
29
|
+
this.signedExtensions = signedExtensions || {};
|
|
30
|
+
}
|
|
31
|
+
disconnect() {
|
|
32
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
33
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").disconnect();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
get isReady() {
|
|
37
|
+
if (!__classPrivateFieldGet(this, _Api_ready, "f")) {
|
|
38
|
+
if (__classPrivateFieldGet(this, _Api_provider, "f")['isReady']) {
|
|
39
|
+
__classPrivateFieldSet(this, _Api_ready, __classPrivateFieldGet(this, _Api_provider, "f")['isReady'], "f");
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
__classPrivateFieldSet(this, _Api_ready, new Promise((resolve) => {
|
|
43
|
+
__classPrivateFieldGet(this, _Api_provider, "f").on('connected', () => {
|
|
44
|
+
resolve();
|
|
45
|
+
});
|
|
46
|
+
__classPrivateFieldGet(this, _Api_provider, "f").connect();
|
|
47
|
+
}), "f");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return __classPrivateFieldGet(this, _Api_ready, "f");
|
|
51
|
+
}
|
|
52
|
+
get chain() {
|
|
53
|
+
if (!__classPrivateFieldGet(this, _Api_chain, "f")) {
|
|
54
|
+
__classPrivateFieldSet(this, _Api_chain, this.getSystemChain(), "f");
|
|
55
|
+
}
|
|
56
|
+
return __classPrivateFieldGet(this, _Api_chain, "f");
|
|
57
|
+
}
|
|
58
|
+
get chainProperties() {
|
|
59
|
+
if (!__classPrivateFieldGet(this, _Api_chainProperties, "f")) {
|
|
60
|
+
__classPrivateFieldSet(this, _Api_chainProperties, this.getSystemProperties(), "f");
|
|
61
|
+
}
|
|
62
|
+
return __classPrivateFieldGet(this, _Api_chainProperties, "f");
|
|
63
|
+
}
|
|
64
|
+
getSystemName() {
|
|
65
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('system_name', []);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
getSystemProperties() {
|
|
70
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('system_properties', []);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
getSystemChain() {
|
|
75
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('system_chain', []);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
getMetadata(hash) {
|
|
80
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
81
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('state_getMetadata', hash ? [hash] : []);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
getBlockHash(blockNumber) {
|
|
85
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
86
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('chain_getBlockHash', Number.isInteger(blockNumber) ? [blockNumber] : []);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
getHeader(hash) {
|
|
90
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('chain_getHeader', hash ? [hash] : []);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
getBlock(hash) {
|
|
95
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
96
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('chain_getBlock', hash ? [hash] : []);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
getStorage(key, hash) {
|
|
100
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
101
|
+
const params = [key];
|
|
102
|
+
if (hash)
|
|
103
|
+
params.push(hash);
|
|
104
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('state_getStorage', params);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
getKeysPaged(prefix, pageSize, startKey, hash) {
|
|
108
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
109
|
+
const params = [prefix, pageSize, startKey];
|
|
110
|
+
if (hash)
|
|
111
|
+
params.push(hash);
|
|
112
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('state_getKeysPaged', params);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
_Api_provider = new WeakMap(), _Api_ready = new WeakMap(), _Api_chain = new WeakMap(), _Api_chainProperties = new WeakMap();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Header, TransactionValidityError } from '@polkadot/types/interfaces';
|
|
2
|
+
import { Block, TaskCallResponse } from './block';
|
|
3
|
+
import { HexString } from '@polkadot/util/types';
|
|
4
|
+
export declare const newHeader: (head: Block) => Promise<Header>;
|
|
5
|
+
export declare const buildBlock: (head: Block, inherents: HexString[], extrinsics: HexString[], ump: Record<number, HexString[]>, onApplyExtrinsicError: (extrinsic: HexString, error: TransactionValidityError) => void) => Promise<[Block, HexString[]]>;
|
|
6
|
+
export declare const dryRunExtrinsic: (head: Block, inherents: HexString[], extrinsic: HexString | {
|
|
7
|
+
call: HexString;
|
|
8
|
+
address: string;
|
|
9
|
+
}) => Promise<TaskCallResponse>;
|
|
10
|
+
export declare const dryRunInherents: (head: Block, inherents: HexString[]) => Promise<[HexString, HexString | null][]>;
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { Block } from './block';
|
|
11
|
+
import { StorageLayer, StorageValueKind } from './storage-layer';
|
|
12
|
+
import { compactAddLength, hexToU8a, stringToHex, u8aConcat } from '@polkadot/util';
|
|
13
|
+
import { compactHex } from '../utils';
|
|
14
|
+
import { defaultLogger, truncate } from '../logger';
|
|
15
|
+
import { getCurrentSlot } from '../utils/time-travel';
|
|
16
|
+
const logger = defaultLogger.child({ name: 'block-builder' });
|
|
17
|
+
const getConsensus = (header) => {
|
|
18
|
+
if (header.digest.logs.length === 0)
|
|
19
|
+
return;
|
|
20
|
+
const preRuntime = header.digest.logs[0].asPreRuntime;
|
|
21
|
+
const [consensusEngine, slot] = preRuntime;
|
|
22
|
+
return { consensusEngine, slot, rest: header.digest.logs.slice(1) };
|
|
23
|
+
};
|
|
24
|
+
const getNewSlot = (digest, slotNumber) => {
|
|
25
|
+
if (digest.isPrimary) {
|
|
26
|
+
return {
|
|
27
|
+
primary: Object.assign(Object.assign({}, digest.asPrimary.toJSON()), { slotNumber }),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
if (digest.isSecondaryPlain) {
|
|
31
|
+
return {
|
|
32
|
+
secondaryPlain: Object.assign(Object.assign({}, digest.asSecondaryPlain.toJSON()), { slotNumber }),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (digest.isSecondaryVRF) {
|
|
36
|
+
return {
|
|
37
|
+
secondaryVRF: Object.assign(Object.assign({}, digest.asSecondaryVRF.toJSON()), { slotNumber }),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return digest.toJSON();
|
|
41
|
+
};
|
|
42
|
+
export const newHeader = (head) => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
+
var _a, _b;
|
|
44
|
+
const meta = yield head.meta;
|
|
45
|
+
const parentHeader = yield head.header;
|
|
46
|
+
let newLogs = parentHeader.digest.logs;
|
|
47
|
+
const consensus = getConsensus(parentHeader);
|
|
48
|
+
if (consensus === null || consensus === void 0 ? void 0 : consensus.consensusEngine.isAura) {
|
|
49
|
+
const slot = yield getCurrentSlot(head.chain);
|
|
50
|
+
const newSlot = compactAddLength(meta.registry.createType('Slot', slot + 1).toU8a());
|
|
51
|
+
newLogs = [{ PreRuntime: [consensus.consensusEngine, newSlot] }, ...consensus.rest];
|
|
52
|
+
}
|
|
53
|
+
else if (consensus === null || consensus === void 0 ? void 0 : consensus.consensusEngine.isBabe) {
|
|
54
|
+
const slot = yield getCurrentSlot(head.chain);
|
|
55
|
+
const digest = meta.registry.createType('RawBabePreDigest', consensus.slot);
|
|
56
|
+
const newSlot = compactAddLength(meta.registry.createType('RawBabePreDigest', getNewSlot(digest, slot + 1)).toU8a());
|
|
57
|
+
newLogs = [{ PreRuntime: [consensus.consensusEngine, newSlot] }, ...consensus.rest];
|
|
58
|
+
}
|
|
59
|
+
else if (((_a = consensus === null || consensus === void 0 ? void 0 : consensus.consensusEngine) === null || _a === void 0 ? void 0 : _a.toString()) == 'nmbs') {
|
|
60
|
+
const nmbsKey = stringToHex('nmbs');
|
|
61
|
+
newLogs = [
|
|
62
|
+
{
|
|
63
|
+
// Using previous block author
|
|
64
|
+
PreRuntime: [
|
|
65
|
+
consensus.consensusEngine,
|
|
66
|
+
(_b = parentHeader.digest.logs
|
|
67
|
+
.find((log) => log.isPreRuntime && log.asPreRuntime[0].toHex() == nmbsKey)) === null || _b === void 0 ? void 0 : _b.asPreRuntime[1].toHex(),
|
|
68
|
+
],
|
|
69
|
+
},
|
|
70
|
+
...consensus.rest,
|
|
71
|
+
];
|
|
72
|
+
if (meta.query.randomness) {
|
|
73
|
+
// TODO: shouldn't modify existing head
|
|
74
|
+
// reset notFirstBlock so randomness will skip validation
|
|
75
|
+
head.pushStorageLayer().set(compactHex(meta.query.randomness.notFirstBlock()), StorageValueKind.Deleted);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const header = meta.registry.createType('Header', {
|
|
79
|
+
parentHash: head.hash,
|
|
80
|
+
number: head.number + 1,
|
|
81
|
+
stateRoot: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
82
|
+
extrinsicsRoot: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
83
|
+
digest: {
|
|
84
|
+
logs: newLogs,
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
return header;
|
|
88
|
+
});
|
|
89
|
+
const initNewBlock = (head, header, inherents, storageLayer) => __awaiter(void 0, void 0, void 0, function* () {
|
|
90
|
+
const blockNumber = header.number.toNumber();
|
|
91
|
+
const hash = `0x${Math.round(Math.random() * 100000000)
|
|
92
|
+
.toString(16)
|
|
93
|
+
.padEnd(64, '0')}`;
|
|
94
|
+
const newBlock = new Block(head.chain, blockNumber, hash, head, {
|
|
95
|
+
header,
|
|
96
|
+
extrinsics: [],
|
|
97
|
+
storage: storageLayer !== null && storageLayer !== void 0 ? storageLayer : head.storage,
|
|
98
|
+
});
|
|
99
|
+
{
|
|
100
|
+
// initialize block
|
|
101
|
+
const { storageDiff } = yield newBlock.call('Core_initialize_block', [header.toHex()]);
|
|
102
|
+
newBlock.pushStorageLayer().setAll(storageDiff);
|
|
103
|
+
logger.trace(truncate(storageDiff), 'Initialize block');
|
|
104
|
+
}
|
|
105
|
+
const layers = [];
|
|
106
|
+
// apply inherents
|
|
107
|
+
for (const extrinsic of inherents) {
|
|
108
|
+
try {
|
|
109
|
+
const { storageDiff } = yield newBlock.call('BlockBuilder_apply_extrinsic', [extrinsic]);
|
|
110
|
+
const layer = newBlock.pushStorageLayer();
|
|
111
|
+
layer.setAll(storageDiff);
|
|
112
|
+
layers.push(layer);
|
|
113
|
+
logger.trace(truncate(storageDiff), 'Applied inherent');
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
logger.warn('Failed to apply inherents %o %s', e, e);
|
|
117
|
+
throw new Error('Failed to apply inherents');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
block: newBlock,
|
|
122
|
+
layers: layers,
|
|
123
|
+
};
|
|
124
|
+
});
|
|
125
|
+
export const buildBlock = (head, inherents, extrinsics, ump, onApplyExtrinsicError) => __awaiter(void 0, void 0, void 0, function* () {
|
|
126
|
+
const registry = yield head.registry;
|
|
127
|
+
const header = yield newHeader(head);
|
|
128
|
+
logger.info({
|
|
129
|
+
number: head.number + 1,
|
|
130
|
+
extrinsicsCount: extrinsics.length,
|
|
131
|
+
umpCount: Object.keys(ump).length,
|
|
132
|
+
}, `Try building block #${(head.number + 1).toLocaleString()}`);
|
|
133
|
+
let layer;
|
|
134
|
+
// apply ump via storage override hack
|
|
135
|
+
if (Object.keys(ump).length > 0) {
|
|
136
|
+
const meta = yield head.meta;
|
|
137
|
+
layer = new StorageLayer(head.storage);
|
|
138
|
+
for (const [paraId, upwardMessages] of Object.entries(ump)) {
|
|
139
|
+
const upwardMessagesU8a = upwardMessages.map((x) => hexToU8a(x));
|
|
140
|
+
const messagesCount = upwardMessages.length;
|
|
141
|
+
const messagesSize = upwardMessagesU8a.map((x) => x.length).reduce((s, i) => s + i, 0);
|
|
142
|
+
if (meta.query.ump) {
|
|
143
|
+
const queueSize = meta.registry.createType('(u32, u32)', [messagesCount, messagesSize]);
|
|
144
|
+
const messages = meta.registry.createType('Vec<Bytes>', upwardMessages);
|
|
145
|
+
// TODO: make sure we append instead of replace
|
|
146
|
+
layer.setAll([
|
|
147
|
+
[compactHex(meta.query.ump.relayDispatchQueues(paraId)), messages.toHex()],
|
|
148
|
+
[compactHex(meta.query.ump.relayDispatchQueueSize(paraId)), queueSize.toHex()],
|
|
149
|
+
]);
|
|
150
|
+
}
|
|
151
|
+
else if (meta.query.messageQueue) {
|
|
152
|
+
// TODO: make sure we append instead of replace
|
|
153
|
+
const origin = { ump: { para: paraId } };
|
|
154
|
+
let last = 0;
|
|
155
|
+
let heap = new Uint8Array(0);
|
|
156
|
+
for (const message of upwardMessagesU8a) {
|
|
157
|
+
const payloadLen = message.length;
|
|
158
|
+
const header = meta.registry.createType('(u32, bool)', [payloadLen, false]);
|
|
159
|
+
last = heap.length;
|
|
160
|
+
heap = u8aConcat(heap, header.toU8a(), message);
|
|
161
|
+
}
|
|
162
|
+
layer.setAll([
|
|
163
|
+
[
|
|
164
|
+
compactHex(meta.query.messageQueue.bookStateFor(origin)),
|
|
165
|
+
meta.registry
|
|
166
|
+
.createType('PalletMessageQueueBookState', {
|
|
167
|
+
begin: 0,
|
|
168
|
+
end: 1,
|
|
169
|
+
count: 1,
|
|
170
|
+
readyNeighbours: { prev: origin, next: origin },
|
|
171
|
+
messageCount: messagesCount,
|
|
172
|
+
size_: messagesSize,
|
|
173
|
+
})
|
|
174
|
+
.toHex(),
|
|
175
|
+
],
|
|
176
|
+
[
|
|
177
|
+
compactHex(meta.query.messageQueue.serviceHead(origin)),
|
|
178
|
+
meta.registry.createType('PolkadotRuntimeParachainsInclusionAggregateMessageOrigin', origin).toHex(),
|
|
179
|
+
],
|
|
180
|
+
[
|
|
181
|
+
compactHex(meta.query.messageQueue.pages(origin, 0)),
|
|
182
|
+
meta.registry
|
|
183
|
+
.createType('PalletMessageQueuePage', {
|
|
184
|
+
remaining: messagesCount,
|
|
185
|
+
remaining_size: messagesSize,
|
|
186
|
+
first_index: 0,
|
|
187
|
+
first: 0,
|
|
188
|
+
last,
|
|
189
|
+
heap: compactAddLength(heap),
|
|
190
|
+
})
|
|
191
|
+
.toHex(),
|
|
192
|
+
],
|
|
193
|
+
]);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
throw new Error('Unknown ump storage');
|
|
197
|
+
}
|
|
198
|
+
logger.trace({ paraId, upwardMessages: truncate(upwardMessages) }, 'Pushed UMP');
|
|
199
|
+
}
|
|
200
|
+
if (meta.query.ump) {
|
|
201
|
+
const needsDispatch = meta.registry.createType('Vec<u32>', Object.keys(ump));
|
|
202
|
+
layer.set(compactHex(meta.query.ump.needsDispatch()), needsDispatch.toHex());
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const { block: newBlock } = yield initNewBlock(head, header, inherents, layer);
|
|
206
|
+
const pendingExtrinsics = [];
|
|
207
|
+
const includedExtrinsic = [];
|
|
208
|
+
// apply extrinsics
|
|
209
|
+
for (const extrinsic of extrinsics) {
|
|
210
|
+
try {
|
|
211
|
+
const { result, storageDiff } = yield newBlock.call('BlockBuilder_apply_extrinsic', [extrinsic]);
|
|
212
|
+
const outcome = registry.createType('ApplyExtrinsicResult', result);
|
|
213
|
+
if (outcome.isErr) {
|
|
214
|
+
onApplyExtrinsicError(extrinsic, outcome.asErr);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
newBlock.pushStorageLayer().setAll(storageDiff);
|
|
218
|
+
logger.trace(truncate(storageDiff), 'Applied extrinsic');
|
|
219
|
+
includedExtrinsic.push(extrinsic);
|
|
220
|
+
}
|
|
221
|
+
catch (e) {
|
|
222
|
+
logger.info('Failed to apply extrinsic %o %s', e, e);
|
|
223
|
+
pendingExtrinsics.push(extrinsic);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
{
|
|
227
|
+
// finalize block
|
|
228
|
+
const { storageDiff } = yield newBlock.call('BlockBuilder_finalize_block', []);
|
|
229
|
+
newBlock.pushStorageLayer().setAll(storageDiff);
|
|
230
|
+
logger.trace(truncate(storageDiff), 'Finalize block');
|
|
231
|
+
}
|
|
232
|
+
const blockData = registry.createType('Block', {
|
|
233
|
+
header,
|
|
234
|
+
extrinsics: includedExtrinsic,
|
|
235
|
+
});
|
|
236
|
+
const storageDiff = yield newBlock.storageDiff();
|
|
237
|
+
logger.trace(Object.entries(storageDiff).map(([key, value]) => [key, truncate(value)]), 'Final block');
|
|
238
|
+
const finalBlock = new Block(head.chain, newBlock.number, blockData.hash.toHex(), head, {
|
|
239
|
+
header,
|
|
240
|
+
extrinsics: [...inherents, ...includedExtrinsic],
|
|
241
|
+
storage: head.storage,
|
|
242
|
+
storageDiff,
|
|
243
|
+
});
|
|
244
|
+
logger.info({
|
|
245
|
+
number: newBlock.number,
|
|
246
|
+
hash: finalBlock.hash,
|
|
247
|
+
extrinsics: truncate(includedExtrinsic),
|
|
248
|
+
pendingExtrinsicsCount: pendingExtrinsics.length,
|
|
249
|
+
ump: truncate(ump),
|
|
250
|
+
}, 'Block built');
|
|
251
|
+
return [finalBlock, pendingExtrinsics];
|
|
252
|
+
});
|
|
253
|
+
export const dryRunExtrinsic = (head, inherents, extrinsic) => __awaiter(void 0, void 0, void 0, function* () {
|
|
254
|
+
const registry = yield head.registry;
|
|
255
|
+
const header = yield newHeader(head);
|
|
256
|
+
const { block: newBlock } = yield initNewBlock(head, header, inherents);
|
|
257
|
+
if (typeof extrinsic !== 'string') {
|
|
258
|
+
if (!head.chain.mockSignatureHost) {
|
|
259
|
+
throw new Error('Cannot fake signature because mock signature host is not enabled. Start chain with `mockSignatureHost: true`');
|
|
260
|
+
}
|
|
261
|
+
const meta = yield head.meta;
|
|
262
|
+
const call = registry.createType('Call', hexToU8a(extrinsic.call));
|
|
263
|
+
const generic = registry.createType('GenericExtrinsic', call);
|
|
264
|
+
const accountRaw = yield head.get(compactHex(meta.query.system.account(extrinsic.address)));
|
|
265
|
+
const account = registry.createType('AccountInfo', hexToU8a(accountRaw));
|
|
266
|
+
generic.signFake(extrinsic.address, {
|
|
267
|
+
blockHash: head.hash,
|
|
268
|
+
genesisHash: head.hash,
|
|
269
|
+
runtimeVersion: yield head.runtimeVersion,
|
|
270
|
+
nonce: account.nonce,
|
|
271
|
+
});
|
|
272
|
+
const mockSignature = new Uint8Array(64);
|
|
273
|
+
mockSignature.fill(0xcd);
|
|
274
|
+
mockSignature.set([0xde, 0xad, 0xbe, 0xef]);
|
|
275
|
+
generic.signature.set(mockSignature);
|
|
276
|
+
defaultLogger.info({ call: call.toHuman() }, 'dry_run_call');
|
|
277
|
+
return newBlock.call('BlockBuilder_apply_extrinsic', [generic.toHex()]);
|
|
278
|
+
}
|
|
279
|
+
defaultLogger.info({ call: registry.createType('GenericExtrinsic', hexToU8a(extrinsic)).toHuman() }, 'dry_run_extrinsic');
|
|
280
|
+
return newBlock.call('BlockBuilder_apply_extrinsic', [extrinsic]);
|
|
281
|
+
});
|
|
282
|
+
export const dryRunInherents = (head, inherents) => __awaiter(void 0, void 0, void 0, function* () {
|
|
283
|
+
const header = yield newHeader(head);
|
|
284
|
+
const { layers } = yield initNewBlock(head, header, inherents);
|
|
285
|
+
const storage = {};
|
|
286
|
+
for (const layer of layers) {
|
|
287
|
+
yield layer.mergeInto(storage);
|
|
288
|
+
}
|
|
289
|
+
return Object.entries(storage);
|
|
290
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Header } from '@polkadot/types/interfaces';
|
|
2
|
+
import { DecoratedMeta } from '@polkadot/types/metadata/decorate/types';
|
|
3
|
+
import { TypeRegistry } from '@polkadot/types';
|
|
4
|
+
import type { HexString } from '@polkadot/util/types';
|
|
5
|
+
import { Blockchain } from '.';
|
|
6
|
+
import { StorageLayer, StorageLayerProvider, StorageValue } from './storage-layer';
|
|
7
|
+
import type { RuntimeVersion } from '../executor';
|
|
8
|
+
export type TaskCallResponse = {
|
|
9
|
+
result: HexString;
|
|
10
|
+
storageDiff: [HexString, HexString | null][];
|
|
11
|
+
offchainStorageDiff: [HexString, HexString | null][];
|
|
12
|
+
runtimeLogs: string[];
|
|
13
|
+
};
|
|
14
|
+
export declare class Block {
|
|
15
|
+
#private;
|
|
16
|
+
readonly number: number;
|
|
17
|
+
readonly hash: HexString;
|
|
18
|
+
constructor(chain: Blockchain, number: number, hash: HexString, parentBlock?: Block, block?: {
|
|
19
|
+
header: Header;
|
|
20
|
+
extrinsics: HexString[];
|
|
21
|
+
storage?: StorageLayerProvider;
|
|
22
|
+
storageDiff?: Record<string, StorageValue | null>;
|
|
23
|
+
});
|
|
24
|
+
get chain(): Blockchain;
|
|
25
|
+
get header(): Header | Promise<Header>;
|
|
26
|
+
get extrinsics(): HexString[] | Promise<HexString[]>;
|
|
27
|
+
get parentBlock(): undefined | Block | Promise<Block | undefined>;
|
|
28
|
+
get storage(): StorageLayerProvider;
|
|
29
|
+
get(key: string): Promise<string | undefined>;
|
|
30
|
+
getKeysPaged(options: {
|
|
31
|
+
prefix?: string;
|
|
32
|
+
startKey?: string;
|
|
33
|
+
pageSize: number;
|
|
34
|
+
}): Promise<string[]>;
|
|
35
|
+
pushStorageLayer(): StorageLayer;
|
|
36
|
+
popStorageLayer(): void;
|
|
37
|
+
storageDiff(): Promise<Record<HexString, HexString | null>>;
|
|
38
|
+
get wasm(): Promise<`0x${string}`>;
|
|
39
|
+
setWasm(wasm: HexString): void;
|
|
40
|
+
get registry(): Promise<TypeRegistry>;
|
|
41
|
+
get runtimeVersion(): Promise<RuntimeVersion>;
|
|
42
|
+
get metadata(): Promise<HexString>;
|
|
43
|
+
get meta(): Promise<DecoratedMeta>;
|
|
44
|
+
call(method: string, args: HexString[]): Promise<TaskCallResponse>;
|
|
45
|
+
}
|