@acala-network/chopsticks-core 0.8.5-5 → 0.9.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 → dist/cjs}/api.js +7 -7
- package/{lib → dist/cjs}/blockchain/block.js +1 -4
- package/{lib → dist/cjs}/genesis-provider.js +1 -1
- package/{lib → dist/cjs}/rpc/substrate/chain.js +1 -1
- package/{lib → dist/cjs}/utils/index.js +11 -1
- package/dist/esm/api.js +125 -0
- package/dist/esm/blockchain/block-builder.js +293 -0
- package/dist/esm/blockchain/block.js +277 -0
- package/dist/esm/blockchain/head-state.js +79 -0
- package/dist/esm/blockchain/index.js +413 -0
- package/dist/esm/blockchain/inherent/index.js +40 -0
- package/dist/esm/blockchain/inherent/para-enter.js +29 -0
- package/dist/esm/blockchain/inherent/parachain/babe-randomness.js +11 -0
- package/dist/esm/blockchain/inherent/parachain/nimbus-author-inherent.js +11 -0
- package/dist/esm/blockchain/inherent/parachain/validation-data.js +165 -0
- package/dist/esm/blockchain/storage-layer.js +215 -0
- package/dist/esm/blockchain/txpool.js +208 -0
- package/dist/esm/chopsticks-provider.js +156 -0
- package/dist/esm/database.js +1 -0
- package/dist/esm/genesis-provider.js +144 -0
- package/dist/esm/logger.js +34 -0
- package/dist/esm/offchain.js +36 -0
- package/dist/esm/rpc/index.js +10 -0
- package/dist/esm/rpc/shared.js +15 -0
- package/dist/esm/rpc/substrate/author.js +85 -0
- package/dist/esm/rpc/substrate/chain.js +84 -0
- package/dist/esm/rpc/substrate/index.js +18 -0
- package/dist/esm/rpc/substrate/payment.js +40 -0
- package/dist/esm/rpc/substrate/state.js +166 -0
- package/dist/esm/rpc/substrate/system.js +48 -0
- package/dist/esm/schema/index.js +11 -0
- package/dist/esm/setup.js +71 -0
- package/dist/esm/utils/decoder.js +95 -0
- package/dist/esm/utils/index.js +91 -0
- package/dist/esm/utils/key-cache.js +61 -0
- package/dist/esm/utils/proof.js +33 -0
- package/dist/esm/utils/set-storage.js +56 -0
- package/dist/esm/utils/time-travel.js +58 -0
- package/dist/esm/wasm-executor/browser-wasm-executor.mjs +32 -0
- package/dist/esm/wasm-executor/browser-worker.js +15 -0
- package/dist/esm/wasm-executor/index.js +146 -0
- package/dist/esm/wasm-executor/node-wasm-executor.mjs +29 -0
- package/dist/esm/wasm-executor/node-worker.js +15 -0
- package/dist/esm/xcm/downward.js +25 -0
- package/dist/esm/xcm/horizontal.js +25 -0
- package/dist/esm/xcm/index.js +20 -0
- package/dist/esm/xcm/upward.js +17 -0
- package/{lib → dist/types}/genesis-provider.d.ts +2 -2
- package/dist/types/index.d.ts +28 -0
- package/{lib → dist/types}/utils/index.d.ts +1 -0
- package/package.json +23 -14
- /package/{lib → dist/cjs}/blockchain/block-builder.js +0 -0
- /package/{lib → dist/cjs}/blockchain/head-state.js +0 -0
- /package/{lib → dist/cjs}/blockchain/index.js +0 -0
- /package/{lib → dist/cjs}/blockchain/inherent/index.js +0 -0
- /package/{lib → dist/cjs}/blockchain/inherent/para-enter.js +0 -0
- /package/{lib → dist/cjs}/blockchain/inherent/parachain/babe-randomness.js +0 -0
- /package/{lib → dist/cjs}/blockchain/inherent/parachain/nimbus-author-inherent.js +0 -0
- /package/{lib → dist/cjs}/blockchain/inherent/parachain/validation-data.js +0 -0
- /package/{lib → dist/cjs}/blockchain/storage-layer.js +0 -0
- /package/{lib → dist/cjs}/blockchain/txpool.js +0 -0
- /package/{lib → dist/cjs}/chopsticks-provider.js +0 -0
- /package/{lib → dist/cjs}/database.js +0 -0
- /package/{lib → dist/cjs}/index.js +0 -0
- /package/{lib → dist/cjs}/logger.js +0 -0
- /package/{lib → dist/cjs}/offchain.js +0 -0
- /package/{lib → dist/cjs}/rpc/index.js +0 -0
- /package/{lib → dist/cjs}/rpc/shared.js +0 -0
- /package/{lib → dist/cjs}/rpc/substrate/author.js +0 -0
- /package/{lib → dist/cjs}/rpc/substrate/index.js +0 -0
- /package/{lib → dist/cjs}/rpc/substrate/payment.js +0 -0
- /package/{lib → dist/cjs}/rpc/substrate/state.js +0 -0
- /package/{lib → dist/cjs}/rpc/substrate/system.js +0 -0
- /package/{lib → dist/cjs}/schema/index.js +0 -0
- /package/{lib → dist/cjs}/setup.js +0 -0
- /package/{lib → dist/cjs}/utils/decoder.js +0 -0
- /package/{lib → dist/cjs}/utils/key-cache.js +0 -0
- /package/{lib → dist/cjs}/utils/proof.js +0 -0
- /package/{lib → dist/cjs}/utils/set-storage.js +0 -0
- /package/{lib → dist/cjs}/utils/time-travel.js +0 -0
- /package/{lib → dist/cjs}/wasm-executor/browser-wasm-executor.mjs +0 -0
- /package/{lib → dist/cjs}/wasm-executor/browser-worker.js +0 -0
- /package/{lib → dist/cjs}/wasm-executor/index.js +0 -0
- /package/{lib → dist/cjs}/wasm-executor/node-wasm-executor.mjs +0 -0
- /package/{lib → dist/cjs}/wasm-executor/node-worker.js +0 -0
- /package/{lib → dist/cjs}/xcm/downward.js +0 -0
- /package/{lib → dist/cjs}/xcm/horizontal.js +0 -0
- /package/{lib → dist/cjs}/xcm/index.js +0 -0
- /package/{lib → dist/cjs}/xcm/upward.js +0 -0
- /package/{lib/index.d.ts → dist/esm/index.js} +0 -0
- /package/{lib → dist/types}/api.d.ts +0 -0
- /package/{lib → dist/types}/blockchain/block-builder.d.ts +0 -0
- /package/{lib → dist/types}/blockchain/block.d.ts +0 -0
- /package/{lib → dist/types}/blockchain/head-state.d.ts +0 -0
- /package/{lib → dist/types}/blockchain/index.d.ts +0 -0
- /package/{lib → dist/types}/blockchain/inherent/index.d.ts +0 -0
- /package/{lib → dist/types}/blockchain/inherent/para-enter.d.ts +0 -0
- /package/{lib → dist/types}/blockchain/inherent/parachain/babe-randomness.d.ts +0 -0
- /package/{lib → dist/types}/blockchain/inherent/parachain/nimbus-author-inherent.d.ts +0 -0
- /package/{lib → dist/types}/blockchain/inherent/parachain/validation-data.d.ts +0 -0
- /package/{lib → dist/types}/blockchain/storage-layer.d.ts +0 -0
- /package/{lib → dist/types}/blockchain/txpool.d.ts +0 -0
- /package/{lib → dist/types}/chopsticks-provider.d.ts +0 -0
- /package/{lib → dist/types}/database.d.ts +0 -0
- /package/{lib → dist/types}/logger.d.ts +0 -0
- /package/{lib → dist/types}/offchain.d.ts +0 -0
- /package/{lib → dist/types}/rpc/index.d.ts +0 -0
- /package/{lib → dist/types}/rpc/shared.d.ts +0 -0
- /package/{lib → dist/types}/rpc/substrate/author.d.ts +0 -0
- /package/{lib → dist/types}/rpc/substrate/chain.d.ts +0 -0
- /package/{lib → dist/types}/rpc/substrate/index.d.ts +0 -0
- /package/{lib → dist/types}/rpc/substrate/payment.d.ts +0 -0
- /package/{lib → dist/types}/rpc/substrate/state.d.ts +0 -0
- /package/{lib → dist/types}/rpc/substrate/system.d.ts +0 -0
- /package/{lib → dist/types}/schema/index.d.ts +0 -0
- /package/{lib → dist/types}/setup.d.ts +0 -0
- /package/{lib → dist/types}/utils/decoder.d.ts +0 -0
- /package/{lib → dist/types}/utils/key-cache.d.ts +0 -0
- /package/{lib → dist/types}/utils/proof.d.ts +0 -0
- /package/{lib → dist/types}/utils/set-storage.d.ts +0 -0
- /package/{lib → dist/types}/utils/time-travel.d.ts +0 -0
- /package/{lib → dist/types}/wasm-executor/browser-worker.d.ts +0 -0
- /package/{lib → dist/types}/wasm-executor/index.d.ts +0 -0
- /package/{lib → dist/types}/wasm-executor/node-worker.d.ts +0 -0
- /package/{lib → dist/types}/xcm/downward.d.ts +0 -0
- /package/{lib → dist/types}/xcm/horizontal.d.ts +0 -0
- /package/{lib → dist/types}/xcm/index.d.ts +0 -0
- /package/{lib → dist/types}/xcm/upward.d.ts +0 -0
package/{lib → dist/cjs}/api.js
RENAMED
|
@@ -79,13 +79,13 @@ class Api {
|
|
|
79
79
|
return __classPrivateFieldGet(this, _Api_provider, "f").send('system_chain', []);
|
|
80
80
|
}
|
|
81
81
|
async getBlockHash(blockNumber) {
|
|
82
|
-
return __classPrivateFieldGet(this, _Api_provider, "f").send('chain_getBlockHash', Number.isInteger(blockNumber) ? [blockNumber] : []);
|
|
82
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('chain_getBlockHash', Number.isInteger(blockNumber) ? [blockNumber] : [], !!blockNumber);
|
|
83
83
|
}
|
|
84
84
|
async getHeader(hash) {
|
|
85
|
-
return __classPrivateFieldGet(this, _Api_provider, "f").send('chain_getHeader', hash ? [hash] : []);
|
|
85
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('chain_getHeader', hash ? [hash] : [], !!hash);
|
|
86
86
|
}
|
|
87
87
|
async getBlock(hash) {
|
|
88
|
-
return __classPrivateFieldGet(this, _Api_provider, "f").send('chain_getBlock', hash ? [hash] : []);
|
|
88
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('chain_getBlock', hash ? [hash] : [], !!hash);
|
|
89
89
|
}
|
|
90
90
|
async getStorage(key, hash) {
|
|
91
91
|
const [child, storageKey] = (0, utils_1.splitChildKey)(key);
|
|
@@ -94,14 +94,14 @@ class Api {
|
|
|
94
94
|
const params = [child, storageKey];
|
|
95
95
|
if (hash)
|
|
96
96
|
params.push(hash);
|
|
97
|
-
return __classPrivateFieldGet(this, _Api_provider, "f").send('childstate_getStorage', params);
|
|
97
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('childstate_getStorage', params, !!hash);
|
|
98
98
|
}
|
|
99
99
|
else {
|
|
100
100
|
// main storage key, use state_getStorage
|
|
101
101
|
const params = [key];
|
|
102
102
|
if (hash)
|
|
103
103
|
params.push(hash);
|
|
104
|
-
return __classPrivateFieldGet(this, _Api_provider, "f").send('state_getStorage', params);
|
|
104
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('state_getStorage', params, !!hash);
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
async getKeysPaged(prefix, pageSize, startKey, hash) {
|
|
@@ -113,7 +113,7 @@ class Api {
|
|
|
113
113
|
if (hash)
|
|
114
114
|
params.push(hash);
|
|
115
115
|
return __classPrivateFieldGet(this, _Api_provider, "f")
|
|
116
|
-
.send('childstate_getKeysPaged', params)
|
|
116
|
+
.send('childstate_getKeysPaged', params, !!hash)
|
|
117
117
|
.then((keys) => keys.map((key) => (0, utils_1.prefixedChildKey)(child, key)));
|
|
118
118
|
}
|
|
119
119
|
else {
|
|
@@ -121,7 +121,7 @@ class Api {
|
|
|
121
121
|
const params = [prefix, pageSize, startKey];
|
|
122
122
|
if (hash)
|
|
123
123
|
params.push(hash);
|
|
124
|
-
return __classPrivateFieldGet(this, _Api_provider, "f").send('state_getKeysPaged', params);
|
|
124
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('state_getKeysPaged', params, !!hash);
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
}
|
|
@@ -19,7 +19,6 @@ const util_1 = require("@polkadot/types-known/util");
|
|
|
19
19
|
const util_2 = require("@polkadot/util");
|
|
20
20
|
const storage_layer_1 = require("./storage-layer");
|
|
21
21
|
const utils_1 = require("../utils");
|
|
22
|
-
const logger_1 = require("../logger");
|
|
23
22
|
const wasm_executor_1 = require("../wasm-executor");
|
|
24
23
|
/**
|
|
25
24
|
* Block class.
|
|
@@ -264,9 +263,7 @@ class Block {
|
|
|
264
263
|
runtimeLogLevel: __classPrivateFieldGet(this, _Block_chain, "f").runtimeLogLevel,
|
|
265
264
|
}, (0, wasm_executor_1.taskHandler)(this));
|
|
266
265
|
if ('Call' in response) {
|
|
267
|
-
|
|
268
|
-
logger_1.defaultLogger.info(`RuntimeLogs:\n${log}`);
|
|
269
|
-
}
|
|
266
|
+
(0, utils_1.printRuntimeLogs)(response.Call.runtimeLogs);
|
|
270
267
|
if (this.chain.offchainWorker) {
|
|
271
268
|
// apply offchain storage
|
|
272
269
|
for (const [key, value] of response.Call.offchainStorageDiff) {
|
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.stripChildPrefix = exports.splitChildKey = exports.isPrefixedChildKey = exports.prefixedChildKey = exports.defer = exports.isUrl = exports.getParaId = exports.compactHex = exports.fetchKeysToArray = exports.fetchKeys = void 0;
|
|
17
|
+
exports.printRuntimeLogs = exports.stripChildPrefix = exports.splitChildKey = exports.isPrefixedChildKey = exports.prefixedChildKey = exports.defer = exports.isUrl = exports.getParaId = exports.compactHex = exports.fetchKeysToArray = exports.fetchKeys = void 0;
|
|
18
18
|
const util_1 = require("@polkadot/util");
|
|
19
19
|
const hex_1 = require("@polkadot/util/hex");
|
|
20
20
|
__exportStar(require("./set-storage"), exports);
|
|
@@ -107,3 +107,13 @@ const stripChildPrefix = (key) => {
|
|
|
107
107
|
return storageKey;
|
|
108
108
|
};
|
|
109
109
|
exports.stripChildPrefix = stripChildPrefix;
|
|
110
|
+
const printRuntimeLogs = (logs) => {
|
|
111
|
+
if (!logs.length)
|
|
112
|
+
return;
|
|
113
|
+
console.group('RuntimeLogs:');
|
|
114
|
+
for (const log of logs) {
|
|
115
|
+
console.log(log);
|
|
116
|
+
}
|
|
117
|
+
console.groupEnd();
|
|
118
|
+
};
|
|
119
|
+
exports.printRuntimeLogs = printRuntimeLogs;
|
package/dist/esm/api.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
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");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
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");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _Api_provider, _Api_ready, _Api_chain, _Api_chainProperties;
|
|
13
|
+
import { prefixedChildKey, splitChildKey, stripChildPrefix } from './utils';
|
|
14
|
+
/**
|
|
15
|
+
* API class. Calls provider to get on-chain data.
|
|
16
|
+
* Either `endpoint` or `genesis` porvider must be provided.
|
|
17
|
+
*
|
|
18
|
+
* @example Instantiate an API
|
|
19
|
+
*
|
|
20
|
+
* ```ts
|
|
21
|
+
* const provider = new WsProvider(options.endpoint)
|
|
22
|
+
* const api = new Api(provider)
|
|
23
|
+
* await api.isReady
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export class Api {
|
|
27
|
+
constructor(provider, signedExtensions) {
|
|
28
|
+
_Api_provider.set(this, void 0);
|
|
29
|
+
_Api_ready.set(this, void 0);
|
|
30
|
+
_Api_chain.set(this, void 0);
|
|
31
|
+
_Api_chainProperties.set(this, void 0);
|
|
32
|
+
__classPrivateFieldSet(this, _Api_provider, provider, "f");
|
|
33
|
+
this.signedExtensions = signedExtensions || {};
|
|
34
|
+
}
|
|
35
|
+
async disconnect() {
|
|
36
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").disconnect();
|
|
37
|
+
}
|
|
38
|
+
get isReady() {
|
|
39
|
+
if (!__classPrivateFieldGet(this, _Api_ready, "f")) {
|
|
40
|
+
if (__classPrivateFieldGet(this, _Api_provider, "f")['isReady']) {
|
|
41
|
+
__classPrivateFieldSet(this, _Api_ready, __classPrivateFieldGet(this, _Api_provider, "f")['isReady'], "f");
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
__classPrivateFieldSet(this, _Api_ready, new Promise((resolve) => {
|
|
45
|
+
if (__classPrivateFieldGet(this, _Api_provider, "f").hasSubscriptions) {
|
|
46
|
+
__classPrivateFieldGet(this, _Api_provider, "f").on('connected', resolve);
|
|
47
|
+
__classPrivateFieldGet(this, _Api_provider, "f").connect();
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
resolve();
|
|
51
|
+
}
|
|
52
|
+
}), "f");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return __classPrivateFieldGet(this, _Api_ready, "f");
|
|
56
|
+
}
|
|
57
|
+
get chain() {
|
|
58
|
+
if (!__classPrivateFieldGet(this, _Api_chain, "f")) {
|
|
59
|
+
__classPrivateFieldSet(this, _Api_chain, this.getSystemChain(), "f");
|
|
60
|
+
}
|
|
61
|
+
return __classPrivateFieldGet(this, _Api_chain, "f");
|
|
62
|
+
}
|
|
63
|
+
get chainProperties() {
|
|
64
|
+
if (!__classPrivateFieldGet(this, _Api_chainProperties, "f")) {
|
|
65
|
+
__classPrivateFieldSet(this, _Api_chainProperties, this.getSystemProperties(), "f");
|
|
66
|
+
}
|
|
67
|
+
return __classPrivateFieldGet(this, _Api_chainProperties, "f");
|
|
68
|
+
}
|
|
69
|
+
async getSystemName() {
|
|
70
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('system_name', []);
|
|
71
|
+
}
|
|
72
|
+
async getSystemProperties() {
|
|
73
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('system_properties', []);
|
|
74
|
+
}
|
|
75
|
+
async getSystemChain() {
|
|
76
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('system_chain', []);
|
|
77
|
+
}
|
|
78
|
+
async getBlockHash(blockNumber) {
|
|
79
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('chain_getBlockHash', Number.isInteger(blockNumber) ? [blockNumber] : [], !!blockNumber);
|
|
80
|
+
}
|
|
81
|
+
async getHeader(hash) {
|
|
82
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('chain_getHeader', hash ? [hash] : [], !!hash);
|
|
83
|
+
}
|
|
84
|
+
async getBlock(hash) {
|
|
85
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('chain_getBlock', hash ? [hash] : [], !!hash);
|
|
86
|
+
}
|
|
87
|
+
async getStorage(key, hash) {
|
|
88
|
+
const [child, storageKey] = splitChildKey(key);
|
|
89
|
+
if (child) {
|
|
90
|
+
// child storage key, use childstate_getStorage
|
|
91
|
+
const params = [child, storageKey];
|
|
92
|
+
if (hash)
|
|
93
|
+
params.push(hash);
|
|
94
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('childstate_getStorage', params, !!hash);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// main storage key, use state_getStorage
|
|
98
|
+
const params = [key];
|
|
99
|
+
if (hash)
|
|
100
|
+
params.push(hash);
|
|
101
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('state_getStorage', params, !!hash);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async getKeysPaged(prefix, pageSize, startKey, hash) {
|
|
105
|
+
const [child, storageKey] = splitChildKey(prefix);
|
|
106
|
+
if (child) {
|
|
107
|
+
// child storage key, use childstate_getKeysPaged
|
|
108
|
+
// strip child prefix from startKey
|
|
109
|
+
const params = [child, storageKey, pageSize, stripChildPrefix(startKey)];
|
|
110
|
+
if (hash)
|
|
111
|
+
params.push(hash);
|
|
112
|
+
return __classPrivateFieldGet(this, _Api_provider, "f")
|
|
113
|
+
.send('childstate_getKeysPaged', params, !!hash)
|
|
114
|
+
.then((keys) => keys.map((key) => prefixedChildKey(child, key)));
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
// main storage key, use state_getKeysPaged
|
|
118
|
+
const params = [prefix, pageSize, startKey];
|
|
119
|
+
if (hash)
|
|
120
|
+
params.push(hash);
|
|
121
|
+
return __classPrivateFieldGet(this, _Api_provider, "f").send('state_getKeysPaged', params, !!hash);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
_Api_provider = new WeakMap(), _Api_ready = new WeakMap(), _Api_chain = new WeakMap(), _Api_chainProperties = new WeakMap();
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { Block } from './block';
|
|
2
|
+
import { StorageLayer, StorageValueKind } from './storage-layer';
|
|
3
|
+
import { compactAddLength, hexToU8a, stringToHex, u8aConcat } from '@polkadot/util';
|
|
4
|
+
import { compactHex } from '../utils';
|
|
5
|
+
import { defaultLogger, truncate } from '../logger';
|
|
6
|
+
import { getCurrentSlot } from '../utils/time-travel';
|
|
7
|
+
const logger = defaultLogger.child({ name: 'block-builder' });
|
|
8
|
+
const getConsensus = (header) => {
|
|
9
|
+
if (header.digest.logs.length === 0)
|
|
10
|
+
return;
|
|
11
|
+
const preRuntime = header.digest.logs[0].asPreRuntime;
|
|
12
|
+
const [consensusEngine, slot] = preRuntime;
|
|
13
|
+
return { consensusEngine, slot, rest: header.digest.logs.slice(1) };
|
|
14
|
+
};
|
|
15
|
+
const getNewSlot = (digest, slotNumber) => {
|
|
16
|
+
if (digest.isPrimary) {
|
|
17
|
+
return {
|
|
18
|
+
primary: {
|
|
19
|
+
...digest.asPrimary.toJSON(),
|
|
20
|
+
slotNumber,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (digest.isSecondaryPlain) {
|
|
25
|
+
return {
|
|
26
|
+
secondaryPlain: {
|
|
27
|
+
...digest.asSecondaryPlain.toJSON(),
|
|
28
|
+
slotNumber,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (digest.isSecondaryVRF) {
|
|
33
|
+
return {
|
|
34
|
+
secondaryVRF: {
|
|
35
|
+
...digest.asSecondaryVRF.toJSON(),
|
|
36
|
+
slotNumber,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return digest.toJSON();
|
|
41
|
+
};
|
|
42
|
+
export const newHeader = async (head, unsafeBlockHeight) => {
|
|
43
|
+
const meta = await head.meta;
|
|
44
|
+
const parentHeader = await head.header;
|
|
45
|
+
let newLogs = parentHeader.digest.logs;
|
|
46
|
+
const consensus = getConsensus(parentHeader);
|
|
47
|
+
if (consensus?.consensusEngine.isAura) {
|
|
48
|
+
const slot = await getCurrentSlot(head.chain);
|
|
49
|
+
const newSlot = compactAddLength(meta.registry.createType('Slot', slot + 1).toU8a());
|
|
50
|
+
newLogs = [{ PreRuntime: [consensus.consensusEngine, newSlot] }, ...consensus.rest];
|
|
51
|
+
}
|
|
52
|
+
else if (consensus?.consensusEngine.isBabe) {
|
|
53
|
+
const slot = await getCurrentSlot(head.chain);
|
|
54
|
+
const digest = meta.registry.createType('RawBabePreDigest', consensus.slot);
|
|
55
|
+
const newSlot = compactAddLength(meta.registry.createType('RawBabePreDigest', getNewSlot(digest, slot + 1)).toU8a());
|
|
56
|
+
newLogs = [{ PreRuntime: [consensus.consensusEngine, newSlot] }, ...consensus.rest];
|
|
57
|
+
}
|
|
58
|
+
else if (consensus?.consensusEngine?.toString() == 'nmbs') {
|
|
59
|
+
const nmbsKey = stringToHex('nmbs');
|
|
60
|
+
newLogs = [
|
|
61
|
+
{
|
|
62
|
+
// Using previous block author
|
|
63
|
+
PreRuntime: [
|
|
64
|
+
consensus.consensusEngine,
|
|
65
|
+
parentHeader.digest.logs
|
|
66
|
+
.find((log) => log.isPreRuntime && log.asPreRuntime[0].toHex() == nmbsKey)
|
|
67
|
+
?.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: unsafeBlockHeight ?? head.number + 1,
|
|
81
|
+
stateRoot: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
82
|
+
extrinsicsRoot: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
83
|
+
digest: {
|
|
84
|
+
logs: newLogs,
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
return header;
|
|
88
|
+
};
|
|
89
|
+
const initNewBlock = async (head, header, inherents, storageLayer, callback) => {
|
|
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 ?? head.storage,
|
|
98
|
+
});
|
|
99
|
+
{
|
|
100
|
+
// initialize block
|
|
101
|
+
const resp = await newBlock.call('Core_initialize_block', [header.toHex()]);
|
|
102
|
+
newBlock.pushStorageLayer().setAll(resp.storageDiff);
|
|
103
|
+
callback?.onPhaseApplied?.('initialize', resp);
|
|
104
|
+
}
|
|
105
|
+
const layers = [];
|
|
106
|
+
// apply inherents
|
|
107
|
+
for (const extrinsic of inherents) {
|
|
108
|
+
try {
|
|
109
|
+
const resp = await newBlock.call('BlockBuilder_apply_extrinsic', [extrinsic]);
|
|
110
|
+
const layer = newBlock.pushStorageLayer();
|
|
111
|
+
layer.setAll(resp.storageDiff);
|
|
112
|
+
layers.push(layer);
|
|
113
|
+
callback?.onPhaseApplied?.(layers.length - 1, resp);
|
|
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 = async (head, inherents, extrinsics, ump, callbacks, unsafeBlockHeight) => {
|
|
126
|
+
const registry = await head.registry;
|
|
127
|
+
const header = await newHeader(head, unsafeBlockHeight);
|
|
128
|
+
const newBlockNumber = header.number.toNumber();
|
|
129
|
+
logger.info({
|
|
130
|
+
number: newBlockNumber,
|
|
131
|
+
extrinsicsCount: extrinsics.length,
|
|
132
|
+
umpCount: Object.keys(ump).length,
|
|
133
|
+
}, `Try building block #${newBlockNumber.toLocaleString()}`);
|
|
134
|
+
let layer;
|
|
135
|
+
// apply ump via storage override hack
|
|
136
|
+
if (Object.keys(ump).length > 0) {
|
|
137
|
+
const meta = await head.meta;
|
|
138
|
+
layer = new StorageLayer(head.storage);
|
|
139
|
+
for (const [paraId, upwardMessages] of Object.entries(ump)) {
|
|
140
|
+
const upwardMessagesU8a = upwardMessages.map((x) => hexToU8a(x));
|
|
141
|
+
const messagesCount = upwardMessages.length;
|
|
142
|
+
const messagesSize = upwardMessagesU8a.map((x) => x.length).reduce((s, i) => s + i, 0);
|
|
143
|
+
if (meta.query.ump) {
|
|
144
|
+
const queueSize = meta.registry.createType('(u32, u32)', [messagesCount, messagesSize]);
|
|
145
|
+
const messages = meta.registry.createType('Vec<Bytes>', upwardMessages);
|
|
146
|
+
// TODO: make sure we append instead of replace
|
|
147
|
+
layer.setAll([
|
|
148
|
+
[compactHex(meta.query.ump.relayDispatchQueues(paraId)), messages.toHex()],
|
|
149
|
+
[compactHex(meta.query.ump.relayDispatchQueueSize(paraId)), queueSize.toHex()],
|
|
150
|
+
]);
|
|
151
|
+
}
|
|
152
|
+
else if (meta.query.messageQueue) {
|
|
153
|
+
// TODO: make sure we append instead of replace
|
|
154
|
+
const origin = { ump: { para: paraId } };
|
|
155
|
+
let last = 0;
|
|
156
|
+
let heap = new Uint8Array(0);
|
|
157
|
+
for (const message of upwardMessagesU8a) {
|
|
158
|
+
const payloadLen = message.length;
|
|
159
|
+
const header = meta.registry.createType('(u32, bool)', [payloadLen, false]);
|
|
160
|
+
last = heap.length;
|
|
161
|
+
heap = u8aConcat(heap, header.toU8a(), message);
|
|
162
|
+
}
|
|
163
|
+
layer.setAll([
|
|
164
|
+
[
|
|
165
|
+
compactHex(meta.query.messageQueue.bookStateFor(origin)),
|
|
166
|
+
meta.registry
|
|
167
|
+
.createType('PalletMessageQueueBookState', {
|
|
168
|
+
begin: 0,
|
|
169
|
+
end: 1,
|
|
170
|
+
count: 1,
|
|
171
|
+
readyNeighbours: { prev: origin, next: origin },
|
|
172
|
+
messageCount: messagesCount,
|
|
173
|
+
size_: messagesSize,
|
|
174
|
+
})
|
|
175
|
+
.toHex(),
|
|
176
|
+
],
|
|
177
|
+
[
|
|
178
|
+
compactHex(meta.query.messageQueue.serviceHead(origin)),
|
|
179
|
+
meta.registry.createType('PolkadotRuntimeParachainsInclusionAggregateMessageOrigin', origin).toHex(),
|
|
180
|
+
],
|
|
181
|
+
[
|
|
182
|
+
compactHex(meta.query.messageQueue.pages(origin, 0)),
|
|
183
|
+
meta.registry
|
|
184
|
+
.createType('PalletMessageQueuePage', {
|
|
185
|
+
remaining: messagesCount,
|
|
186
|
+
remaining_size: messagesSize,
|
|
187
|
+
first_index: 0,
|
|
188
|
+
first: 0,
|
|
189
|
+
last,
|
|
190
|
+
heap: compactAddLength(heap),
|
|
191
|
+
})
|
|
192
|
+
.toHex(),
|
|
193
|
+
],
|
|
194
|
+
]);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
throw new Error('Unknown ump storage');
|
|
198
|
+
}
|
|
199
|
+
logger.trace({ paraId, upwardMessages: truncate(upwardMessages) }, 'Pushed UMP');
|
|
200
|
+
}
|
|
201
|
+
if (meta.query.ump) {
|
|
202
|
+
const needsDispatch = meta.registry.createType('Vec<u32>', Object.keys(ump));
|
|
203
|
+
layer.set(compactHex(meta.query.ump.needsDispatch()), needsDispatch.toHex());
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const { block: newBlock } = await initNewBlock(head, header, inherents, layer);
|
|
207
|
+
const pendingExtrinsics = [];
|
|
208
|
+
const includedExtrinsic = [];
|
|
209
|
+
// apply extrinsics
|
|
210
|
+
for (const extrinsic of extrinsics) {
|
|
211
|
+
try {
|
|
212
|
+
const resp = await newBlock.call('BlockBuilder_apply_extrinsic', [extrinsic]);
|
|
213
|
+
const outcome = registry.createType('ApplyExtrinsicResult', resp.result);
|
|
214
|
+
if (outcome.isErr) {
|
|
215
|
+
callbacks?.onApplyExtrinsicError?.(extrinsic, outcome.asErr);
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
newBlock.pushStorageLayer().setAll(resp.storageDiff);
|
|
219
|
+
includedExtrinsic.push(extrinsic);
|
|
220
|
+
callbacks?.onPhaseApplied?.(includedExtrinsic.length - 1, resp);
|
|
221
|
+
}
|
|
222
|
+
catch (e) {
|
|
223
|
+
logger.info('Failed to apply extrinsic %o %s', e, e);
|
|
224
|
+
pendingExtrinsics.push(extrinsic);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
{
|
|
228
|
+
// finalize block
|
|
229
|
+
const resp = await newBlock.call('BlockBuilder_finalize_block', []);
|
|
230
|
+
newBlock.pushStorageLayer().setAll(resp.storageDiff);
|
|
231
|
+
callbacks?.onPhaseApplied?.('finalize', resp);
|
|
232
|
+
}
|
|
233
|
+
const blockData = registry.createType('Block', {
|
|
234
|
+
header,
|
|
235
|
+
extrinsics: includedExtrinsic,
|
|
236
|
+
});
|
|
237
|
+
const storageDiff = await newBlock.storageDiff();
|
|
238
|
+
if (logger.level.toLowerCase() === 'trace') {
|
|
239
|
+
logger.trace(Object.entries(storageDiff).map(([key, value]) => [key, truncate(value)]), 'Final block');
|
|
240
|
+
}
|
|
241
|
+
const finalBlock = new Block(head.chain, newBlock.number, blockData.hash.toHex(), head, {
|
|
242
|
+
header,
|
|
243
|
+
extrinsics: [...inherents, ...includedExtrinsic],
|
|
244
|
+
storage: head.storage,
|
|
245
|
+
storageDiff,
|
|
246
|
+
});
|
|
247
|
+
logger.info({
|
|
248
|
+
number: newBlock.number,
|
|
249
|
+
hash: finalBlock.hash,
|
|
250
|
+
extrinsics: truncate(includedExtrinsic),
|
|
251
|
+
pendingExtrinsicsCount: pendingExtrinsics.length,
|
|
252
|
+
ump: truncate(ump),
|
|
253
|
+
}, 'Block built');
|
|
254
|
+
return [finalBlock, pendingExtrinsics];
|
|
255
|
+
};
|
|
256
|
+
export const dryRunExtrinsic = async (head, inherents, extrinsic) => {
|
|
257
|
+
const registry = await head.registry;
|
|
258
|
+
const header = await newHeader(head);
|
|
259
|
+
const { block: newBlock } = await initNewBlock(head, header, inherents);
|
|
260
|
+
if (typeof extrinsic !== 'string') {
|
|
261
|
+
if (!head.chain.mockSignatureHost) {
|
|
262
|
+
throw new Error('Cannot fake signature because mock signature host is not enabled. Start chain with `mockSignatureHost: true`');
|
|
263
|
+
}
|
|
264
|
+
const meta = await head.meta;
|
|
265
|
+
const call = registry.createType('Call', hexToU8a(extrinsic.call));
|
|
266
|
+
const generic = registry.createType('GenericExtrinsic', call);
|
|
267
|
+
const accountRaw = await head.get(compactHex(meta.query.system.account(extrinsic.address)));
|
|
268
|
+
const account = registry.createType('AccountInfo', hexToU8a(accountRaw));
|
|
269
|
+
generic.signFake(extrinsic.address, {
|
|
270
|
+
blockHash: head.hash,
|
|
271
|
+
genesisHash: head.hash,
|
|
272
|
+
runtimeVersion: await head.runtimeVersion,
|
|
273
|
+
nonce: account.nonce,
|
|
274
|
+
});
|
|
275
|
+
const mockSignature = new Uint8Array(64);
|
|
276
|
+
mockSignature.fill(0xcd);
|
|
277
|
+
mockSignature.set([0xde, 0xad, 0xbe, 0xef]);
|
|
278
|
+
generic.signature.set(mockSignature);
|
|
279
|
+
defaultLogger.info({ call: call.toHuman() }, 'dry_run_call');
|
|
280
|
+
return newBlock.call('BlockBuilder_apply_extrinsic', [generic.toHex()]);
|
|
281
|
+
}
|
|
282
|
+
defaultLogger.info({ call: registry.createType('GenericExtrinsic', hexToU8a(extrinsic)).toHuman() }, 'dry_run_extrinsic');
|
|
283
|
+
return newBlock.call('BlockBuilder_apply_extrinsic', [extrinsic]);
|
|
284
|
+
};
|
|
285
|
+
export const dryRunInherents = async (head, inherents) => {
|
|
286
|
+
const header = await newHeader(head);
|
|
287
|
+
const { layers } = await initNewBlock(head, header, inherents);
|
|
288
|
+
const storage = {};
|
|
289
|
+
for (const layer of layers) {
|
|
290
|
+
await layer.mergeInto(storage);
|
|
291
|
+
}
|
|
292
|
+
return Object.entries(storage);
|
|
293
|
+
};
|